lists.squeakfoundation.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Packages
October 2015
----- 2024 -----
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
packages@lists.squeakfoundation.org
1 participants
218 discussions
Start a n
N
ew thread
The Trunk: Morphic-mt.1010.mcz
by commits@source.squeak.org
06 Oct '15
06 Oct '15
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1010.mcz
==================== Summary ==================== Name: Morphic-mt.1010 Author: mt Time: 6 October 2015, 1:49:59.363 pm UUID: 5584d8ee-d8e6-1041-8d6f-076e24462426 Ancestors: Morphic-cmm.1009 Allow morphs to have custom corner radiuses when using the rounded corner style. =============== Diff against Morphic-cmm.1009 =============== Item was changed: ----- Method: Morph>>boundsWithinCorners (in category 'drawing') ----- boundsWithinCorners "Return a single sub-rectangle that lies entirely inside corners that are made by me. Used to identify large regions of window that do not need to be redrawn." ^ self wantsRoundedCorners + ifTrue: [self bounds insetBy: 0@self cornerRadius] - ifTrue: [self bounds insetBy: 0@self class preferredCornerRadius] ifFalse: [self bounds] ! Item was added: + ----- Method: Morph>>cornerRadius (in category 'rounding') ----- + cornerRadius + + ^ self + valueOfProperty: #cornerRadius + ifAbsent: [self class preferredCornerRadius]! Item was added: + ----- Method: Morph>>cornerRadius: (in category 'rounding') ----- + cornerRadius: radius + + self + setProperty: #cornerRadius + toValue: radius. + + self changed.! Item was changed: + ----- Method: Morph>>cornerStyle (in category 'rounding') ----- - ----- Method: Morph>>cornerStyle (in category 'visual properties') ----- cornerStyle "Returns one of the following symbols: #square #rounded according to the current corner style." ^ self valueOfProperty: #cornerStyle ifAbsent: [#square]! Item was changed: ----- Method: Morph>>drawDropHighlightOn: (in category 'drawing') ----- drawDropHighlightOn: aCanvas self highlightedForDrop ifTrue: [ self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self cornerRadius width: 1 color: self dropHighlightColor] - ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self class preferredCornerRadius width: 1 color: self dropHighlightColor] ifFalse: [aCanvas frameRectangle: self fullBounds color: self dropHighlightColor]].! Item was changed: ----- Method: Morph>>drawDropShadowOn: (in category 'drawing') ----- drawDropShadowOn: aCanvas "Rectangular shadow with support for rounded corners." | shadowBounds | shadowBounds := self shadowOffset isRectangle ifTrue: [self bounds outsetBy: self shadowOffset] ifFalse: [self bounds translateBy: (self shadowOffset negated max: 0@0)]. "Only redraw the shadow if the shadow area is affected." + ((aCanvas clipRect intersects: shadowBounds) and: [((self bounds insetBy: (self wantsRoundedCorners ifFalse: [0] ifTrue: [self cornerRadius])) containsRect: aCanvas clipRect) not]) - ((aCanvas clipRect intersects: shadowBounds) and: [((self bounds insetBy: (self wantsRoundedCorners ifFalse: [0] ifTrue: [self class preferredCornerRadius])) containsRect: aCanvas clipRect) not]) ifTrue: [ (self hasProperty: #dropShadow) ifFalse: [self updateDropShadowCache]. aCanvas translucentImage: (self valueOfProperty: #dropShadow) at: shadowBounds topLeft].! Item was changed: ----- Method: Morph>>drawKeyboardFocusIndicationOn: (in category 'drawing') ----- drawKeyboardFocusIndicationOn: aCanvas self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self bounds radius: self cornerRadius width: 3 "self borderStyle width" color: self keyboardFocusColor] - ifTrue: [aCanvas frameRoundRect: self bounds radius: self class preferredCornerRadius width: 3 "self borderStyle width" color: self keyboardFocusColor] ifFalse: [aCanvas frameRectangle: self bounds width: 3 "self borderStyle width" color: self keyboardFocusColor].! Item was changed: ----- Method: Morph>>drawMouseDownHighlightOn: (in category 'drawing') ----- drawMouseDownHighlightOn: aCanvas self highlightedForMouseDown ifTrue: [ self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self cornerRadius width: 1 color: self color darker darker] - ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self class preferredCornerRadius width: 1 color: self color darker darker] ifFalse: [aCanvas frameRectangle: self fullBounds color: self color darker darker]].! Item was changed: ----- Method: Morph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas self wantsRoundedCorners + ifTrue: [aCanvas frameAndFillRoundRect: self bounds radius: self cornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] - ifTrue: [aCanvas frameAndFillRoundRect: self bounds radius: self class preferredCornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] ifFalse: [aCanvas fillRectangle: self bounds fillStyle: self fillStyle borderStyle: self borderStyle]. ! Item was changed: ----- Method: Morph>>updateDropShadowCache (in category 'drawing') ----- updateDropShadowCache | shadowBounds offset form canvas drawBlock localBounds mask maskCanvas | shadowBounds := self shadowOffset isRectangle ifTrue: [0@0 corner: (self bounds outsetBy: self shadowOffset) extent] ifFalse: [0@0 corner: self extent + self shadowOffset abs]. offset := self shadowOffset isRectangle ifTrue: [0@0] ifFalse: [self shadowOffset max: 0@0]. localBounds := self shadowOffset isRectangle ifTrue: [self shadowOffset topLeft extent: self extent] ifFalse: [(self shadowOffset negated max: 0@0) extent: self extent]. form := Form extent: shadowBounds extent depth: Display depth. canvas := form getCanvas. drawBlock := self useSoftDropShadow ifFalse: [ [:c | self wantsRoundedCorners + ifTrue: [c fillRoundRect: localBounds radius: self cornerRadius fillStyle: self shadowColor] - ifTrue: [c fillRoundRect: localBounds radius: self class preferredCornerRadius fillStyle: self shadowColor] ifFalse: [c fillRectangle: localBounds fillStyle: self shadowColor]]] ifTrue: [ [:c | self wantsRoundedCorners ifTrue: [0 to: 9 do: [:i | c fillRoundRect: (shadowBounds insetBy: i) + radius: (self cornerRadius max: 20) -i - radius: (self class preferredCornerRadius max: 20) -i fillStyle: (self shadowColor alpha: self shadowColor alpha * (i+1))]] ifFalse: [0 to: 9 do: [:i | c fillRoundRect: (shadowBounds insetBy: i) radius: 20-i fillStyle: (self shadowColor alpha: self shadowColor alpha * (i+1))]]]]. canvas translateBy: offset during: [ :shadowCanvas | drawBlock value: shadowCanvas]. "Support transparent morph colors without having the shadow to shine through.." mask := Form extent: shadowBounds extent depth: Display depth. maskCanvas := mask getCanvas. self wantsRoundedCorners + ifTrue: [maskCanvas fillRoundRect: (localBounds insetBy: self borderWidth) radius: self cornerRadius fillStyle: Color black] - ifTrue: [maskCanvas fillRoundRect: (localBounds insetBy: self borderWidth) radius: self class preferredCornerRadius fillStyle: Color black] ifFalse: [maskCanvas fillRectangle: (localBounds insetBy: self borderWidth) fillStyle: Color black]. mask displayOn: form at: 0@0 rule: Form erase. self setProperty: #dropShadow toValue: form.! Item was changed: ----- Method: NewBalloonMorph>>drawDropShadowOn: (in category 'drawing') ----- drawDropShadowOn: aCanvas aCanvas translateBy: self shadowOffset during: [ :shadowCanvas | (shadowCanvas isVisible: self bubbleBounds) ifTrue: [ self wantsRoundedCorners + ifTrue: [shadowCanvas fillRoundRect: self bubbleBounds radius: self cornerRadius fillStyle: self shadowColor] - ifTrue: [shadowCanvas fillRoundRect: self bubbleBounds radius: self class preferredCornerRadius fillStyle: self shadowColor] ifFalse: [shadowCanvas fillRectangle: self bubbleBounds fillStyle: self shadowColor]]. self hasTail ifTrue: [ shadowCanvas drawPolygon: self verticesForTail fillStyle: self shadowColor]]. ! Item was changed: ----- Method: NewBalloonMorph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas "Bubble." self wantsRoundedCorners ifTrue: [aCanvas frameAndFillRoundRect: self bubbleBounds + radius: self cornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] - radius: self class preferredCornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] ifFalse: [aCanvas fillRectangle: self bubbleBounds fillStyle: self fillStyle borderStyle: self borderStyle]. "Tail." self hasTail ifTrue: [ self verticesForTail in: [:points | | pixelOffset | pixelOffset := points first y < points second y ifFalse: [points first x < points second x ifTrue: [self borderStyle width negated @ self borderStyle width] "bottomLeft" ifFalse: [self borderStyle width @ self borderStyle width]] "bottomRight" ifTrue: [points first x < points second x ifTrue: [self borderStyle width negated @ self borderStyle width negated] "topLeft" ifFalse: [self borderStyle width @ self borderStyle width negated]]. "topRight" aCanvas drawPolygon: points fillStyle: self fillStyle. aCanvas line: points first to: points second + pixelOffset width: self borderStyle width color: self borderStyle color. aCanvas line: points first to: points third + pixelOffset width: self borderStyle width color: self borderStyle color]]! Item was changed: ----- Method: NewBalloonMorph>>verticesForTail (in category 'drawing') ----- verticesForTail | offset factorX factorY tpos bpos | offset := 5 + (self wantsRoundedCorners + ifTrue: [self cornerRadius] - ifTrue: [self class preferredCornerRadius] ifFalse: [0]). tpos := self tailPosition. factorX := tpos x < self center x ifTrue: [1] ifFalse: [-1]. factorY := tpos y > self center y ifTrue: [1] ifFalse: [-1]. bpos := self bubbleBounds perform: self orientation. ^ { tpos. bpos + (((offset + self tailWidth) * factorX) @ (self borderStyle width negated * factorY)). bpos + ((offset * factorX) @ (self borderStyle width negated * factorY)).}! Item was changed: ----- Method: PluggableButtonMorph>>drawBackgroundOn: (in category 'drawing') ----- drawBackgroundOn: aCanvas | cc gradient borderColor fill | cc := self color. cc isTransparent ifTrue:[cc := Color gray: 0.9]. self enabled ifFalse:[cc := Color lightGray]. cc brightness > 0.9 ifTrue:[cc := cc adjustBrightness: 0.9 - cc brightness]. showSelectionFeedback ifTrue:[ borderColor := cc muchDarker. gradient := GradientFillStyle ramp: { 0.0 -> cc muchDarker. 0.1-> (cc adjustBrightness: -0.2). 0.5 -> cc. 0.9-> (cc adjustBrightness: -0.1). 1 -> cc muchDarker}. cc := cc muchDarker. ] ifFalse:[ borderColor := Color lightGray. gradient := GradientFillStyle ramp: { 0.0 -> Color white. 0.1-> (cc adjustBrightness: 0.05). 0.6 -> (cc darker)}. ]. gradient origin: bounds topLeft. gradient direction: 0@self height. PluggableButtonMorph gradientButton ifFalse: [fill := SolidFillStyle color: cc] ifTrue: [fill := gradient]. ^ self wantsRoundedCorners ifTrue: [aCanvas frameAndFillRoundRect: self bounds + radius: self cornerRadius - radius: self class preferredCornerRadius fillStyle: fill borderWidth: 1 borderColor: borderColor] ifFalse: [aCanvas frameAndFillRectangle: self bounds fillColor: fill asColor borderWidth: 1 borderColor: borderColor darker; fillRectangle: self innerBounds fillStyle: fill]! Item was changed: ----- Method: UserDialogBoxMorph>>drawSubmorphsOn: (in category 'drawing') ----- drawSubmorphsOn: aCanvas super drawSubmorphsOn: aCanvas. self wantsRoundedCorners ifTrue: [ "Overdraw lower part of title bar to hide bottom corners." aCanvas + fillRectangle: (self submorphs first "titleRow" bottomLeft - (-1 @ self submorphs first cornerRadius) - fillRectangle: (self submorphs first "titleRow" bottomLeft - (-1 @ Morph preferredCornerRadius) corner: self submorphs first "titleRow" bottomRight - (1@0)) color: self color].! Item was changed: ----- Method: UserDialogBoxMorph>>initialize (in category 'initialization') ----- initialize | titleRow cc | super initialize. self color: Color white. self listDirection: #topToBottom; wrapCentering: #center; hResizing: #shrinkWrap; vResizing: #shrinkWrap. self layoutInset: -1 @ -1; cellInset: 5@5. self borderStyle: BorderStyle thinGray. self setProperty: #indicateKeyboardFocus: toValue: #never. FillInTheBlankMorph roundedDialogCorners ifTrue: [self useRoundedCorners]. self hasDropShadow: Preferences menuAppearance3d. self useSoftDropShadow ifFalse: [ self shadowColor: (TranslucentColor r: 0.0 g: 0.0 b: 0.0 alpha: 0.666); shadowOffset: 1 @ 1] ifTrue: [ self shadowColor: (TranslucentColor r: 0.0 g: 0.0 b: 0.0 alpha: 0.01); shadowOffset: (10@8 corner: 10@12)]. cc := Color gray: 0.8. titleRow := AlignmentMorph newRow. titleRow hResizing: #spaceFill; vResizing: #shrinkWrap. self cornerStyle == #rounded ifTrue: [titleRow useRoundedCorners]. titleRow borderStyle: BorderStyle thinGray. + titleRow layoutInset: (5@5 corner: (2@ (5 + (titleRow cornerStyle == #rounded ifTrue: [titleRow cornerRadius] ifFalse: [0])))). - titleRow layoutInset: (5@5 corner: (2@ (5 + (titleRow cornerStyle == #rounded ifTrue: [Morph preferredCornerRadius] ifFalse: [0])))). titleRow color: cc. titleRow fillStyle: self titleGradient. titleMorph := StringMorph new. titleMorph emphasis: 1. titleRow addMorph: titleMorph. labelMorph := TextMorph new. labelMorph margins: (Preferences standardButtonFont widthOf: $x) * 2 @ 0. labelMorph lock. buttonRow := AlignmentMorph newRow vResizing: #rigid; height: (Preferences standardButtonFont height + 20); hResizing: #spaceFill; layoutInset: (((Preferences standardButtonFont widthOf: $x) * 2 @ 0) corner: ((Preferences standardButtonFont widthOf: $x) * 2 @ 10)); cellInset: (Preferences standardButtonFont widthOf: $x) * 2. buttonRow color: Color transparent. self addMorphBack: titleRow ; addMorphBack: labelMorph ; addMorphBack: buttonRow. keyMap := Dictionary new!
1
0
0
0
The Trunk: Morphic-mt.1010.mcz
by commits@source.squeak.org
06 Oct '15
06 Oct '15
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1010.mcz
==================== Summary ==================== Name: Morphic-mt.1010 Author: mt Time: 6 October 2015, 1:49:59.363 pm UUID: 5584d8ee-d8e6-1041-8d6f-076e24462426 Ancestors: Morphic-cmm.1009 Allow morphs to have custom corner radiuses when using the rounded corner style. =============== Diff against Morphic-cmm.1009 =============== Item was changed: ----- Method: Morph>>boundsWithinCorners (in category 'drawing') ----- boundsWithinCorners "Return a single sub-rectangle that lies entirely inside corners that are made by me. Used to identify large regions of window that do not need to be redrawn." ^ self wantsRoundedCorners + ifTrue: [self bounds insetBy: 0@self cornerRadius] - ifTrue: [self bounds insetBy: 0@self class preferredCornerRadius] ifFalse: [self bounds] ! Item was added: + ----- Method: Morph>>cornerRadius (in category 'rounding') ----- + cornerRadius + + ^ self + valueOfProperty: #cornerRadius + ifAbsent: [self class preferredCornerRadius]! Item was added: + ----- Method: Morph>>cornerRadius: (in category 'rounding') ----- + cornerRadius: radius + + self + setProperty: #cornerRadius + toValue: radius. + + self changed.! Item was changed: + ----- Method: Morph>>cornerStyle (in category 'rounding') ----- - ----- Method: Morph>>cornerStyle (in category 'visual properties') ----- cornerStyle "Returns one of the following symbols: #square #rounded according to the current corner style." ^ self valueOfProperty: #cornerStyle ifAbsent: [#square]! Item was changed: ----- Method: Morph>>drawDropHighlightOn: (in category 'drawing') ----- drawDropHighlightOn: aCanvas self highlightedForDrop ifTrue: [ self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self cornerRadius width: 1 color: self dropHighlightColor] - ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self class preferredCornerRadius width: 1 color: self dropHighlightColor] ifFalse: [aCanvas frameRectangle: self fullBounds color: self dropHighlightColor]].! Item was changed: ----- Method: Morph>>drawDropShadowOn: (in category 'drawing') ----- drawDropShadowOn: aCanvas "Rectangular shadow with support for rounded corners." | shadowBounds | shadowBounds := self shadowOffset isRectangle ifTrue: [self bounds outsetBy: self shadowOffset] ifFalse: [self bounds translateBy: (self shadowOffset negated max: 0@0)]. "Only redraw the shadow if the shadow area is affected." + ((aCanvas clipRect intersects: shadowBounds) and: [((self bounds insetBy: (self wantsRoundedCorners ifFalse: [0] ifTrue: [self cornerRadius])) containsRect: aCanvas clipRect) not]) - ((aCanvas clipRect intersects: shadowBounds) and: [((self bounds insetBy: (self wantsRoundedCorners ifFalse: [0] ifTrue: [self class preferredCornerRadius])) containsRect: aCanvas clipRect) not]) ifTrue: [ (self hasProperty: #dropShadow) ifFalse: [self updateDropShadowCache]. aCanvas translucentImage: (self valueOfProperty: #dropShadow) at: shadowBounds topLeft].! Item was changed: ----- Method: Morph>>drawKeyboardFocusIndicationOn: (in category 'drawing') ----- drawKeyboardFocusIndicationOn: aCanvas self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self bounds radius: self cornerRadius width: 3 "self borderStyle width" color: self keyboardFocusColor] - ifTrue: [aCanvas frameRoundRect: self bounds radius: self class preferredCornerRadius width: 3 "self borderStyle width" color: self keyboardFocusColor] ifFalse: [aCanvas frameRectangle: self bounds width: 3 "self borderStyle width" color: self keyboardFocusColor].! Item was changed: ----- Method: Morph>>drawMouseDownHighlightOn: (in category 'drawing') ----- drawMouseDownHighlightOn: aCanvas self highlightedForMouseDown ifTrue: [ self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self cornerRadius width: 1 color: self color darker darker] - ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self class preferredCornerRadius width: 1 color: self color darker darker] ifFalse: [aCanvas frameRectangle: self fullBounds color: self color darker darker]].! Item was changed: ----- Method: Morph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas self wantsRoundedCorners + ifTrue: [aCanvas frameAndFillRoundRect: self bounds radius: self cornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] - ifTrue: [aCanvas frameAndFillRoundRect: self bounds radius: self class preferredCornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] ifFalse: [aCanvas fillRectangle: self bounds fillStyle: self fillStyle borderStyle: self borderStyle]. ! Item was changed: ----- Method: Morph>>updateDropShadowCache (in category 'drawing') ----- updateDropShadowCache | shadowBounds offset form canvas drawBlock localBounds mask maskCanvas | shadowBounds := self shadowOffset isRectangle ifTrue: [0@0 corner: (self bounds outsetBy: self shadowOffset) extent] ifFalse: [0@0 corner: self extent + self shadowOffset abs]. offset := self shadowOffset isRectangle ifTrue: [0@0] ifFalse: [self shadowOffset max: 0@0]. localBounds := self shadowOffset isRectangle ifTrue: [self shadowOffset topLeft extent: self extent] ifFalse: [(self shadowOffset negated max: 0@0) extent: self extent]. form := Form extent: shadowBounds extent depth: Display depth. canvas := form getCanvas. drawBlock := self useSoftDropShadow ifFalse: [ [:c | self wantsRoundedCorners + ifTrue: [c fillRoundRect: localBounds radius: self cornerRadius fillStyle: self shadowColor] - ifTrue: [c fillRoundRect: localBounds radius: self class preferredCornerRadius fillStyle: self shadowColor] ifFalse: [c fillRectangle: localBounds fillStyle: self shadowColor]]] ifTrue: [ [:c | self wantsRoundedCorners ifTrue: [0 to: 9 do: [:i | c fillRoundRect: (shadowBounds insetBy: i) + radius: (self cornerRadius max: 20) -i - radius: (self class preferredCornerRadius max: 20) -i fillStyle: (self shadowColor alpha: self shadowColor alpha * (i+1))]] ifFalse: [0 to: 9 do: [:i | c fillRoundRect: (shadowBounds insetBy: i) radius: 20-i fillStyle: (self shadowColor alpha: self shadowColor alpha * (i+1))]]]]. canvas translateBy: offset during: [ :shadowCanvas | drawBlock value: shadowCanvas]. "Support transparent morph colors without having the shadow to shine through.." mask := Form extent: shadowBounds extent depth: Display depth. maskCanvas := mask getCanvas. self wantsRoundedCorners + ifTrue: [maskCanvas fillRoundRect: (localBounds insetBy: self borderWidth) radius: self cornerRadius fillStyle: Color black] - ifTrue: [maskCanvas fillRoundRect: (localBounds insetBy: self borderWidth) radius: self class preferredCornerRadius fillStyle: Color black] ifFalse: [maskCanvas fillRectangle: (localBounds insetBy: self borderWidth) fillStyle: Color black]. mask displayOn: form at: 0@0 rule: Form erase. self setProperty: #dropShadow toValue: form.! Item was changed: ----- Method: NewBalloonMorph>>drawDropShadowOn: (in category 'drawing') ----- drawDropShadowOn: aCanvas aCanvas translateBy: self shadowOffset during: [ :shadowCanvas | (shadowCanvas isVisible: self bubbleBounds) ifTrue: [ self wantsRoundedCorners + ifTrue: [shadowCanvas fillRoundRect: self bubbleBounds radius: self cornerRadius fillStyle: self shadowColor] - ifTrue: [shadowCanvas fillRoundRect: self bubbleBounds radius: self class preferredCornerRadius fillStyle: self shadowColor] ifFalse: [shadowCanvas fillRectangle: self bubbleBounds fillStyle: self shadowColor]]. self hasTail ifTrue: [ shadowCanvas drawPolygon: self verticesForTail fillStyle: self shadowColor]]. ! Item was changed: ----- Method: NewBalloonMorph>>drawOn: (in category 'drawing') ----- drawOn: aCanvas "Bubble." self wantsRoundedCorners ifTrue: [aCanvas frameAndFillRoundRect: self bubbleBounds + radius: self cornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] - radius: self class preferredCornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] ifFalse: [aCanvas fillRectangle: self bubbleBounds fillStyle: self fillStyle borderStyle: self borderStyle]. "Tail." self hasTail ifTrue: [ self verticesForTail in: [:points | | pixelOffset | pixelOffset := points first y < points second y ifFalse: [points first x < points second x ifTrue: [self borderStyle width negated @ self borderStyle width] "bottomLeft" ifFalse: [self borderStyle width @ self borderStyle width]] "bottomRight" ifTrue: [points first x < points second x ifTrue: [self borderStyle width negated @ self borderStyle width negated] "topLeft" ifFalse: [self borderStyle width @ self borderStyle width negated]]. "topRight" aCanvas drawPolygon: points fillStyle: self fillStyle. aCanvas line: points first to: points second + pixelOffset width: self borderStyle width color: self borderStyle color. aCanvas line: points first to: points third + pixelOffset width: self borderStyle width color: self borderStyle color]]! Item was changed: ----- Method: NewBalloonMorph>>verticesForTail (in category 'drawing') ----- verticesForTail | offset factorX factorY tpos bpos | offset := 5 + (self wantsRoundedCorners + ifTrue: [self cornerRadius] - ifTrue: [self class preferredCornerRadius] ifFalse: [0]). tpos := self tailPosition. factorX := tpos x < self center x ifTrue: [1] ifFalse: [-1]. factorY := tpos y > self center y ifTrue: [1] ifFalse: [-1]. bpos := self bubbleBounds perform: self orientation. ^ { tpos. bpos + (((offset + self tailWidth) * factorX) @ (self borderStyle width negated * factorY)). bpos + ((offset * factorX) @ (self borderStyle width negated * factorY)).}! Item was changed: ----- Method: PluggableButtonMorph>>drawBackgroundOn: (in category 'drawing') ----- drawBackgroundOn: aCanvas | cc gradient borderColor fill | cc := self color. cc isTransparent ifTrue:[cc := Color gray: 0.9]. self enabled ifFalse:[cc := Color lightGray]. cc brightness > 0.9 ifTrue:[cc := cc adjustBrightness: 0.9 - cc brightness]. showSelectionFeedback ifTrue:[ borderColor := cc muchDarker. gradient := GradientFillStyle ramp: { 0.0 -> cc muchDarker. 0.1-> (cc adjustBrightness: -0.2). 0.5 -> cc. 0.9-> (cc adjustBrightness: -0.1). 1 -> cc muchDarker}. cc := cc muchDarker. ] ifFalse:[ borderColor := Color lightGray. gradient := GradientFillStyle ramp: { 0.0 -> Color white. 0.1-> (cc adjustBrightness: 0.05). 0.6 -> (cc darker)}. ]. gradient origin: bounds topLeft. gradient direction: 0@self height. PluggableButtonMorph gradientButton ifFalse: [fill := SolidFillStyle color: cc] ifTrue: [fill := gradient]. ^ self wantsRoundedCorners ifTrue: [aCanvas frameAndFillRoundRect: self bounds + radius: self cornerRadius - radius: self class preferredCornerRadius fillStyle: fill borderWidth: 1 borderColor: borderColor] ifFalse: [aCanvas frameAndFillRectangle: self bounds fillColor: fill asColor borderWidth: 1 borderColor: borderColor darker; fillRectangle: self innerBounds fillStyle: fill]! Item was changed: ----- Method: UserDialogBoxMorph>>drawSubmorphsOn: (in category 'drawing') ----- drawSubmorphsOn: aCanvas super drawSubmorphsOn: aCanvas. self wantsRoundedCorners ifTrue: [ "Overdraw lower part of title bar to hide bottom corners." aCanvas + fillRectangle: (self submorphs first "titleRow" bottomLeft - (-1 @ self submorphs first cornerRadius) - fillRectangle: (self submorphs first "titleRow" bottomLeft - (-1 @ Morph preferredCornerRadius) corner: self submorphs first "titleRow" bottomRight - (1@0)) color: self color].! Item was changed: ----- Method: UserDialogBoxMorph>>initialize (in category 'initialization') ----- initialize | titleRow cc | super initialize. self color: Color white. self listDirection: #topToBottom; wrapCentering: #center; hResizing: #shrinkWrap; vResizing: #shrinkWrap. self layoutInset: -1 @ -1; cellInset: 5@5. self borderStyle: BorderStyle thinGray. self setProperty: #indicateKeyboardFocus: toValue: #never. FillInTheBlankMorph roundedDialogCorners ifTrue: [self useRoundedCorners]. self hasDropShadow: Preferences menuAppearance3d. self useSoftDropShadow ifFalse: [ self shadowColor: (TranslucentColor r: 0.0 g: 0.0 b: 0.0 alpha: 0.666); shadowOffset: 1 @ 1] ifTrue: [ self shadowColor: (TranslucentColor r: 0.0 g: 0.0 b: 0.0 alpha: 0.01); shadowOffset: (10@8 corner: 10@12)]. cc := Color gray: 0.8. titleRow := AlignmentMorph newRow. titleRow hResizing: #spaceFill; vResizing: #shrinkWrap. self cornerStyle == #rounded ifTrue: [titleRow useRoundedCorners]. titleRow borderStyle: BorderStyle thinGray. + titleRow layoutInset: (5@5 corner: (2@ (5 + (titleRow cornerStyle == #rounded ifTrue: [titleRow cornerRadius] ifFalse: [0])))). - titleRow layoutInset: (5@5 corner: (2@ (5 + (titleRow cornerStyle == #rounded ifTrue: [Morph preferredCornerRadius] ifFalse: [0])))). titleRow color: cc. titleRow fillStyle: self titleGradient. titleMorph := StringMorph new. titleMorph emphasis: 1. titleRow addMorph: titleMorph. labelMorph := TextMorph new. labelMorph margins: (Preferences standardButtonFont widthOf: $x) * 2 @ 0. labelMorph lock. buttonRow := AlignmentMorph newRow vResizing: #rigid; height: (Preferences standardButtonFont height + 20); hResizing: #spaceFill; layoutInset: (((Preferences standardButtonFont widthOf: $x) * 2 @ 0) corner: ((Preferences standardButtonFont widthOf: $x) * 2 @ 10)); cellInset: (Preferences standardButtonFont widthOf: $x) * 2. buttonRow color: Color transparent. self addMorphBack: titleRow ; addMorphBack: labelMorph ; addMorphBack: buttonRow. keyMap := Dictionary new!
1
0
0
0
The Trunk: Morphic-cmm.1008.mcz
by commits@source.squeak.org
05 Oct '15
05 Oct '15
Chris Muller uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-cmm.1008.mcz
==================== Summary ==================== Name: Morphic-cmm.1008 Author: cmm Time: 14 September 2015, 2:27:11.585 pm UUID: 056757ae-538d-4a80-b9d2-0bd93c2b24c9 Ancestors: Morphic-mt.1005 Integrate 'Focus Follows Mouse' and 'Windows Raise On Click' features from X and Gnome. =============== Diff against Morphic-mt.1005 =============== Item was changed: ----- Method: CornerGripMorph>>mouseMove: (in category 'as yet unclassified') ----- mouseMove: anEvent | delta | target ifNil: [^ self]. target fastFramingOn ifTrue: [delta := target doFastWindowReframe: self ptName] ifFalse: [ + delta := lastMouse ifNil: [0@0] ifNotNil: [anEvent cursorPoint - lastMouse]. - delta := anEvent cursorPoint - lastMouse. lastMouse := anEvent cursorPoint. self apply: delta. self bounds: (self bounds origin + delta extent: self bounds extent)].! Item was changed: ----- Method: HandMorph>>handleEvent: (in category 'events-processing') ----- handleEvent: anEvent | evt ofs | owner ifNil:[^self]. evt := anEvent. EventStats ifNil:[EventStats := IdentityDictionary new]. EventStats at: #count put: (EventStats at: #count ifAbsent:[0]) + 1. EventStats at: evt type put: (EventStats at: evt type ifAbsent:[0]) + 1. evt isMouseOver ifTrue:[^self sendMouseEvent: evt]. ShowEvents == true ifTrue:[ + Display fill: (0@0 extent: 300@120) rule: Form over fillColor: Color white. - Display fill: (0@0 extent: 250@120) rule: Form over fillColor: Color white. ofs := (owner hands indexOf: self) - 1 * 60. + evt isKeyboard + ifTrue: [ 'key: ', evt printString displayAt: (0@ofs) + (0@30) ] + ifFalse: [ 'evt: ', evt printString displayAt: (0@ofs) + (0@0) ]. + 'kf: ', self keyboardFocus printString displayAt: (0@ofs)+(0@45). - evt printString displayAt: (0@ofs) + (evt isKeyboard ifTrue:[0@30] ifFalse:[0@0]). - self keyboardFocus printString displayAt: (0@ofs)+(0@45). ]. "Notify listeners" self sendListenEvent: evt to: self eventListeners. evt isWindowEvent ifTrue: [ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isKeyboard ifTrue:[ self sendListenEvent: evt to: self keyboardListeners. self sendKeyboardEvent: evt. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isDropEvent ifTrue:[ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isMouse ifTrue:[ self sendListenEvent: evt to: self mouseListeners. lastMouseEvent := evt]. "Check for pending drag or double click operations." mouseClickState ifNotNil:[ (mouseClickState handleEvent: evt from: self) ifFalse:[ "Possibly dispatched #click: or something and will not re-establish otherwise" ^self mouseOverHandler processMouseOver: lastMouseEvent]]. evt isMove ifTrue:[ self position: evt position. self sendMouseEvent: evt. ] ifFalse:[ "Issue a synthetic move event if we're not at the position of the event" (evt position = self position) ifFalse:[self moveToEvent: evt]. "Drop submorphs on button events" (self hasSubmorphs) ifTrue:[self dropMorphs: evt] ifFalse:[self sendMouseEvent: evt]. ]. + ShowEvents == true ifTrue:['mf: ', self mouseFocus printString displayAt: (0@ofs) + (0@15)]. - ShowEvents == true ifTrue:[self mouseFocus printString displayAt: (0@ofs) + (0@15)]. self mouseOverHandler processMouseOver: lastMouseEvent. "self handleDragOutside: anEvent." ! Item was added: + ----- Method: HandMorph>>windowUnderneath (in category 'accessing') ----- + windowUnderneath + ActiveWorld submorphsDo: + [ : each | (each isSystemWindow and: [ each containsPoint: self position ]) ifTrue: [ ^ each ] ]. + ^ nil! Item was changed: ----- Method: Morph>>handleMouseDown: (in category 'events-processing') ----- handleMouseDown: anEvent "System level event handling." anEvent wasHandled ifTrue:[^self]. "not interested" anEvent hand removePendingBalloonFor: self. anEvent hand removePendingHaloFor: self. anEvent wasHandled: true. (anEvent controlKeyPressed and: [anEvent blueButtonChanged not and: [Preferences cmdGesturesEnabled]]) ifTrue: [^ self invokeMetaMenu: anEvent]. "Make me modal during mouse transitions" anEvent hand newMouseFocus: self event: anEvent. anEvent blueButtonChanged ifTrue:[^self blueButtonDown: anEvent]. "this mouse down could be the start of a gesture, or the end of a gesture focus" (self isGestureStart: anEvent) ifTrue: [^ self gestureStart: anEvent]. + "Filter events sent to the subwidgets of non-MorphicModels in inactive windows, if they are not supposed to receive them due to windowActiveOnFirstClick being set to false. I don't like having this check for owningWindow here, is there another way?" + SystemWindow allWindowsAcceptInput + ifTrue: + [ self owningWindow + ifNil: [ self mouseDown: anEvent ] + ifNotNil: + [ : owningWindow | + (owningWindow canProcessMouseDown: anEvent) + ifTrue: [ self mouseDown: anEvent ] + ifFalse: [ owningWindow activate ] ] ] + ifFalse: [ self mouseDown: anEvent ]. - self mouseDown: anEvent. Preferences maintainHalos ifFalse:[ anEvent hand removeHaloFromClick: anEvent on: self ]. (self handlesMouseStillDown: anEvent) ifTrue:[ self startStepping: #handleMouseStillDown: at: Time millisecondClockValue + self mouseStillDownThreshold arguments: {anEvent copy resetHandlerFields} stepTime: self mouseStillDownStepRate ]. ! Item was changed: ----- Method: Morph>>keyboardFocusChange: (in category 'event handling') ----- + keyboardFocusChange: aBoolean - keyboardFocusChange: aBoolean "The message is sent to a morph when its keyboard focus change. The given argument indicates that the receiver is gaining keyboard focus (versus losing) the keyboard focus. Morphs that accept keystrokes should change their appearance in some way when they are the current keyboard focus." + self eventHandler ifNotNil: + [ : h | h + keyboardFocusChange: aBoolean + fromMorph: self ]. + "Support for 'Focus Follows Mouse'. Want the window to maintain focus even after the pointer moves into its title bar." + self owningWindow ifNotNil: [ : window | window lookFocused: (aBoolean or: [ window containsPoint: ActiveHand position]) ]. + self indicateKeyboardFocus ifTrue: [ self changed ]! - - self eventHandler - ifNotNil: [:h | h keyboardFocusChange: aBoolean fromMorph: self]. - - self indicateKeyboardFocus - ifTrue: [self changed].! Item was added: + ----- Method: Morph>>owningWindow (in category 'private') ----- + owningWindow + self withAllOwnersDo: [ : each | each isSystemWindow ifTrue: [ ^ each ] ]. + ^ nil! Item was added: + ----- Method: MorphicModel>>handleMouseDown: (in category 'events-processing') ----- + handleMouseDown: aMouseEvent + SystemWindow allWindowsAcceptInput ifTrue: + [ "This override is needed so that, when 'Window Active On First Click' is false, clicking on a PluggableListMorph of an inactive window will, correctly, NOT update the selection in the list; it will only activate the window." + aMouseEvent blueButtonChanged ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window canProcessMouseDown: aMouseEvent) ifFalse: [ ^ window activate ]. + Model windowActiveOnFirstClick ifTrue: [ window activate ] ] ] ]. + super handleMouseDown: aMouseEvent! Item was changed: ----- Method: PluggableListMorph>>mouseEnter: (in category 'events') ----- + mouseEnter: event - mouseEnter: event - super mouseEnter: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand newKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand newKeyboardFocus: self. ]! Item was changed: ----- Method: PluggableListMorph>>mouseLeave: (in category 'events') ----- + mouseLeave: event + "The mouse has left the bounds of the receiver" - mouseLeave: event - "The mouse has left the area of the receiver" - super mouseLeave: event. - self hoverRow: nil. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand releaseKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand releaseKeyboardFocus: self].! Item was changed: ----- Method: PluggableTextMorph>>mouseEnter: (in category 'event handling') ----- mouseEnter: event super mouseEnter: event. selectionInterval ifNotNil: [textMorph editor selectInterval: selectionInterval; setEmphasisHere]. textMorph selectionChanged. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[ - Preferences mouseOverForKeyboardFocus ifTrue:[ event hand newKeyboardFocus: self]! Item was changed: ----- Method: PluggableTextMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + "The mouse has left the bounds of the receiver" - "The mouse has left the area of the receiver" - textMorph ifNotNil: [selectionInterval := textMorph editor selectionInterval]. super mouseLeave: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: - Preferences mouseOverForKeyboardFocus ifTrue: [event hand releaseKeyboardFocus: self]! Item was changed: ----- Method: ProportionalSplitterMorph>>proposedCorrectionWouldCauseFocusChange: (in category 'layout') ----- proposedCorrectionWouldCauseFocusChange: correction + ^ (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) and: - ^ Preferences mouseOverForKeyboardFocus and: [ | edge | splitsTopAndBottom ifTrue: [ edge := correction positive ifTrue: [ self bottom + 3 ] ifFalse: [ self top - 3 ]. ActiveHand position y inRangeOf: edge and: edge + correction ] ifFalse: [ edge := correction positive ifTrue: [ self right ] ifFalse: [ self left ]. ActiveHand position x inRangeOf: edge and: edge + correction ] ]! Item was changed: ----- Method: ScrollPane>>mouseEnter: (in category 'event handling') ----- mouseEnter: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := true]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := true]. (owner isSystemWindow) ifTrue: [owner paneTransition: event]. retractableScrollBar ifTrue:[ self hideOrShowScrollBars ]. ! Item was changed: ----- Method: ScrollPane>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := false]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := false]. retractableScrollBar ifTrue: [self hideScrollBars]. (owner isSystemWindow) ifTrue: [owner paneTransition: event] ! Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: aMouseEvent super mouseLeave: aMouseEvent. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! - Preferences mouseOverForKeyboardFocus ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! Item was changed: MorphicModel subclass: #SystemWindow instanceVariableNames: 'labelString stripes label closeBox collapseBox activeOnlyOnTop paneMorphs paneRects collapsedFrame fullFrame isCollapsed menuBox mustNotClose labelWidgetAllowance updatablePanes allowReframeHandles labelArea expandBox' + classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient FocusFollowsMouse GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow WindowsRaiseOnClick' - classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow' poolDictionaries: '' category: 'Morphic-Windows'! !SystemWindow commentStamp: '<historical>' prior: 0! SystemWindow is the Morphic equivalent of StandardSystemView -- a labelled container for rectangular views, with iconic facilities for close, collapse/expand, and resizing. The attribute onlyActiveOnTop, if set to true (and any call to activate will set this), determines that only the top member of a collection of such windows on the screen shall be active. To be not active means that a mouse click in any region will only result in bringing the window to the top and then making it active.! Item was added: + ----- Method: SystemWindow class>>allWindowsAcceptInput (in category 'private') ----- + allWindowsAcceptInput + "With either of these two preferences settings, inactive windows will not have their widgets locked. All windows accept input as if they were active." + ^ self focusFollowsMouse or: [ self windowsRaiseOnClick not ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse (in category 'preferences') ----- + focusFollowsMouse + <preference: 'Focus Follows Mouse' + category: 'windows' + description: 'When true, the widget under the hand has keyboard focus.' + type: #Boolean> + ^ FocusFollowsMouse ifNil: [ false ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse: (in category 'preferences') ----- + focusFollowsMouse: aBoolean + (FocusFollowsMouse := aBoolean) == true. + self reconfigureWindowsForFocus! Item was added: + ----- Method: SystemWindow class>>reconfigureWindowsForFocus (in category 'private') ----- + reconfigureWindowsForFocus + self withAllSubclasses do: + [ : eachSubclass | eachSubclass allInstances do: + [ : eachInstance | eachInstance configureFocus ] ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick (in category 'preferences') ----- + windowsRaiseOnClick + <preference: 'Windows Raise On Click' + category: 'windows' + description: 'If true, a click anywhere within a window will raise it above all other windows to become the active window. If false, it won''t.' + type: #Boolean> + ^ WindowsRaiseOnClick ifNil: [ true ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick: (in category 'preferences') ----- + windowsRaiseOnClick: aBoolean + (WindowsRaiseOnClick := aBoolean == true). + self reconfigureWindowsForFocus! Item was changed: ----- Method: SystemWindow>>activate (in category 'top window') ----- activate "Activate the owner too." |mo mc| mo := self modalOwner. mc := self modalChild. mc isNil ifFalse: [mc owner notNil ifTrue: [ mc activate. ^mc modalChild isNil ifTrue: [mc flash]]]. (isCollapsed not and: [ self paneMorphs size > 1 and: [ self splitters isEmpty ] ]) ifTrue: [ self addPaneSplitters ]. self activateWindow. self rememberedKeyboardFocus ifNil: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]] ifNotNil: [:m | m world ifNil: [self rememberKeyboardFocus: nil] "deleted" ifNotNil: [:w | m wantsKeyboardFocus ifTrue: [m takeKeyboardFocus] ifFalse: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]]]]. + (mo notNil and: [mo isSystemWindow]) - (mo notNil and: [mo isKindOf: SystemWindow]) ifTrue: [mo bringBehind: self]! Item was changed: ----- Method: SystemWindow>>activateWindow (in category 'top window') ----- activateWindow "Bring me to the front and make me able to respond to mouse and keyboard. Was #activate (sw 5/18/2001 23:20)" + | oldTop outerMorph sketchEditor pal windowUnderneath | - - | oldTop outerMorph sketchEditor pal | - self hasDropShadow: Preferences menuAppearance3d. - outerMorph := self topRendererOrSelf. outerMorph owner ifNil: [^ self "avoid spurious activate when drop in trash"]. + self hasDropShadow: Preferences menuAppearance3d. oldTop := TopWindow. oldTop = self ifTrue: [^self]. TopWindow := self. oldTop ifNotNil: [oldTop passivate]. outerMorph owner firstSubmorph == outerMorph ifFalse: ["Bring me (with any flex) to the top if not already" outerMorph owner addMorphFront: outerMorph]. + self configureFocus. - self submorphsDo: [:m | m unlock]. - - label ifNotNil: [label color: Color black]. - - self undimWindowButtons. - labelArea ifNotNil: [labelArea submorphsDo: [:m | m unlock; show]]. - self - setStripeColorsFrom: self paneColorToUse; - adoptPaneColor: self paneColorToUse. - self isCollapsed ifFalse: [model modelWakeUpIn: self. self positionSubmorphs. labelArea ifNil: [self adjustBorderUponActivationWhenLabeless]]. - (sketchEditor := self extantSketchEditor) ifNotNil: [sketchEditor comeToFront. (pal := self world findA: PaintBoxMorph) ifNotNil: [pal comeToFront]]. + self updatePaneColors. + "Newly spawned windows are normally active, but if focusFollowsMouse is set, then the focused window can only be the one under the hand." + (self class allWindowsAcceptInput not or: [ (windowUnderneath := ActiveHand windowUnderneath) isNil or: [ windowUnderneath == self ] ]) + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! - - self updatePaneColors.! Item was added: + ----- Method: SystemWindow>>canProcessMouseDown: (in category 'top window') ----- + canProcessMouseDown: anEvent + "In case 'Focus Follows Mouse' is set, then there are two possibilities for mouse input on a background window: if 'Window Active On First Click' is set, it must be honored and the window must be activated. If it is not set, then the behavior depends on 'Windows Raise On Click' setting. If its true, then just activate the window and DON'T process aMouseEvent. If false, then process the event in any case." + ^ self isActive or: [ Model windowActiveOnFirstClick or: [ SystemWindow windowsRaiseOnClick not ] ]! Item was added: + ----- Method: SystemWindow>>configureFocus (in category 'top window') ----- + configureFocus + "Make me unable to respond to mouse and keyboard unless allWindowsAcceptInput is set or 'Window Active On First Click' is unset. Otherwise, the classic Squeak behavior of Control boxes remaining active, except in novice mode." + self submorphsDo: + [ : each | each lock: + (self isActive not and: + [ each == labelArea + ifTrue: [ self class windowsRaiseOnClick not ] + ifFalse: [ self class allWindowsAcceptInput not ] ]) ]. + labelArea + ifNil: [ "i.e. label area is nil, so we're titleless" + self adjustBorderUponDeactivationWhenLabeless ] + ifNotNil: + [ labelArea submorphsDo: + [ : each | | classicSqueakBehavior | + classicSqueakBehavior := self class allWindowsAcceptInput not. + each lock: + (classicSqueakBehavior + ifTrue: + [ self isActive not and: + [ Preferences noviceMode or: + [ each ~~ closeBox and: [ each ~~ collapseBox ] ] ] ] + ifFalse: + [ self isActive not and: [ Model windowActiveOnFirstClick not ] ]) ] ]! Item was changed: ----- Method: SystemWindow>>handleListenEvent: (in category 'events') ----- handleListenEvent: evt "Make sure we lock our contents after DnD has finished" evt isMouse ifFalse:[^self]. evt hand hasSubmorphs ifTrue:[^self]. "still dragging" + (self isActive and: [ self class allWindowsAcceptInput not ]) ifFalse: [self configureFocus]. - self == TopWindow ifFalse:[self lockInactivePortions]. evt hand removeMouseListener: self.! Item was added: + ----- Method: SystemWindow>>handlesMouseOver: (in category 'events') ----- + handlesMouseOver: anEvent + ^ true! Item was removed: - ----- Method: SystemWindow>>lockInactivePortions (in category 'top window') ----- - lockInactivePortions - "Make me unable to respond to mouse and keyboard. Control boxes remain active, except in novice mode" - - self submorphsDo: [:m | m == labelArea ifFalse: [m lock]]. - self dimWindowButtons. - labelArea ifNotNil: - [labelArea submorphsDo: - [:m | - (Preferences noviceMode or: [m ~~ closeBox and: [m ~~ collapseBox]]) - ifTrue: [m lock]]] - ifNil: "i.e. label area is nil, so we're titleless" - [self adjustBorderUponDeactivationWhenLabeless].! Item was added: + ----- Method: SystemWindow>>lookFocused (in category 'top window') ----- + lookFocused + label ifNotNil: [ label color: Color black ]. + (self isActive or: [Model windowActiveOnFirstClick]) ifTrue: [ self undimWindowButtons ]. + self + updatePaneColors ; + adoptPaneColor: self paneColorToUse! Item was added: + ----- Method: SystemWindow>>lookFocused: (in category 'top window') ----- + lookFocused: aBoolean + aBoolean + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! Item was added: + ----- Method: SystemWindow>>lookUnfocused (in category 'top window') ----- + lookUnfocused + label ifNotNil: [ label color: Color darkGray ]. + self dimWindowButtons. + self paneColorToUseWhenNotActive in: + [ : color | self + setStripeColorsFrom: color ; + adoptPaneColor: color ]! Item was added: + ----- Method: SystemWindow>>mouseEnter: (in category 'events') ----- + mouseEnter: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseEnter: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookFocused ]! Item was added: + ----- Method: SystemWindow>>mouseLeave: (in category 'events') ----- + mouseLeave: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseLeave: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookUnfocused ]! Item was changed: ----- Method: SystemWindow>>mouseLeaveDragging: (in category 'events') ----- mouseLeaveDragging: evt "lock children after drop operations" + (self isActive and:[evt hand hasSubmorphs and: [self class allWindowsAcceptInput not]]) ifTrue:[ + self configureFocus. - (self ~~ TopWindow and:[evt hand hasSubmorphs]) ifTrue:[ - self lockInactivePortions. evt hand removeMouseListener: self. ].! Item was changed: ----- Method: SystemWindow>>passivate (in category 'top window') ----- passivate + "Lose my drop shadlow and reconfigure my focus according to preferences." + self + hasDropShadow: false ; + configureFocus ; + lookUnfocused. + model modelSleep! - "Make me unable to respond to mouse and keyboard" - - label ifNotNil: [label color: Color darkGray]. - - self hasDropShadow: false. - self paneColorToUseWhenNotActive in: [:c | - self - setStripeColorsFrom: c; - adoptPaneColor: c]. - - model modelSleep. - - self lockInactivePortions - ! Item was changed: ----- Method: SystemWindowButton>>mouseEnter: (in category 'visual properties') ----- + mouseEnter: evt + | classicSqueakBehavior | + classicSqueakBehavior := SystemWindow allWindowsAcceptInput not. + classicSqueakBehavior + ifTrue: [ self highlight ] + ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window isActive or: [ Model windowActiveOnFirstClick ]) ifTrue: [ self highlight ] ] ]! - mouseEnter: evt - - self highlight. - ! Item was changed: ----- Method: TextMorphForEditView>>mouseUp: (in category 'event handling') ----- mouseUp: evt super mouseUp: evt. self stopSteppingSelector: #autoScrollView:. + SystemWindow allWindowsAcceptInput ifFalse: [editView scrollSelectionIntoView: evt]. - editView scrollSelectionIntoView: evt. - self setCompositionWindow. !
1
0
0
0
The Trunk: Morphic-cmm.1008.mcz
by commits@source.squeak.org
05 Oct '15
05 Oct '15
Chris Muller uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-cmm.1008.mcz
==================== Summary ==================== Name: Morphic-cmm.1008 Author: cmm Time: 14 September 2015, 2:27:11.585 pm UUID: 056757ae-538d-4a80-b9d2-0bd93c2b24c9 Ancestors: Morphic-mt.1005 Integrate 'Focus Follows Mouse' and 'Windows Raise On Click' features from X and Gnome. =============== Diff against Morphic-mt.1005 =============== Item was changed: ----- Method: CornerGripMorph>>mouseMove: (in category 'as yet unclassified') ----- mouseMove: anEvent | delta | target ifNil: [^ self]. target fastFramingOn ifTrue: [delta := target doFastWindowReframe: self ptName] ifFalse: [ + delta := lastMouse ifNil: [0@0] ifNotNil: [anEvent cursorPoint - lastMouse]. - delta := anEvent cursorPoint - lastMouse. lastMouse := anEvent cursorPoint. self apply: delta. self bounds: (self bounds origin + delta extent: self bounds extent)].! Item was changed: ----- Method: HandMorph>>handleEvent: (in category 'events-processing') ----- handleEvent: anEvent | evt ofs | owner ifNil:[^self]. evt := anEvent. EventStats ifNil:[EventStats := IdentityDictionary new]. EventStats at: #count put: (EventStats at: #count ifAbsent:[0]) + 1. EventStats at: evt type put: (EventStats at: evt type ifAbsent:[0]) + 1. evt isMouseOver ifTrue:[^self sendMouseEvent: evt]. ShowEvents == true ifTrue:[ + Display fill: (0@0 extent: 300@120) rule: Form over fillColor: Color white. - Display fill: (0@0 extent: 250@120) rule: Form over fillColor: Color white. ofs := (owner hands indexOf: self) - 1 * 60. + evt isKeyboard + ifTrue: [ 'key: ', evt printString displayAt: (0@ofs) + (0@30) ] + ifFalse: [ 'evt: ', evt printString displayAt: (0@ofs) + (0@0) ]. + 'kf: ', self keyboardFocus printString displayAt: (0@ofs)+(0@45). - evt printString displayAt: (0@ofs) + (evt isKeyboard ifTrue:[0@30] ifFalse:[0@0]). - self keyboardFocus printString displayAt: (0@ofs)+(0@45). ]. "Notify listeners" self sendListenEvent: evt to: self eventListeners. evt isWindowEvent ifTrue: [ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isKeyboard ifTrue:[ self sendListenEvent: evt to: self keyboardListeners. self sendKeyboardEvent: evt. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isDropEvent ifTrue:[ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isMouse ifTrue:[ self sendListenEvent: evt to: self mouseListeners. lastMouseEvent := evt]. "Check for pending drag or double click operations." mouseClickState ifNotNil:[ (mouseClickState handleEvent: evt from: self) ifFalse:[ "Possibly dispatched #click: or something and will not re-establish otherwise" ^self mouseOverHandler processMouseOver: lastMouseEvent]]. evt isMove ifTrue:[ self position: evt position. self sendMouseEvent: evt. ] ifFalse:[ "Issue a synthetic move event if we're not at the position of the event" (evt position = self position) ifFalse:[self moveToEvent: evt]. "Drop submorphs on button events" (self hasSubmorphs) ifTrue:[self dropMorphs: evt] ifFalse:[self sendMouseEvent: evt]. ]. + ShowEvents == true ifTrue:['mf: ', self mouseFocus printString displayAt: (0@ofs) + (0@15)]. - ShowEvents == true ifTrue:[self mouseFocus printString displayAt: (0@ofs) + (0@15)]. self mouseOverHandler processMouseOver: lastMouseEvent. "self handleDragOutside: anEvent." ! Item was added: + ----- Method: HandMorph>>windowUnderneath (in category 'accessing') ----- + windowUnderneath + ActiveWorld submorphsDo: + [ : each | (each isSystemWindow and: [ each containsPoint: self position ]) ifTrue: [ ^ each ] ]. + ^ nil! Item was changed: ----- Method: Morph>>handleMouseDown: (in category 'events-processing') ----- handleMouseDown: anEvent "System level event handling." anEvent wasHandled ifTrue:[^self]. "not interested" anEvent hand removePendingBalloonFor: self. anEvent hand removePendingHaloFor: self. anEvent wasHandled: true. (anEvent controlKeyPressed and: [anEvent blueButtonChanged not and: [Preferences cmdGesturesEnabled]]) ifTrue: [^ self invokeMetaMenu: anEvent]. "Make me modal during mouse transitions" anEvent hand newMouseFocus: self event: anEvent. anEvent blueButtonChanged ifTrue:[^self blueButtonDown: anEvent]. "this mouse down could be the start of a gesture, or the end of a gesture focus" (self isGestureStart: anEvent) ifTrue: [^ self gestureStart: anEvent]. + "Filter events sent to the subwidgets of non-MorphicModels in inactive windows, if they are not supposed to receive them due to windowActiveOnFirstClick being set to false. I don't like having this check for owningWindow here, is there another way?" + SystemWindow allWindowsAcceptInput + ifTrue: + [ self owningWindow + ifNil: [ self mouseDown: anEvent ] + ifNotNil: + [ : owningWindow | + (owningWindow canProcessMouseDown: anEvent) + ifTrue: [ self mouseDown: anEvent ] + ifFalse: [ owningWindow activate ] ] ] + ifFalse: [ self mouseDown: anEvent ]. - self mouseDown: anEvent. Preferences maintainHalos ifFalse:[ anEvent hand removeHaloFromClick: anEvent on: self ]. (self handlesMouseStillDown: anEvent) ifTrue:[ self startStepping: #handleMouseStillDown: at: Time millisecondClockValue + self mouseStillDownThreshold arguments: {anEvent copy resetHandlerFields} stepTime: self mouseStillDownStepRate ]. ! Item was changed: ----- Method: Morph>>keyboardFocusChange: (in category 'event handling') ----- + keyboardFocusChange: aBoolean - keyboardFocusChange: aBoolean "The message is sent to a morph when its keyboard focus change. The given argument indicates that the receiver is gaining keyboard focus (versus losing) the keyboard focus. Morphs that accept keystrokes should change their appearance in some way when they are the current keyboard focus." + self eventHandler ifNotNil: + [ : h | h + keyboardFocusChange: aBoolean + fromMorph: self ]. + "Support for 'Focus Follows Mouse'. Want the window to maintain focus even after the pointer moves into its title bar." + self owningWindow ifNotNil: [ : window | window lookFocused: (aBoolean or: [ window containsPoint: ActiveHand position]) ]. + self indicateKeyboardFocus ifTrue: [ self changed ]! - - self eventHandler - ifNotNil: [:h | h keyboardFocusChange: aBoolean fromMorph: self]. - - self indicateKeyboardFocus - ifTrue: [self changed].! Item was added: + ----- Method: Morph>>owningWindow (in category 'private') ----- + owningWindow + self withAllOwnersDo: [ : each | each isSystemWindow ifTrue: [ ^ each ] ]. + ^ nil! Item was added: + ----- Method: MorphicModel>>handleMouseDown: (in category 'events-processing') ----- + handleMouseDown: aMouseEvent + SystemWindow allWindowsAcceptInput ifTrue: + [ "This override is needed so that, when 'Window Active On First Click' is false, clicking on a PluggableListMorph of an inactive window will, correctly, NOT update the selection in the list; it will only activate the window." + aMouseEvent blueButtonChanged ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window canProcessMouseDown: aMouseEvent) ifFalse: [ ^ window activate ]. + Model windowActiveOnFirstClick ifTrue: [ window activate ] ] ] ]. + super handleMouseDown: aMouseEvent! Item was changed: ----- Method: PluggableListMorph>>mouseEnter: (in category 'events') ----- + mouseEnter: event - mouseEnter: event - super mouseEnter: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand newKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand newKeyboardFocus: self. ]! Item was changed: ----- Method: PluggableListMorph>>mouseLeave: (in category 'events') ----- + mouseLeave: event + "The mouse has left the bounds of the receiver" - mouseLeave: event - "The mouse has left the area of the receiver" - super mouseLeave: event. - self hoverRow: nil. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand releaseKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand releaseKeyboardFocus: self].! Item was changed: ----- Method: PluggableTextMorph>>mouseEnter: (in category 'event handling') ----- mouseEnter: event super mouseEnter: event. selectionInterval ifNotNil: [textMorph editor selectInterval: selectionInterval; setEmphasisHere]. textMorph selectionChanged. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[ - Preferences mouseOverForKeyboardFocus ifTrue:[ event hand newKeyboardFocus: self]! Item was changed: ----- Method: PluggableTextMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + "The mouse has left the bounds of the receiver" - "The mouse has left the area of the receiver" - textMorph ifNotNil: [selectionInterval := textMorph editor selectionInterval]. super mouseLeave: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: - Preferences mouseOverForKeyboardFocus ifTrue: [event hand releaseKeyboardFocus: self]! Item was changed: ----- Method: ProportionalSplitterMorph>>proposedCorrectionWouldCauseFocusChange: (in category 'layout') ----- proposedCorrectionWouldCauseFocusChange: correction + ^ (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) and: - ^ Preferences mouseOverForKeyboardFocus and: [ | edge | splitsTopAndBottom ifTrue: [ edge := correction positive ifTrue: [ self bottom + 3 ] ifFalse: [ self top - 3 ]. ActiveHand position y inRangeOf: edge and: edge + correction ] ifFalse: [ edge := correction positive ifTrue: [ self right ] ifFalse: [ self left ]. ActiveHand position x inRangeOf: edge and: edge + correction ] ]! Item was changed: ----- Method: ScrollPane>>mouseEnter: (in category 'event handling') ----- mouseEnter: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := true]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := true]. (owner isSystemWindow) ifTrue: [owner paneTransition: event]. retractableScrollBar ifTrue:[ self hideOrShowScrollBars ]. ! Item was changed: ----- Method: ScrollPane>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := false]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := false]. retractableScrollBar ifTrue: [self hideScrollBars]. (owner isSystemWindow) ifTrue: [owner paneTransition: event] ! Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: aMouseEvent super mouseLeave: aMouseEvent. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! - Preferences mouseOverForKeyboardFocus ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! Item was changed: MorphicModel subclass: #SystemWindow instanceVariableNames: 'labelString stripes label closeBox collapseBox activeOnlyOnTop paneMorphs paneRects collapsedFrame fullFrame isCollapsed menuBox mustNotClose labelWidgetAllowance updatablePanes allowReframeHandles labelArea expandBox' + classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient FocusFollowsMouse GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow WindowsRaiseOnClick' - classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow' poolDictionaries: '' category: 'Morphic-Windows'! !SystemWindow commentStamp: '<historical>' prior: 0! SystemWindow is the Morphic equivalent of StandardSystemView -- a labelled container for rectangular views, with iconic facilities for close, collapse/expand, and resizing. The attribute onlyActiveOnTop, if set to true (and any call to activate will set this), determines that only the top member of a collection of such windows on the screen shall be active. To be not active means that a mouse click in any region will only result in bringing the window to the top and then making it active.! Item was added: + ----- Method: SystemWindow class>>allWindowsAcceptInput (in category 'private') ----- + allWindowsAcceptInput + "With either of these two preferences settings, inactive windows will not have their widgets locked. All windows accept input as if they were active." + ^ self focusFollowsMouse or: [ self windowsRaiseOnClick not ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse (in category 'preferences') ----- + focusFollowsMouse + <preference: 'Focus Follows Mouse' + category: 'windows' + description: 'When true, the widget under the hand has keyboard focus.' + type: #Boolean> + ^ FocusFollowsMouse ifNil: [ false ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse: (in category 'preferences') ----- + focusFollowsMouse: aBoolean + (FocusFollowsMouse := aBoolean) == true. + self reconfigureWindowsForFocus! Item was added: + ----- Method: SystemWindow class>>reconfigureWindowsForFocus (in category 'private') ----- + reconfigureWindowsForFocus + self withAllSubclasses do: + [ : eachSubclass | eachSubclass allInstances do: + [ : eachInstance | eachInstance configureFocus ] ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick (in category 'preferences') ----- + windowsRaiseOnClick + <preference: 'Windows Raise On Click' + category: 'windows' + description: 'If true, a click anywhere within a window will raise it above all other windows to become the active window. If false, it won''t.' + type: #Boolean> + ^ WindowsRaiseOnClick ifNil: [ true ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick: (in category 'preferences') ----- + windowsRaiseOnClick: aBoolean + (WindowsRaiseOnClick := aBoolean == true). + self reconfigureWindowsForFocus! Item was changed: ----- Method: SystemWindow>>activate (in category 'top window') ----- activate "Activate the owner too." |mo mc| mo := self modalOwner. mc := self modalChild. mc isNil ifFalse: [mc owner notNil ifTrue: [ mc activate. ^mc modalChild isNil ifTrue: [mc flash]]]. (isCollapsed not and: [ self paneMorphs size > 1 and: [ self splitters isEmpty ] ]) ifTrue: [ self addPaneSplitters ]. self activateWindow. self rememberedKeyboardFocus ifNil: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]] ifNotNil: [:m | m world ifNil: [self rememberKeyboardFocus: nil] "deleted" ifNotNil: [:w | m wantsKeyboardFocus ifTrue: [m takeKeyboardFocus] ifFalse: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]]]]. + (mo notNil and: [mo isSystemWindow]) - (mo notNil and: [mo isKindOf: SystemWindow]) ifTrue: [mo bringBehind: self]! Item was changed: ----- Method: SystemWindow>>activateWindow (in category 'top window') ----- activateWindow "Bring me to the front and make me able to respond to mouse and keyboard. Was #activate (sw 5/18/2001 23:20)" + | oldTop outerMorph sketchEditor pal windowUnderneath | - - | oldTop outerMorph sketchEditor pal | - self hasDropShadow: Preferences menuAppearance3d. - outerMorph := self topRendererOrSelf. outerMorph owner ifNil: [^ self "avoid spurious activate when drop in trash"]. + self hasDropShadow: Preferences menuAppearance3d. oldTop := TopWindow. oldTop = self ifTrue: [^self]. TopWindow := self. oldTop ifNotNil: [oldTop passivate]. outerMorph owner firstSubmorph == outerMorph ifFalse: ["Bring me (with any flex) to the top if not already" outerMorph owner addMorphFront: outerMorph]. + self configureFocus. - self submorphsDo: [:m | m unlock]. - - label ifNotNil: [label color: Color black]. - - self undimWindowButtons. - labelArea ifNotNil: [labelArea submorphsDo: [:m | m unlock; show]]. - self - setStripeColorsFrom: self paneColorToUse; - adoptPaneColor: self paneColorToUse. - self isCollapsed ifFalse: [model modelWakeUpIn: self. self positionSubmorphs. labelArea ifNil: [self adjustBorderUponActivationWhenLabeless]]. - (sketchEditor := self extantSketchEditor) ifNotNil: [sketchEditor comeToFront. (pal := self world findA: PaintBoxMorph) ifNotNil: [pal comeToFront]]. + self updatePaneColors. + "Newly spawned windows are normally active, but if focusFollowsMouse is set, then the focused window can only be the one under the hand." + (self class allWindowsAcceptInput not or: [ (windowUnderneath := ActiveHand windowUnderneath) isNil or: [ windowUnderneath == self ] ]) + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! - - self updatePaneColors.! Item was added: + ----- Method: SystemWindow>>canProcessMouseDown: (in category 'top window') ----- + canProcessMouseDown: anEvent + "In case 'Focus Follows Mouse' is set, then there are two possibilities for mouse input on a background window: if 'Window Active On First Click' is set, it must be honored and the window must be activated. If it is not set, then the behavior depends on 'Windows Raise On Click' setting. If its true, then just activate the window and DON'T process aMouseEvent. If false, then process the event in any case." + ^ self isActive or: [ Model windowActiveOnFirstClick or: [ SystemWindow windowsRaiseOnClick not ] ]! Item was added: + ----- Method: SystemWindow>>configureFocus (in category 'top window') ----- + configureFocus + "Make me unable to respond to mouse and keyboard unless allWindowsAcceptInput is set or 'Window Active On First Click' is unset. Otherwise, the classic Squeak behavior of Control boxes remaining active, except in novice mode." + self submorphsDo: + [ : each | each lock: + (self isActive not and: + [ each == labelArea + ifTrue: [ self class windowsRaiseOnClick not ] + ifFalse: [ self class allWindowsAcceptInput not ] ]) ]. + labelArea + ifNil: [ "i.e. label area is nil, so we're titleless" + self adjustBorderUponDeactivationWhenLabeless ] + ifNotNil: + [ labelArea submorphsDo: + [ : each | | classicSqueakBehavior | + classicSqueakBehavior := self class allWindowsAcceptInput not. + each lock: + (classicSqueakBehavior + ifTrue: + [ self isActive not and: + [ Preferences noviceMode or: + [ each ~~ closeBox and: [ each ~~ collapseBox ] ] ] ] + ifFalse: + [ self isActive not and: [ Model windowActiveOnFirstClick not ] ]) ] ]! Item was changed: ----- Method: SystemWindow>>handleListenEvent: (in category 'events') ----- handleListenEvent: evt "Make sure we lock our contents after DnD has finished" evt isMouse ifFalse:[^self]. evt hand hasSubmorphs ifTrue:[^self]. "still dragging" + (self isActive and: [ self class allWindowsAcceptInput not ]) ifFalse: [self configureFocus]. - self == TopWindow ifFalse:[self lockInactivePortions]. evt hand removeMouseListener: self.! Item was added: + ----- Method: SystemWindow>>handlesMouseOver: (in category 'events') ----- + handlesMouseOver: anEvent + ^ true! Item was removed: - ----- Method: SystemWindow>>lockInactivePortions (in category 'top window') ----- - lockInactivePortions - "Make me unable to respond to mouse and keyboard. Control boxes remain active, except in novice mode" - - self submorphsDo: [:m | m == labelArea ifFalse: [m lock]]. - self dimWindowButtons. - labelArea ifNotNil: - [labelArea submorphsDo: - [:m | - (Preferences noviceMode or: [m ~~ closeBox and: [m ~~ collapseBox]]) - ifTrue: [m lock]]] - ifNil: "i.e. label area is nil, so we're titleless" - [self adjustBorderUponDeactivationWhenLabeless].! Item was added: + ----- Method: SystemWindow>>lookFocused (in category 'top window') ----- + lookFocused + label ifNotNil: [ label color: Color black ]. + (self isActive or: [Model windowActiveOnFirstClick]) ifTrue: [ self undimWindowButtons ]. + self + updatePaneColors ; + adoptPaneColor: self paneColorToUse! Item was added: + ----- Method: SystemWindow>>lookFocused: (in category 'top window') ----- + lookFocused: aBoolean + aBoolean + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! Item was added: + ----- Method: SystemWindow>>lookUnfocused (in category 'top window') ----- + lookUnfocused + label ifNotNil: [ label color: Color darkGray ]. + self dimWindowButtons. + self paneColorToUseWhenNotActive in: + [ : color | self + setStripeColorsFrom: color ; + adoptPaneColor: color ]! Item was added: + ----- Method: SystemWindow>>mouseEnter: (in category 'events') ----- + mouseEnter: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseEnter: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookFocused ]! Item was added: + ----- Method: SystemWindow>>mouseLeave: (in category 'events') ----- + mouseLeave: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseLeave: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookUnfocused ]! Item was changed: ----- Method: SystemWindow>>mouseLeaveDragging: (in category 'events') ----- mouseLeaveDragging: evt "lock children after drop operations" + (self isActive and:[evt hand hasSubmorphs and: [self class allWindowsAcceptInput not]]) ifTrue:[ + self configureFocus. - (self ~~ TopWindow and:[evt hand hasSubmorphs]) ifTrue:[ - self lockInactivePortions. evt hand removeMouseListener: self. ].! Item was changed: ----- Method: SystemWindow>>passivate (in category 'top window') ----- passivate + "Lose my drop shadlow and reconfigure my focus according to preferences." + self + hasDropShadow: false ; + configureFocus ; + lookUnfocused. + model modelSleep! - "Make me unable to respond to mouse and keyboard" - - label ifNotNil: [label color: Color darkGray]. - - self hasDropShadow: false. - self paneColorToUseWhenNotActive in: [:c | - self - setStripeColorsFrom: c; - adoptPaneColor: c]. - - model modelSleep. - - self lockInactivePortions - ! Item was changed: ----- Method: SystemWindowButton>>mouseEnter: (in category 'visual properties') ----- + mouseEnter: evt + | classicSqueakBehavior | + classicSqueakBehavior := SystemWindow allWindowsAcceptInput not. + classicSqueakBehavior + ifTrue: [ self highlight ] + ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window isActive or: [ Model windowActiveOnFirstClick ]) ifTrue: [ self highlight ] ] ]! - mouseEnter: evt - - self highlight. - ! Item was changed: ----- Method: TextMorphForEditView>>mouseUp: (in category 'event handling') ----- mouseUp: evt super mouseUp: evt. self stopSteppingSelector: #autoScrollView:. + SystemWindow allWindowsAcceptInput ifFalse: [editView scrollSelectionIntoView: evt]. - editView scrollSelectionIntoView: evt. - self setCompositionWindow. !
1
0
0
0
The Trunk: Morphic-cmm.1009.mcz
by commits@source.squeak.org
05 Oct '15
05 Oct '15
Chris Muller uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-cmm.1009.mcz
==================== Summary ==================== Name: Morphic-cmm.1009 Author: cmm Time: 5 October 2015, 1:56:52.458 pm UUID: f0ce65ed-cf24-44b5-9ae5-17c5cb319b9c Ancestors: Morphic-cmm.1008, Morphic-mt.1007 Merged. =============== Diff against Morphic-mt.1007 =============== Item was changed: ----- Method: CornerGripMorph>>mouseMove: (in category 'as yet unclassified') ----- mouseMove: anEvent | delta | target ifNil: [^ self]. target fastFramingOn ifTrue: [delta := target doFastWindowReframe: self ptName] ifFalse: [ + delta := lastMouse ifNil: [0@0] ifNotNil: [anEvent cursorPoint - lastMouse]. - delta := anEvent cursorPoint - lastMouse. lastMouse := anEvent cursorPoint. self apply: delta. self bounds: (self bounds origin + delta extent: self bounds extent)].! Item was changed: ----- Method: HandMorph>>handleEvent: (in category 'events-processing') ----- handleEvent: anEvent | evt ofs | owner ifNil:[^self]. evt := anEvent. EventStats ifNil:[EventStats := IdentityDictionary new]. EventStats at: #count put: (EventStats at: #count ifAbsent:[0]) + 1. EventStats at: evt type put: (EventStats at: evt type ifAbsent:[0]) + 1. evt isMouseOver ifTrue:[^self sendMouseEvent: evt]. ShowEvents == true ifTrue:[ + Display fill: (0@0 extent: 300@120) rule: Form over fillColor: Color white. - Display fill: (0@0 extent: 250@120) rule: Form over fillColor: Color white. ofs := (owner hands indexOf: self) - 1 * 60. + evt isKeyboard + ifTrue: [ 'key: ', evt printString displayAt: (0@ofs) + (0@30) ] + ifFalse: [ 'evt: ', evt printString displayAt: (0@ofs) + (0@0) ]. + 'kf: ', self keyboardFocus printString displayAt: (0@ofs)+(0@45). - evt printString displayAt: (0@ofs) + (evt isKeyboard ifTrue:[0@30] ifFalse:[0@0]). - self keyboardFocus printString displayAt: (0@ofs)+(0@45). ]. "Notify listeners" self sendListenEvent: evt to: self eventListeners. evt isWindowEvent ifTrue: [ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isKeyboard ifTrue:[ self sendListenEvent: evt to: self keyboardListeners. self sendKeyboardEvent: evt. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isDropEvent ifTrue:[ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isMouse ifTrue:[ self sendListenEvent: evt to: self mouseListeners. lastMouseEvent := evt]. "Check for pending drag or double click operations." mouseClickState ifNotNil:[ (mouseClickState handleEvent: evt from: self) ifFalse:[ "Possibly dispatched #click: or something and will not re-establish otherwise" ^self mouseOverHandler processMouseOver: lastMouseEvent]]. evt isMove ifTrue:[ self position: evt position. self sendMouseEvent: evt. ] ifFalse:[ "Issue a synthetic move event if we're not at the position of the event" (evt position = self position) ifFalse:[self moveToEvent: evt]. "Drop submorphs on button events" (self hasSubmorphs) ifTrue:[self dropMorphs: evt] ifFalse:[self sendMouseEvent: evt]. ]. + ShowEvents == true ifTrue:['mf: ', self mouseFocus printString displayAt: (0@ofs) + (0@15)]. - ShowEvents == true ifTrue:[self mouseFocus printString displayAt: (0@ofs) + (0@15)]. self mouseOverHandler processMouseOver: lastMouseEvent. "self handleDragOutside: anEvent." ! Item was added: + ----- Method: HandMorph>>windowUnderneath (in category 'accessing') ----- + windowUnderneath + ActiveWorld submorphsDo: + [ : each | (each isSystemWindow and: [ each containsPoint: self position ]) ifTrue: [ ^ each ] ]. + ^ nil! Item was changed: ----- Method: Morph>>handleMouseDown: (in category 'events-processing') ----- handleMouseDown: anEvent "System level event handling." anEvent wasHandled ifTrue:[^self]. "not interested" anEvent hand removePendingBalloonFor: self. anEvent hand removePendingHaloFor: self. anEvent wasHandled: true. (anEvent controlKeyPressed and: [anEvent blueButtonChanged not and: [Preferences cmdGesturesEnabled]]) ifTrue: [^ self invokeMetaMenu: anEvent]. "Make me modal during mouse transitions" anEvent hand newMouseFocus: self event: anEvent. anEvent blueButtonChanged ifTrue:[^self blueButtonDown: anEvent]. "this mouse down could be the start of a gesture, or the end of a gesture focus" (self isGestureStart: anEvent) ifTrue: [^ self gestureStart: anEvent]. + "Filter events sent to the subwidgets of non-MorphicModels in inactive windows, if they are not supposed to receive them due to windowActiveOnFirstClick being set to false. I don't like having this check for owningWindow here, is there another way?" + SystemWindow allWindowsAcceptInput + ifTrue: + [ self owningWindow + ifNil: [ self mouseDown: anEvent ] + ifNotNil: + [ : owningWindow | + (owningWindow canProcessMouseDown: anEvent) + ifTrue: [ self mouseDown: anEvent ] + ifFalse: [ owningWindow activate ] ] ] + ifFalse: [ self mouseDown: anEvent ]. - self mouseDown: anEvent. Preferences maintainHalos ifFalse:[ anEvent hand removeHaloFromClick: anEvent on: self ]. (self handlesMouseStillDown: anEvent) ifTrue:[ self startStepping: #handleMouseStillDown: at: Time millisecondClockValue + self mouseStillDownThreshold arguments: {anEvent copy resetHandlerFields} stepTime: self mouseStillDownStepRate ]. ! Item was changed: ----- Method: Morph>>keyboardFocusChange: (in category 'event handling') ----- + keyboardFocusChange: aBoolean - keyboardFocusChange: aBoolean "The message is sent to a morph when its keyboard focus change. The given argument indicates that the receiver is gaining keyboard focus (versus losing) the keyboard focus. Morphs that accept keystrokes should change their appearance in some way when they are the current keyboard focus." + self eventHandler ifNotNil: + [ : h | h + keyboardFocusChange: aBoolean + fromMorph: self ]. + "Support for 'Focus Follows Mouse'. Want the window to maintain focus even after the pointer moves into its title bar." + self owningWindow ifNotNil: [ : window | window lookFocused: (aBoolean or: [ window containsPoint: ActiveHand position]) ]. + self indicateKeyboardFocus ifTrue: [ self changed ]! - - self eventHandler - ifNotNil: [:h | h keyboardFocusChange: aBoolean fromMorph: self]. - - self indicateKeyboardFocus - ifTrue: [self changed].! Item was added: + ----- Method: Morph>>owningWindow (in category 'private') ----- + owningWindow + self withAllOwnersDo: [ : each | each isSystemWindow ifTrue: [ ^ each ] ]. + ^ nil! Item was added: + ----- Method: MorphicModel>>handleMouseDown: (in category 'events-processing') ----- + handleMouseDown: aMouseEvent + SystemWindow allWindowsAcceptInput ifTrue: + [ "This override is needed so that, when 'Window Active On First Click' is false, clicking on a PluggableListMorph of an inactive window will, correctly, NOT update the selection in the list; it will only activate the window." + aMouseEvent blueButtonChanged ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window canProcessMouseDown: aMouseEvent) ifFalse: [ ^ window activate ]. + Model windowActiveOnFirstClick ifTrue: [ window activate ] ] ] ]. + super handleMouseDown: aMouseEvent! Item was changed: ----- Method: PluggableListMorph>>mouseEnter: (in category 'events') ----- + mouseEnter: event - mouseEnter: event - super mouseEnter: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand newKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand newKeyboardFocus: self. ]! Item was changed: ----- Method: PluggableListMorph>>mouseLeave: (in category 'events') ----- + mouseLeave: event + "The mouse has left the bounds of the receiver" - mouseLeave: event - "The mouse has left the area of the receiver" - super mouseLeave: event. - self hoverRow: nil. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand releaseKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand releaseKeyboardFocus: self].! Item was changed: ----- Method: PluggableTextMorph>>mouseEnter: (in category 'event handling') ----- mouseEnter: event super mouseEnter: event. selectionInterval ifNotNil: [textMorph editor selectInterval: selectionInterval; setEmphasisHere]. textMorph selectionChanged. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[ - Preferences mouseOverForKeyboardFocus ifTrue:[ event hand newKeyboardFocus: self]! Item was changed: ----- Method: PluggableTextMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + "The mouse has left the bounds of the receiver" - "The mouse has left the area of the receiver" - textMorph ifNotNil: [selectionInterval := textMorph editor selectionInterval]. super mouseLeave: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: - Preferences mouseOverForKeyboardFocus ifTrue: [event hand releaseKeyboardFocus: self]! Item was changed: ----- Method: ProportionalSplitterMorph>>proposedCorrectionWouldCauseFocusChange: (in category 'layout') ----- proposedCorrectionWouldCauseFocusChange: correction + ^ (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) and: - ^ Preferences mouseOverForKeyboardFocus and: [ | edge | splitsTopAndBottom ifTrue: [ edge := correction positive ifTrue: [ self bottom + 3 ] ifFalse: [ self top - 3 ]. ActiveHand position y inRangeOf: edge and: edge + correction ] ifFalse: [ edge := correction positive ifTrue: [ self right ] ifFalse: [ self left ]. ActiveHand position x inRangeOf: edge and: edge + correction ] ]! Item was changed: ----- Method: ScrollPane>>mouseEnter: (in category 'event handling') ----- mouseEnter: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := true]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := true]. (owner isSystemWindow) ifTrue: [owner paneTransition: event]. retractableScrollBar ifTrue:[ self hideOrShowScrollBars ]. ! Item was changed: ----- Method: ScrollPane>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := false]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := false]. retractableScrollBar ifTrue: [self hideScrollBars]. (owner isSystemWindow) ifTrue: [owner paneTransition: event] ! Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: aMouseEvent super mouseLeave: aMouseEvent. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! - Preferences mouseOverForKeyboardFocus ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! Item was changed: MorphicModel subclass: #SystemWindow instanceVariableNames: 'labelString stripes label closeBox collapseBox activeOnlyOnTop paneMorphs paneRects collapsedFrame fullFrame isCollapsed menuBox mustNotClose labelWidgetAllowance updatablePanes allowReframeHandles labelArea expandBox' + classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient FocusFollowsMouse GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow WindowsRaiseOnClick' - classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow' poolDictionaries: '' category: 'Morphic-Windows'! !SystemWindow commentStamp: '<historical>' prior: 0! SystemWindow is the Morphic equivalent of StandardSystemView -- a labelled container for rectangular views, with iconic facilities for close, collapse/expand, and resizing. The attribute onlyActiveOnTop, if set to true (and any call to activate will set this), determines that only the top member of a collection of such windows on the screen shall be active. To be not active means that a mouse click in any region will only result in bringing the window to the top and then making it active.! Item was added: + ----- Method: SystemWindow class>>allWindowsAcceptInput (in category 'private') ----- + allWindowsAcceptInput + "With either of these two preferences settings, inactive windows will not have their widgets locked. All windows accept input as if they were active." + ^ self focusFollowsMouse or: [ self windowsRaiseOnClick not ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse (in category 'preferences') ----- + focusFollowsMouse + <preference: 'Focus Follows Mouse' + category: 'windows' + description: 'When true, the widget under the hand has keyboard focus.' + type: #Boolean> + ^ FocusFollowsMouse ifNil: [ false ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse: (in category 'preferences') ----- + focusFollowsMouse: aBoolean + (FocusFollowsMouse := aBoolean) == true. + self reconfigureWindowsForFocus! Item was added: + ----- Method: SystemWindow class>>reconfigureWindowsForFocus (in category 'private') ----- + reconfigureWindowsForFocus + self withAllSubclasses do: + [ : eachSubclass | eachSubclass allInstances do: + [ : eachInstance | eachInstance configureFocus ] ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick (in category 'preferences') ----- + windowsRaiseOnClick + <preference: 'Windows Raise On Click' + category: 'windows' + description: 'If true, a click anywhere within a window will raise it above all other windows to become the active window. If false, it won''t.' + type: #Boolean> + ^ WindowsRaiseOnClick ifNil: [ true ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick: (in category 'preferences') ----- + windowsRaiseOnClick: aBoolean + (WindowsRaiseOnClick := aBoolean == true). + self reconfigureWindowsForFocus! Item was changed: ----- Method: SystemWindow>>activate (in category 'top window') ----- activate "Activate the owner too." |mo mc| mo := self modalOwner. mc := self modalChild. mc isNil ifFalse: [mc owner notNil ifTrue: [ mc activate. ^mc modalChild isNil ifTrue: [mc flash]]]. (isCollapsed not and: [ self paneMorphs size > 1 and: [ self splitters isEmpty ] ]) ifTrue: [ self addPaneSplitters ]. self activateWindow. self rememberedKeyboardFocus ifNil: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]] ifNotNil: [:m | m world ifNil: [self rememberKeyboardFocus: nil] "deleted" ifNotNil: [:w | m wantsKeyboardFocus ifTrue: [m takeKeyboardFocus] ifFalse: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]]]]. + (mo notNil and: [mo isSystemWindow]) - (mo notNil and: [mo isKindOf: SystemWindow]) ifTrue: [mo bringBehind: self]! Item was changed: ----- Method: SystemWindow>>activateWindow (in category 'top window') ----- activateWindow "Bring me to the front and make me able to respond to mouse and keyboard. Was #activate (sw 5/18/2001 23:20)" + | oldTop outerMorph sketchEditor pal windowUnderneath | - - | oldTop outerMorph sketchEditor pal | - self hasDropShadow: Preferences menuAppearance3d. - outerMorph := self topRendererOrSelf. outerMorph owner ifNil: [^ self "avoid spurious activate when drop in trash"]. + self hasDropShadow: Preferences menuAppearance3d. oldTop := TopWindow. oldTop = self ifTrue: [^self]. TopWindow := self. oldTop ifNotNil: [oldTop passivate]. outerMorph owner firstSubmorph == outerMorph ifFalse: ["Bring me (with any flex) to the top if not already" outerMorph owner addMorphFront: outerMorph]. + self configureFocus. - self submorphsDo: [:m | m unlock]. - - label ifNotNil: [label color: Color black]. - - self undimWindowButtons. - labelArea ifNotNil: [labelArea submorphsDo: [:m | m unlock; show]]. - self - setStripeColorsFrom: self paneColorToUse; - adoptPaneColor: self paneColorToUse. - self isCollapsed ifFalse: [model modelWakeUpIn: self. self positionSubmorphs. labelArea ifNil: [self adjustBorderUponActivationWhenLabeless]]. - (sketchEditor := self extantSketchEditor) ifNotNil: [sketchEditor comeToFront. (pal := self world findA: PaintBoxMorph) ifNotNil: [pal comeToFront]]. + self updatePaneColors. + "Newly spawned windows are normally active, but if focusFollowsMouse is set, then the focused window can only be the one under the hand." + (self class allWindowsAcceptInput not or: [ (windowUnderneath := ActiveHand windowUnderneath) isNil or: [ windowUnderneath == self ] ]) + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! - - self updatePaneColors.! Item was added: + ----- Method: SystemWindow>>canProcessMouseDown: (in category 'top window') ----- + canProcessMouseDown: anEvent + "In case 'Focus Follows Mouse' is set, then there are two possibilities for mouse input on a background window: if 'Window Active On First Click' is set, it must be honored and the window must be activated. If it is not set, then the behavior depends on 'Windows Raise On Click' setting. If its true, then just activate the window and DON'T process aMouseEvent. If false, then process the event in any case." + ^ self isActive or: [ Model windowActiveOnFirstClick or: [ SystemWindow windowsRaiseOnClick not ] ]! Item was added: + ----- Method: SystemWindow>>configureFocus (in category 'top window') ----- + configureFocus + "Make me unable to respond to mouse and keyboard unless allWindowsAcceptInput is set or 'Window Active On First Click' is unset. Otherwise, the classic Squeak behavior of Control boxes remaining active, except in novice mode." + self submorphsDo: + [ : each | each lock: + (self isActive not and: + [ each == labelArea + ifTrue: [ self class windowsRaiseOnClick not ] + ifFalse: [ self class allWindowsAcceptInput not ] ]) ]. + labelArea + ifNil: [ "i.e. label area is nil, so we're titleless" + self adjustBorderUponDeactivationWhenLabeless ] + ifNotNil: + [ labelArea submorphsDo: + [ : each | | classicSqueakBehavior | + classicSqueakBehavior := self class allWindowsAcceptInput not. + each lock: + (classicSqueakBehavior + ifTrue: + [ self isActive not and: + [ Preferences noviceMode or: + [ each ~~ closeBox and: [ each ~~ collapseBox ] ] ] ] + ifFalse: + [ self isActive not and: [ Model windowActiveOnFirstClick not ] ]) ] ]! Item was changed: ----- Method: SystemWindow>>handleListenEvent: (in category 'events') ----- handleListenEvent: evt "Make sure we lock our contents after DnD has finished" evt isMouse ifFalse:[^self]. evt hand hasSubmorphs ifTrue:[^self]. "still dragging" + (self isActive and: [ self class allWindowsAcceptInput not ]) ifFalse: [self configureFocus]. - self == TopWindow ifFalse:[self lockInactivePortions]. evt hand removeMouseListener: self.! Item was added: + ----- Method: SystemWindow>>handlesMouseOver: (in category 'events') ----- + handlesMouseOver: anEvent + ^ true! Item was removed: - ----- Method: SystemWindow>>lockInactivePortions (in category 'top window') ----- - lockInactivePortions - "Make me unable to respond to mouse and keyboard. Control boxes remain active, except in novice mode" - - self submorphsDo: [:m | m == labelArea ifFalse: [m lock]]. - self dimWindowButtons. - labelArea ifNotNil: - [labelArea submorphsDo: - [:m | - (Preferences noviceMode or: [m ~~ closeBox and: [m ~~ collapseBox]]) - ifTrue: [m lock]]] - ifNil: "i.e. label area is nil, so we're titleless" - [self adjustBorderUponDeactivationWhenLabeless].! Item was added: + ----- Method: SystemWindow>>lookFocused (in category 'top window') ----- + lookFocused + label ifNotNil: [ label color: Color black ]. + (self isActive or: [Model windowActiveOnFirstClick]) ifTrue: [ self undimWindowButtons ]. + self + updatePaneColors ; + adoptPaneColor: self paneColorToUse! Item was added: + ----- Method: SystemWindow>>lookFocused: (in category 'top window') ----- + lookFocused: aBoolean + aBoolean + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! Item was added: + ----- Method: SystemWindow>>lookUnfocused (in category 'top window') ----- + lookUnfocused + label ifNotNil: [ label color: Color darkGray ]. + self dimWindowButtons. + self paneColorToUseWhenNotActive in: + [ : col | self + setStripeColorsFrom: col ; + adoptPaneColor: col ]! Item was added: + ----- Method: SystemWindow>>mouseEnter: (in category 'events') ----- + mouseEnter: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseEnter: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookFocused ]! Item was added: + ----- Method: SystemWindow>>mouseLeave: (in category 'events') ----- + mouseLeave: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseLeave: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookUnfocused ]! Item was changed: ----- Method: SystemWindow>>mouseLeaveDragging: (in category 'events') ----- mouseLeaveDragging: evt "lock children after drop operations" + (self isActive and:[evt hand hasSubmorphs and: [self class allWindowsAcceptInput not]]) ifTrue:[ + self configureFocus. - (self ~~ TopWindow and:[evt hand hasSubmorphs]) ifTrue:[ - self lockInactivePortions. evt hand removeMouseListener: self. ].! Item was changed: ----- Method: SystemWindow>>passivate (in category 'top window') ----- passivate + "Lose my drop shadlow and reconfigure my focus according to preferences." + self + hasDropShadow: false ; + configureFocus ; + lookUnfocused. + model modelSleep! - "Make me unable to respond to mouse and keyboard" - - label ifNotNil: [label color: Color darkGray]. - - self hasDropShadow: false. - self paneColorToUseWhenNotActive in: [:c | - self - setStripeColorsFrom: c; - adoptPaneColor: c]. - - model modelSleep. - - self lockInactivePortions - ! Item was changed: ----- Method: SystemWindowButton>>mouseEnter: (in category 'visual properties') ----- + mouseEnter: evt + | classicSqueakBehavior | + classicSqueakBehavior := SystemWindow allWindowsAcceptInput not. + classicSqueakBehavior + ifTrue: [ self highlight ] + ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window isActive or: [ Model windowActiveOnFirstClick ]) ifTrue: [ self highlight ] ] ]! - mouseEnter: evt - - self highlight. - ! Item was changed: ----- Method: TextMorphForEditView>>mouseUp: (in category 'event handling') ----- mouseUp: evt super mouseUp: evt. self stopSteppingSelector: #autoScrollView:. + SystemWindow allWindowsAcceptInput ifFalse: [editView scrollSelectionIntoView: evt]. - editView scrollSelectionIntoView: evt. - self setCompositionWindow. !
1
0
0
0
The Trunk: Morphic-cmm.1009.mcz
by commits@source.squeak.org
05 Oct '15
05 Oct '15
Chris Muller uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-cmm.1009.mcz
==================== Summary ==================== Name: Morphic-cmm.1009 Author: cmm Time: 5 October 2015, 1:56:52.458 pm UUID: f0ce65ed-cf24-44b5-9ae5-17c5cb319b9c Ancestors: Morphic-cmm.1008, Morphic-mt.1007 Merged. =============== Diff against Morphic-mt.1007 =============== Item was changed: ----- Method: CornerGripMorph>>mouseMove: (in category 'as yet unclassified') ----- mouseMove: anEvent | delta | target ifNil: [^ self]. target fastFramingOn ifTrue: [delta := target doFastWindowReframe: self ptName] ifFalse: [ + delta := lastMouse ifNil: [0@0] ifNotNil: [anEvent cursorPoint - lastMouse]. - delta := anEvent cursorPoint - lastMouse. lastMouse := anEvent cursorPoint. self apply: delta. self bounds: (self bounds origin + delta extent: self bounds extent)].! Item was changed: ----- Method: HandMorph>>handleEvent: (in category 'events-processing') ----- handleEvent: anEvent | evt ofs | owner ifNil:[^self]. evt := anEvent. EventStats ifNil:[EventStats := IdentityDictionary new]. EventStats at: #count put: (EventStats at: #count ifAbsent:[0]) + 1. EventStats at: evt type put: (EventStats at: evt type ifAbsent:[0]) + 1. evt isMouseOver ifTrue:[^self sendMouseEvent: evt]. ShowEvents == true ifTrue:[ + Display fill: (0@0 extent: 300@120) rule: Form over fillColor: Color white. - Display fill: (0@0 extent: 250@120) rule: Form over fillColor: Color white. ofs := (owner hands indexOf: self) - 1 * 60. + evt isKeyboard + ifTrue: [ 'key: ', evt printString displayAt: (0@ofs) + (0@30) ] + ifFalse: [ 'evt: ', evt printString displayAt: (0@ofs) + (0@0) ]. + 'kf: ', self keyboardFocus printString displayAt: (0@ofs)+(0@45). - evt printString displayAt: (0@ofs) + (evt isKeyboard ifTrue:[0@30] ifFalse:[0@0]). - self keyboardFocus printString displayAt: (0@ofs)+(0@45). ]. "Notify listeners" self sendListenEvent: evt to: self eventListeners. evt isWindowEvent ifTrue: [ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isKeyboard ifTrue:[ self sendListenEvent: evt to: self keyboardListeners. self sendKeyboardEvent: evt. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isDropEvent ifTrue:[ self sendEvent: evt focus: nil. ^self mouseOverHandler processMouseOver: lastMouseEvent]. evt isMouse ifTrue:[ self sendListenEvent: evt to: self mouseListeners. lastMouseEvent := evt]. "Check for pending drag or double click operations." mouseClickState ifNotNil:[ (mouseClickState handleEvent: evt from: self) ifFalse:[ "Possibly dispatched #click: or something and will not re-establish otherwise" ^self mouseOverHandler processMouseOver: lastMouseEvent]]. evt isMove ifTrue:[ self position: evt position. self sendMouseEvent: evt. ] ifFalse:[ "Issue a synthetic move event if we're not at the position of the event" (evt position = self position) ifFalse:[self moveToEvent: evt]. "Drop submorphs on button events" (self hasSubmorphs) ifTrue:[self dropMorphs: evt] ifFalse:[self sendMouseEvent: evt]. ]. + ShowEvents == true ifTrue:['mf: ', self mouseFocus printString displayAt: (0@ofs) + (0@15)]. - ShowEvents == true ifTrue:[self mouseFocus printString displayAt: (0@ofs) + (0@15)]. self mouseOverHandler processMouseOver: lastMouseEvent. "self handleDragOutside: anEvent." ! Item was added: + ----- Method: HandMorph>>windowUnderneath (in category 'accessing') ----- + windowUnderneath + ActiveWorld submorphsDo: + [ : each | (each isSystemWindow and: [ each containsPoint: self position ]) ifTrue: [ ^ each ] ]. + ^ nil! Item was changed: ----- Method: Morph>>handleMouseDown: (in category 'events-processing') ----- handleMouseDown: anEvent "System level event handling." anEvent wasHandled ifTrue:[^self]. "not interested" anEvent hand removePendingBalloonFor: self. anEvent hand removePendingHaloFor: self. anEvent wasHandled: true. (anEvent controlKeyPressed and: [anEvent blueButtonChanged not and: [Preferences cmdGesturesEnabled]]) ifTrue: [^ self invokeMetaMenu: anEvent]. "Make me modal during mouse transitions" anEvent hand newMouseFocus: self event: anEvent. anEvent blueButtonChanged ifTrue:[^self blueButtonDown: anEvent]. "this mouse down could be the start of a gesture, or the end of a gesture focus" (self isGestureStart: anEvent) ifTrue: [^ self gestureStart: anEvent]. + "Filter events sent to the subwidgets of non-MorphicModels in inactive windows, if they are not supposed to receive them due to windowActiveOnFirstClick being set to false. I don't like having this check for owningWindow here, is there another way?" + SystemWindow allWindowsAcceptInput + ifTrue: + [ self owningWindow + ifNil: [ self mouseDown: anEvent ] + ifNotNil: + [ : owningWindow | + (owningWindow canProcessMouseDown: anEvent) + ifTrue: [ self mouseDown: anEvent ] + ifFalse: [ owningWindow activate ] ] ] + ifFalse: [ self mouseDown: anEvent ]. - self mouseDown: anEvent. Preferences maintainHalos ifFalse:[ anEvent hand removeHaloFromClick: anEvent on: self ]. (self handlesMouseStillDown: anEvent) ifTrue:[ self startStepping: #handleMouseStillDown: at: Time millisecondClockValue + self mouseStillDownThreshold arguments: {anEvent copy resetHandlerFields} stepTime: self mouseStillDownStepRate ]. ! Item was changed: ----- Method: Morph>>keyboardFocusChange: (in category 'event handling') ----- + keyboardFocusChange: aBoolean - keyboardFocusChange: aBoolean "The message is sent to a morph when its keyboard focus change. The given argument indicates that the receiver is gaining keyboard focus (versus losing) the keyboard focus. Morphs that accept keystrokes should change their appearance in some way when they are the current keyboard focus." + self eventHandler ifNotNil: + [ : h | h + keyboardFocusChange: aBoolean + fromMorph: self ]. + "Support for 'Focus Follows Mouse'. Want the window to maintain focus even after the pointer moves into its title bar." + self owningWindow ifNotNil: [ : window | window lookFocused: (aBoolean or: [ window containsPoint: ActiveHand position]) ]. + self indicateKeyboardFocus ifTrue: [ self changed ]! - - self eventHandler - ifNotNil: [:h | h keyboardFocusChange: aBoolean fromMorph: self]. - - self indicateKeyboardFocus - ifTrue: [self changed].! Item was added: + ----- Method: Morph>>owningWindow (in category 'private') ----- + owningWindow + self withAllOwnersDo: [ : each | each isSystemWindow ifTrue: [ ^ each ] ]. + ^ nil! Item was added: + ----- Method: MorphicModel>>handleMouseDown: (in category 'events-processing') ----- + handleMouseDown: aMouseEvent + SystemWindow allWindowsAcceptInput ifTrue: + [ "This override is needed so that, when 'Window Active On First Click' is false, clicking on a PluggableListMorph of an inactive window will, correctly, NOT update the selection in the list; it will only activate the window." + aMouseEvent blueButtonChanged ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window canProcessMouseDown: aMouseEvent) ifFalse: [ ^ window activate ]. + Model windowActiveOnFirstClick ifTrue: [ window activate ] ] ] ]. + super handleMouseDown: aMouseEvent! Item was changed: ----- Method: PluggableListMorph>>mouseEnter: (in category 'events') ----- + mouseEnter: event - mouseEnter: event - super mouseEnter: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand newKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand newKeyboardFocus: self. ]! Item was changed: ----- Method: PluggableListMorph>>mouseLeave: (in category 'events') ----- + mouseLeave: event + "The mouse has left the bounds of the receiver" - mouseLeave: event - "The mouse has left the area of the receiver" - super mouseLeave: event. - self hoverRow: nil. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ event hand releaseKeyboardFocus: self ]! - - Preferences mouseOverForKeyboardFocus ifTrue:[ - event hand releaseKeyboardFocus: self].! Item was changed: ----- Method: PluggableTextMorph>>mouseEnter: (in category 'event handling') ----- mouseEnter: event super mouseEnter: event. selectionInterval ifNotNil: [textMorph editor selectInterval: selectionInterval; setEmphasisHere]. textMorph selectionChanged. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[ - Preferences mouseOverForKeyboardFocus ifTrue:[ event hand newKeyboardFocus: self]! Item was changed: ----- Method: PluggableTextMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + "The mouse has left the bounds of the receiver" - "The mouse has left the area of the receiver" - textMorph ifNotNil: [selectionInterval := textMorph editor selectionInterval]. super mouseLeave: event. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: - Preferences mouseOverForKeyboardFocus ifTrue: [event hand releaseKeyboardFocus: self]! Item was changed: ----- Method: ProportionalSplitterMorph>>proposedCorrectionWouldCauseFocusChange: (in category 'layout') ----- proposedCorrectionWouldCauseFocusChange: correction + ^ (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) and: - ^ Preferences mouseOverForKeyboardFocus and: [ | edge | splitsTopAndBottom ifTrue: [ edge := correction positive ifTrue: [ self bottom + 3 ] ifFalse: [ self top - 3 ]. ActiveHand position y inRangeOf: edge and: edge + correction ] ifFalse: [ edge := correction positive ifTrue: [ self right ] ifFalse: [ self left ]. ActiveHand position x inRangeOf: edge and: edge + correction ] ]! Item was changed: ----- Method: ScrollPane>>mouseEnter: (in category 'event handling') ----- mouseEnter: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := true]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := true]. (owner isSystemWindow) ifTrue: [owner paneTransition: event]. retractableScrollBar ifTrue:[ self hideOrShowScrollBars ]. ! Item was changed: ----- Method: ScrollPane>>mouseLeave: (in category 'event handling') ----- mouseLeave: event + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue:[hasFocus := false]. - Preferences mouseOverForKeyboardFocus ifTrue:[hasFocus := false]. retractableScrollBar ifTrue: [self hideScrollBars]. (owner isSystemWindow) ifTrue: [owner paneTransition: event] ! Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseLeave: (in category 'event handling') ----- mouseLeave: aMouseEvent super mouseLeave: aMouseEvent. + (SystemWindow allWindowsAcceptInput or: [ Preferences mouseOverForKeyboardFocus ]) ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! - Preferences mouseOverForKeyboardFocus ifTrue: [ aMouseEvent hand releaseKeyboardFocus: self ]! Item was changed: MorphicModel subclass: #SystemWindow instanceVariableNames: 'labelString stripes label closeBox collapseBox activeOnlyOnTop paneMorphs paneRects collapsedFrame fullFrame isCollapsed menuBox mustNotClose labelWidgetAllowance updatablePanes allowReframeHandles labelArea expandBox' + classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient FocusFollowsMouse GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow WindowsRaiseOnClick' - classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow' poolDictionaries: '' category: 'Morphic-Windows'! !SystemWindow commentStamp: '<historical>' prior: 0! SystemWindow is the Morphic equivalent of StandardSystemView -- a labelled container for rectangular views, with iconic facilities for close, collapse/expand, and resizing. The attribute onlyActiveOnTop, if set to true (and any call to activate will set this), determines that only the top member of a collection of such windows on the screen shall be active. To be not active means that a mouse click in any region will only result in bringing the window to the top and then making it active.! Item was added: + ----- Method: SystemWindow class>>allWindowsAcceptInput (in category 'private') ----- + allWindowsAcceptInput + "With either of these two preferences settings, inactive windows will not have their widgets locked. All windows accept input as if they were active." + ^ self focusFollowsMouse or: [ self windowsRaiseOnClick not ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse (in category 'preferences') ----- + focusFollowsMouse + <preference: 'Focus Follows Mouse' + category: 'windows' + description: 'When true, the widget under the hand has keyboard focus.' + type: #Boolean> + ^ FocusFollowsMouse ifNil: [ false ]! Item was added: + ----- Method: SystemWindow class>>focusFollowsMouse: (in category 'preferences') ----- + focusFollowsMouse: aBoolean + (FocusFollowsMouse := aBoolean) == true. + self reconfigureWindowsForFocus! Item was added: + ----- Method: SystemWindow class>>reconfigureWindowsForFocus (in category 'private') ----- + reconfigureWindowsForFocus + self withAllSubclasses do: + [ : eachSubclass | eachSubclass allInstances do: + [ : eachInstance | eachInstance configureFocus ] ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick (in category 'preferences') ----- + windowsRaiseOnClick + <preference: 'Windows Raise On Click' + category: 'windows' + description: 'If true, a click anywhere within a window will raise it above all other windows to become the active window. If false, it won''t.' + type: #Boolean> + ^ WindowsRaiseOnClick ifNil: [ true ]! Item was added: + ----- Method: SystemWindow class>>windowsRaiseOnClick: (in category 'preferences') ----- + windowsRaiseOnClick: aBoolean + (WindowsRaiseOnClick := aBoolean == true). + self reconfigureWindowsForFocus! Item was changed: ----- Method: SystemWindow>>activate (in category 'top window') ----- activate "Activate the owner too." |mo mc| mo := self modalOwner. mc := self modalChild. mc isNil ifFalse: [mc owner notNil ifTrue: [ mc activate. ^mc modalChild isNil ifTrue: [mc flash]]]. (isCollapsed not and: [ self paneMorphs size > 1 and: [ self splitters isEmpty ] ]) ifTrue: [ self addPaneSplitters ]. self activateWindow. self rememberedKeyboardFocus ifNil: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]] ifNotNil: [:m | m world ifNil: [self rememberKeyboardFocus: nil] "deleted" ifNotNil: [:w | m wantsKeyboardFocus ifTrue: [m takeKeyboardFocus] ifFalse: [(self respondsTo: #navigateFocusForward) ifTrue: [self navigateFocusForward]]]]. + (mo notNil and: [mo isSystemWindow]) - (mo notNil and: [mo isKindOf: SystemWindow]) ifTrue: [mo bringBehind: self]! Item was changed: ----- Method: SystemWindow>>activateWindow (in category 'top window') ----- activateWindow "Bring me to the front and make me able to respond to mouse and keyboard. Was #activate (sw 5/18/2001 23:20)" + | oldTop outerMorph sketchEditor pal windowUnderneath | - - | oldTop outerMorph sketchEditor pal | - self hasDropShadow: Preferences menuAppearance3d. - outerMorph := self topRendererOrSelf. outerMorph owner ifNil: [^ self "avoid spurious activate when drop in trash"]. + self hasDropShadow: Preferences menuAppearance3d. oldTop := TopWindow. oldTop = self ifTrue: [^self]. TopWindow := self. oldTop ifNotNil: [oldTop passivate]. outerMorph owner firstSubmorph == outerMorph ifFalse: ["Bring me (with any flex) to the top if not already" outerMorph owner addMorphFront: outerMorph]. + self configureFocus. - self submorphsDo: [:m | m unlock]. - - label ifNotNil: [label color: Color black]. - - self undimWindowButtons. - labelArea ifNotNil: [labelArea submorphsDo: [:m | m unlock; show]]. - self - setStripeColorsFrom: self paneColorToUse; - adoptPaneColor: self paneColorToUse. - self isCollapsed ifFalse: [model modelWakeUpIn: self. self positionSubmorphs. labelArea ifNil: [self adjustBorderUponActivationWhenLabeless]]. - (sketchEditor := self extantSketchEditor) ifNotNil: [sketchEditor comeToFront. (pal := self world findA: PaintBoxMorph) ifNotNil: [pal comeToFront]]. + self updatePaneColors. + "Newly spawned windows are normally active, but if focusFollowsMouse is set, then the focused window can only be the one under the hand." + (self class allWindowsAcceptInput not or: [ (windowUnderneath := ActiveHand windowUnderneath) isNil or: [ windowUnderneath == self ] ]) + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! - - self updatePaneColors.! Item was added: + ----- Method: SystemWindow>>canProcessMouseDown: (in category 'top window') ----- + canProcessMouseDown: anEvent + "In case 'Focus Follows Mouse' is set, then there are two possibilities for mouse input on a background window: if 'Window Active On First Click' is set, it must be honored and the window must be activated. If it is not set, then the behavior depends on 'Windows Raise On Click' setting. If its true, then just activate the window and DON'T process aMouseEvent. If false, then process the event in any case." + ^ self isActive or: [ Model windowActiveOnFirstClick or: [ SystemWindow windowsRaiseOnClick not ] ]! Item was added: + ----- Method: SystemWindow>>configureFocus (in category 'top window') ----- + configureFocus + "Make me unable to respond to mouse and keyboard unless allWindowsAcceptInput is set or 'Window Active On First Click' is unset. Otherwise, the classic Squeak behavior of Control boxes remaining active, except in novice mode." + self submorphsDo: + [ : each | each lock: + (self isActive not and: + [ each == labelArea + ifTrue: [ self class windowsRaiseOnClick not ] + ifFalse: [ self class allWindowsAcceptInput not ] ]) ]. + labelArea + ifNil: [ "i.e. label area is nil, so we're titleless" + self adjustBorderUponDeactivationWhenLabeless ] + ifNotNil: + [ labelArea submorphsDo: + [ : each | | classicSqueakBehavior | + classicSqueakBehavior := self class allWindowsAcceptInput not. + each lock: + (classicSqueakBehavior + ifTrue: + [ self isActive not and: + [ Preferences noviceMode or: + [ each ~~ closeBox and: [ each ~~ collapseBox ] ] ] ] + ifFalse: + [ self isActive not and: [ Model windowActiveOnFirstClick not ] ]) ] ]! Item was changed: ----- Method: SystemWindow>>handleListenEvent: (in category 'events') ----- handleListenEvent: evt "Make sure we lock our contents after DnD has finished" evt isMouse ifFalse:[^self]. evt hand hasSubmorphs ifTrue:[^self]. "still dragging" + (self isActive and: [ self class allWindowsAcceptInput not ]) ifFalse: [self configureFocus]. - self == TopWindow ifFalse:[self lockInactivePortions]. evt hand removeMouseListener: self.! Item was added: + ----- Method: SystemWindow>>handlesMouseOver: (in category 'events') ----- + handlesMouseOver: anEvent + ^ true! Item was removed: - ----- Method: SystemWindow>>lockInactivePortions (in category 'top window') ----- - lockInactivePortions - "Make me unable to respond to mouse and keyboard. Control boxes remain active, except in novice mode" - - self submorphsDo: [:m | m == labelArea ifFalse: [m lock]]. - self dimWindowButtons. - labelArea ifNotNil: - [labelArea submorphsDo: - [:m | - (Preferences noviceMode or: [m ~~ closeBox and: [m ~~ collapseBox]]) - ifTrue: [m lock]]] - ifNil: "i.e. label area is nil, so we're titleless" - [self adjustBorderUponDeactivationWhenLabeless].! Item was added: + ----- Method: SystemWindow>>lookFocused (in category 'top window') ----- + lookFocused + label ifNotNil: [ label color: Color black ]. + (self isActive or: [Model windowActiveOnFirstClick]) ifTrue: [ self undimWindowButtons ]. + self + updatePaneColors ; + adoptPaneColor: self paneColorToUse! Item was added: + ----- Method: SystemWindow>>lookFocused: (in category 'top window') ----- + lookFocused: aBoolean + aBoolean + ifTrue: [ self lookFocused ] + ifFalse: [ self lookUnfocused ]! Item was added: + ----- Method: SystemWindow>>lookUnfocused (in category 'top window') ----- + lookUnfocused + label ifNotNil: [ label color: Color darkGray ]. + self dimWindowButtons. + self paneColorToUseWhenNotActive in: + [ : col | self + setStripeColorsFrom: col ; + adoptPaneColor: col ]! Item was added: + ----- Method: SystemWindow>>mouseEnter: (in category 'events') ----- + mouseEnter: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseEnter: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookFocused ]! Item was added: + ----- Method: SystemWindow>>mouseLeave: (in category 'events') ----- + mouseLeave: anEvent + "Handle a mouseEnter event, meaning the mouse just entered my bounds with no button pressed. The default response is to let my eventHandler, if any, handle it." + super mouseLeave: anEvent. + self class allWindowsAcceptInput ifTrue: [ self lookUnfocused ]! Item was changed: ----- Method: SystemWindow>>mouseLeaveDragging: (in category 'events') ----- mouseLeaveDragging: evt "lock children after drop operations" + (self isActive and:[evt hand hasSubmorphs and: [self class allWindowsAcceptInput not]]) ifTrue:[ + self configureFocus. - (self ~~ TopWindow and:[evt hand hasSubmorphs]) ifTrue:[ - self lockInactivePortions. evt hand removeMouseListener: self. ].! Item was changed: ----- Method: SystemWindow>>passivate (in category 'top window') ----- passivate + "Lose my drop shadlow and reconfigure my focus according to preferences." + self + hasDropShadow: false ; + configureFocus ; + lookUnfocused. + model modelSleep! - "Make me unable to respond to mouse and keyboard" - - label ifNotNil: [label color: Color darkGray]. - - self hasDropShadow: false. - self paneColorToUseWhenNotActive in: [:c | - self - setStripeColorsFrom: c; - adoptPaneColor: c]. - - model modelSleep. - - self lockInactivePortions - ! Item was changed: ----- Method: SystemWindowButton>>mouseEnter: (in category 'visual properties') ----- + mouseEnter: evt + | classicSqueakBehavior | + classicSqueakBehavior := SystemWindow allWindowsAcceptInput not. + classicSqueakBehavior + ifTrue: [ self highlight ] + ifFalse: + [ self owningWindow ifNotNil: + [ : window | (window isActive or: [ Model windowActiveOnFirstClick ]) ifTrue: [ self highlight ] ] ]! - mouseEnter: evt - - self highlight. - ! Item was changed: ----- Method: TextMorphForEditView>>mouseUp: (in category 'event handling') ----- mouseUp: evt super mouseUp: evt. self stopSteppingSelector: #autoScrollView:. + SystemWindow allWindowsAcceptInput ifFalse: [editView scrollSelectionIntoView: evt]. - editView scrollSelectionIntoView: evt. - self setCompositionWindow. !
1
0
0
0
The Trunk: Tools-cmm.634.mcz
by commits@source.squeak.org
05 Oct '15
05 Oct '15
Chris Muller uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-cmm.634.mcz
==================== Summary ==================== Name: Tools-cmm.634 Author: cmm Time: 5 October 2015, 1:39:05.231 pm UUID: 1b9e0e4c-f728-48ff-9046-54b7f7c302d0 Ancestors: Tools-cmm.620, Tools-eem.633 - IDE, please stop forcing a message category selection just because I accepted a method. If I want that, I'll simply press the hot-key, Shift+Command+C. =============== Diff against Tools-eem.633 =============== Item was changed: ----- Method: Browser>>compileMessage:notifying: (in category 'code pane') ----- compileMessage: aText notifying: aController "Compile the code that was accepted by the user, placing the compiled method into an appropriate message category. Return true if the compilation succeeded, else false." - | fallBackCategoryName originalSelectorName result fallBackMethodName | + self selectedMessageCategoryName = ClassOrganizer allCategory - - self selectedMessageCategoryName ifNil: - [ self selectOriginalCategoryForCurrentMethod - ifFalse:["Select the '--all--' category" - self messageCategoryListIndex: 1]]. - - - self selectedMessageCategoryName asSymbol = ClassOrganizer allCategory ifTrue: [ "User tried to save a method while the ALL category was selected" fallBackCategoryName := selectedMessageCategoryName. fallBackMethodName := selectedMessageName. editSelection == #newMessage ifTrue: [ "Select the 'as yet unclassified' category" selectedMessageCategoryName := nil. (result := self defineMessageFrom: aText notifying: aController) ifNil: ["Compilation failure: reselect the original category & method" selectedMessageCategoryName := fallBackCategoryName. selectedMessageName := fallBackMethodName] ifNotNil: [self setSelector: result]] ifFalse: [originalSelectorName := self selectedMessageName. self setOriginalCategoryIndexForCurrentMethod. selectedMessageName := fallBackMethodName := originalSelectorName. (result := self defineMessageFrom: aText notifying: aController) ifNotNil: [self setSelector: result] ifNil: [ "Compilation failure: reselect the original category & method" selectedMessageCategoryName := fallBackCategoryName. selectedMessageName := fallBackMethodName. ^ result notNil]]. self changed: #messageCategoryList. ^ result notNil] ifFalse: [ "User tried to save a method while the ALL category was NOT selected" ^ (self defineMessageFrom: aText notifying: aController) notNil]!
1
0
0
0
The Trunk: Tools-cmm.634.mcz
by commits@source.squeak.org
05 Oct '15
05 Oct '15
Chris Muller uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-cmm.634.mcz
==================== Summary ==================== Name: Tools-cmm.634 Author: cmm Time: 5 October 2015, 1:39:05.231 pm UUID: 1b9e0e4c-f728-48ff-9046-54b7f7c302d0 Ancestors: Tools-cmm.620, Tools-eem.633 - IDE, please stop forcing a message category selection just because I accepted a method. If I want that, I'll simply press the hot-key, Shift+Command+C. =============== Diff against Tools-eem.633 =============== Item was changed: ----- Method: Browser>>compileMessage:notifying: (in category 'code pane') ----- compileMessage: aText notifying: aController "Compile the code that was accepted by the user, placing the compiled method into an appropriate message category. Return true if the compilation succeeded, else false." - | fallBackCategoryName originalSelectorName result fallBackMethodName | + self selectedMessageCategoryName = ClassOrganizer allCategory - - self selectedMessageCategoryName ifNil: - [ self selectOriginalCategoryForCurrentMethod - ifFalse:["Select the '--all--' category" - self messageCategoryListIndex: 1]]. - - - self selectedMessageCategoryName asSymbol = ClassOrganizer allCategory ifTrue: [ "User tried to save a method while the ALL category was selected" fallBackCategoryName := selectedMessageCategoryName. fallBackMethodName := selectedMessageName. editSelection == #newMessage ifTrue: [ "Select the 'as yet unclassified' category" selectedMessageCategoryName := nil. (result := self defineMessageFrom: aText notifying: aController) ifNil: ["Compilation failure: reselect the original category & method" selectedMessageCategoryName := fallBackCategoryName. selectedMessageName := fallBackMethodName] ifNotNil: [self setSelector: result]] ifFalse: [originalSelectorName := self selectedMessageName. self setOriginalCategoryIndexForCurrentMethod. selectedMessageName := fallBackMethodName := originalSelectorName. (result := self defineMessageFrom: aText notifying: aController) ifNotNil: [self setSelector: result] ifNil: [ "Compilation failure: reselect the original category & method" selectedMessageCategoryName := fallBackCategoryName. selectedMessageName := fallBackMethodName. ^ result notNil]]. self changed: #messageCategoryList. ^ result notNil] ifFalse: [ "User tried to save a method while the ALL category was NOT selected" ^ (self defineMessageFrom: aText notifying: aController) notNil]!
1
0
0
0
← Newer
1
...
19
20
21
22
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Results per page:
10
25
50
100
200