[squeak-dev] A fix for ProportionalSplitterMorph, take 2
Stéphane Rollandin
lecteur at zogotounga.net
Sat Mar 31 08:47:47 UTC 2018
Repeat:
Attached is a fix for ProportionalSplitterMorph.
Currently, moving a window splitter changes all relevant frame layout
offsets; fractions are not touched. But offsets are absolute values, in
pixels, and a frame with a large offset will be badly redimensionned
when the system window extent is reduced.
To see this, open a browser, and move the main horizontal splitter way
up. Then shrink the browser: the code pane will keep a largeish height
(because of its large vertical offsets), and eventually be moved above
the browser top.
To fix this, I propose in the attached changeset to keep track of the
overall splitter delta, then on #mouseUp to recompute the fractions and
reset the offsets to the typical small values they have.
I don't know if I am being clear, but it works... try it.
(the #balanceOffsets method may possibly be simplified I guess)
Stef
-------------- next part --------------
'From Squeak5.1 of 5 September 2016 [latest update: #16549] on 31 March 2018 at 10:44:47 am'!
!ProportionalSplitterMorph methodsFor: '*People-spfa-fixes' stamp: 'spfa 3/30/2018 17:18'!
balanceOffsets
self layoutFrame hasFixedHeight ifTrue: [
| otop obot ctop cbot topf |
otop := (owner submorphs detect: [:m |
m layoutFrame topFraction isZero] ifNone: [^ self]) in: [:tm |
tm top - (tm layoutFrame topOffset ifNil: [0])].
obot := (owner submorphs detect: [:m |
m layoutFrame bottomFraction = 1] ifNone: [^ self]) in: [:tm |
tm bottom - (tm layoutFrame bottomOffset ifNil: [0])].
ctop := (self layoutFrame topFraction * (obot - otop)) rounded
+ otop + (self layoutFrame topOffset ifNil: [0]).
cbot := (self layoutFrame bottomFraction * (obot - otop)) rounded
+ otop + (self layoutFrame bottomOffset ifNil: [0]).
topf := self layoutFrame topFraction.
self layoutFrame topFraction: ((ctop + cbot) * 0.5 - otop) / (obot - otop) asFloat.
self layoutFrame bottomFraction: self layoutFrame topFraction.
self layoutFrame topOffset: ctop -
(self layoutFrame topFraction * (obot - otop) + otop) rounded.
self layoutFrame bottomOffset: cbot -
(self layoutFrame bottomFraction * (obot - otop) + otop) rounded..
(leftOrTop copy union: rightOrBottom) do: [:m |
(m layoutFrame topFraction closeTo: topf) ifTrue: [
m layoutFrame topFraction: self layoutFrame topFraction.
m layoutFrame topOffset:
m layoutFrame topOffset - (self valueOfProperty: #fullDelta) y].
(m layoutFrame bottomFraction closeTo: topf) ifTrue: [
m layoutFrame bottomFraction: self layoutFrame topFraction.
m layoutFrame bottomOffset:
m layoutFrame bottomOffset - (self valueOfProperty: #fullDelta) y.]]] .
self layoutFrame hasFixedWidth ifTrue: [
| oleft oright cleft cright leftf |
oleft := (owner submorphs detect: [:m |
m layoutFrame leftFraction isZero] ifNone: [^ self]) in: [:tm |
tm left - (tm layoutFrame leftOffset ifNil: [0])].
oright := (owner submorphs detect: [:m |
m layoutFrame rightFraction = 1] ifNone: [^ self]) in: [:tm |
tm right - (tm layoutFrame rightOffset ifNil: [0])].
cleft := (self layoutFrame leftFraction * (oright - oleft)) rounded
+ oleft + (self layoutFrame leftOffset ifNil: [0]).
cright := (self layoutFrame rightFraction * (oright - oleft)) rounded
+ oleft + (self layoutFrame rightOffset ifNil: [0]).
leftf := self layoutFrame leftFraction.
self layoutFrame leftFraction: ((cleft + cright) * 0.5 - oleft) / (oright - oleft) asFloat.
self layoutFrame rightFraction: self layoutFrame leftFraction.
self layoutFrame leftOffset: cleft -
(self layoutFrame leftFraction * (oright - oleft) + oleft) rounded.
self layoutFrame rightOffset: cright -
(self layoutFrame rightFraction * (oright - oleft) + oleft) rounded.
(leftOrTop copy union: rightOrBottom) do: [:m |
(m layoutFrame leftFraction closeTo: leftf) ifTrue: [
m layoutFrame leftFraction: self layoutFrame leftFraction.
m layoutFrame leftOffset:
m layoutFrame leftOffset - (self valueOfProperty: #fullDelta) x].
(m layoutFrame rightFraction closeTo: leftf) ifTrue: [
m layoutFrame rightFraction: self layoutFrame leftFraction.
m layoutFrame rightOffset:
m layoutFrame rightOffset - (self valueOfProperty: #fullDelta) x.]]] .
self removeProperty: #fullDelta.
owner layoutChanged
! !
!ProportionalSplitterMorph methodsFor: '*People-spfa-fixes' stamp: 'spfa 3/30/2018 16:55'!
mouseDown: anEvent
"If the user manually drags me, don't override him with auto positioning."
self setProperty: #fullDelta toValue: 0 at 0.
anEvent redButtonChanged
ifTrue: [ self withSiblingSplittersDo: [ : each | each stopStepping ] ]
ifFalse:
[ anEvent shiftPressed
ifTrue: [ self startStepping ]
ifFalse:
[ self startStepping.
self withSiblingSplittersDo: [ : each | each startStepping ] ] ].
(self class showSplitterHandles not and: [ self bounds containsPoint: anEvent cursorPoint ]) ifTrue:
[ oldColor := self color.
self color: Color black ].
^ super mouseDown: anEvent! !
!ProportionalSplitterMorph methodsFor: '*People-spfa-fixes' stamp: 'spfa 3/30/2018 17:18'!
mouseUp: anEvent
(self bounds containsPoint: anEvent cursorPoint)
ifFalse: [anEvent hand showTemporaryCursor: nil].
self class fastSplitterResize
ifTrue: [self updateFromEvent: anEvent].
traceMorph ifNotNil: [traceMorph delete. traceMorph := nil].
self color: self getOldColor.
self balanceOffsets! !
!ProportionalSplitterMorph methodsFor: '*People-spfa-fixes' stamp: 'spfa 3/31/2018 10:38'!
repositionBy: delta
| selfTop selfBottom selfLeft selfRight |
self setProperty: #fullDelta toValue: ((self valueOfProperty: #fullDelta) ifNil: [0 at 0]) + delta.
leftOrTop do:
[ : each | | firstRight firstBottom firstLeft firstTop |
firstRight := each layoutFrame rightOffset ifNil: [ 0 ].
firstBottom := each layoutFrame bottomOffset ifNil: [ 0 ].
each layoutFrame rightOffset: firstRight + delta x.
each layoutFrame bottomOffset: firstBottom + delta y.
each layoutFrame hasFixedHeight ifTrue: [
firstTop := each layoutFrame topOffset ifNil: [ 0 ].
each layoutFrame topOffset: firstTop + delta y ].
each layoutFrame hasFixedWidth ifTrue: [
firstLeft := each layoutFrame leftOffset ifNil: [ 0 ].
each layoutFrame leftOffset: firstLeft + delta x. ] ].
rightOrBottom do:
[ : each | | secondLeft secondTop secondRight secondBottom |
secondLeft := each layoutFrame leftOffset ifNil: [ 0 ].
secondTop := each layoutFrame topOffset ifNil: [ 0 ].
each layoutFrame leftOffset: secondLeft + delta x.
each layoutFrame topOffset: secondTop + delta y.
each layoutFrame hasFixedHeight ifTrue: [
secondBottom := each layoutFrame bottomOffset ifNil: [ 0 ].
each layoutFrame bottomOffset: secondBottom + delta y. ].
each layoutFrame hasFixedWidth ifTrue: [
secondRight := each layoutFrame rightOffset ifNil: [ 0 ].
each layoutFrame rightOffset: secondRight + delta x. ] ].
selfTop := self layoutFrame topOffset ifNil: [ 0 ].
selfBottom := self layoutFrame bottomOffset ifNil: [ 0 ].
selfLeft := self layoutFrame leftOffset ifNil: [ 0 ].
selfRight := self layoutFrame rightOffset ifNil: [ 0 ].
self layoutFrame
topOffset: selfTop + delta y ;
bottomOffset: selfBottom + delta y ;
leftOffset: selfLeft + delta x ;
rightOffset: selfRight + delta x.
self owner layoutChanged.
self movements removeFirst; add: (splitsTopAndBottom ifTrue: [ delta y sign ] ifFalse: [ delta x sign ])! !
More information about the Squeak-dev
mailing list
|