Bernhard Pieber uploaded a new version of Morphic to project The Inbox:
http://source.squeak.org/inbox/Morphic-bp.1033.mcz ==================== Summary ==================== Name: Morphic-bp.1033 Author: bp Time: 10 January 2016, 11:41:34.907 pm UUID: 9f66e1c2-045a-4459-af65-cf222455afca Ancestors: Morphic-mt.1032 SystemWindows snap and resize when dragged to corners and edges of the Display =============== Diff against Morphic-mt.1032 =============== 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 DragToEdges ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient FocusFollowsMouse GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow WindowsRaiseOnClick' - classVariableNames: 'ClickOnLabelToEdit CloseBoxFrame CloseBoxImageFlat CloseBoxImageGradient CollapseBoxImageFlat CollapseBoxImageGradient DoubleClickOnLabelToExpand ExpandBoxFrame ExpandBoxImageFlat ExpandBoxImageGradient FocusFollowsMouse GradientWindow HideExpandButton MenuBoxFrame MenuBoxImageFlat MenuBoxImageGradient ResizeAlongEdges ReuseWindows TopWindow WindowsRaiseOnClick' 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>>dragToEdges (in category 'preferences') ----- + dragToEdges + <preference: 'Drag To Edges' + category: 'windows' + description: 'When true, windows snap and resize to corners and edges of the Display.' + type: #Boolean> + ^DragToEdges ifNil: [false]! Item was added: + ----- Method: SystemWindow class>>dragToEdges: (in category 'preferences') ----- + dragToEdges: aBoolean + DragToEdges := aBoolean! Item was changed: ----- Method: SystemWindow>>doFastFrameDrag: (in category 'events') ----- doFastFrameDrag: grabPoint "Do fast frame dragging from the given point" | offset newBounds outerWorldBounds | outerWorldBounds := self boundsIn: nil. offset := outerWorldBounds origin - grabPoint. + newBounds := outerWorldBounds newRectFrom: [:f | + | p a selector | + p := Sensor cursorPoint. + a := ActiveWorld clearArea. + (self class dragToEdges and: [(selector := self dragToEdgesSelectorFor: p in: a) notNil]) + ifTrue: [a perform: selector] + ifFalse: [p + offset extent: outerWorldBounds extent]]. + self bounds: newBounds; comeToFront! - newBounds := outerWorldBounds newRectFrom: [:f | - Sensor cursorPoint + offset extent: outerWorldBounds extent]. - self position: (self globalPointToLocal: newBounds topLeft); comeToFront! Item was added: + ----- Method: SystemWindow>>dragToEdgesSelectorFor:in: (in category 'resize/collapse') ----- + dragToEdgesSelectorFor: p in: a + "answer first matching drag resize selector, if none is found, answer nil" + #(point:nearTopLeftOf: point:nearTopRightOf: point:nearBottomLeftOf: point:nearBottomRightOf: point:nearTopOf: point:nearBottomOf: point:nearLeftOf: point:nearRightOf:) + with: #(topLeftQuadrant topRightQuadrant bottomLeftQuadrant bottomRightQuadrant topHalf bottomHalf leftHalf rightHalf) + do: [:predicate :selector | + (self perform: predicate with: p with: a) ifTrue: [^selector]]. + ^nil! Item was added: + ----- Method: SystemWindow>>point:nearBottomLeftOf: (in category 'resize/collapse') ----- + point: p nearBottomLeftOf: a + ^(self point: p nearBottomOf: a) and: [self point: p nearLeftOf: a]! Item was added: + ----- Method: SystemWindow>>point:nearBottomOf: (in category 'resize/collapse') ----- + point: p nearBottomOf: a + ^p y > (a bottom - 10)! Item was added: + ----- Method: SystemWindow>>point:nearBottomRightOf: (in category 'resize/collapse') ----- + point: p nearBottomRightOf: a + ^(self point: p nearBottomOf: a) and: [self point: p nearRightOf: a]! Item was added: + ----- Method: SystemWindow>>point:nearLeftOf: (in category 'resize/collapse') ----- + point: p nearLeftOf: a + ^p x < (a left + 10)! Item was added: + ----- Method: SystemWindow>>point:nearRightOf: (in category 'resize/collapse') ----- + point: p nearRightOf: a + ^p x > (a right - 10)! Item was added: + ----- Method: SystemWindow>>point:nearTopLeftOf: (in category 'resize/collapse') ----- + point: p nearTopLeftOf: a + ^(self point: p nearTopOf: a) and: [self point: p nearLeftOf: a]! Item was added: + ----- Method: SystemWindow>>point:nearTopOf: (in category 'resize/collapse') ----- + point: p nearTopOf: a + ^p y < (a top + 10)! Item was added: + ----- Method: SystemWindow>>point:nearTopRightOf: (in category 'resize/collapse') ----- + point: p nearTopRightOf: a + ^(self point: p nearTopOf: a) and: [self point: p nearRightOf: a]! |
Hi Bernhard,
nice idea! Here are some suggestions: - Let boolean messages start with "is" such as "isPoint:nearRightOf:" instead of "point:nearRightOf:". - Make it work for non-fast (normal) dragging also. - Remove hardcoded "10" to a snap-threshold preference or at least some named method that returns that constant value. - Do some #bench to measure the impact of the additonal calls to #clearArea, #dragToEdgesSelectorFor:in:, etc. because this might be relevant for the "fast drag mode" --- I think that the impact of the additional calculations should be manageable. - What about snapping to the edges of other windows nearby? :-) Best, Marcel |
Hmm... it might be tricky to implement that for non-fast dragging. (see SystemWindow >> #startDragFromLabel:).
But maybe it could also work for SystemWindow >> #doFastWindowReframe:. Best, Marcel |
In reply to this post by marcel.taeumel
Hi Marcel,
Thank you for the feedback, especially the code review. I just copied an improved version to the inbox. Comments inline. > Am 11.01.2016 um 16:16 schrieb marcel.taeumel <[hidden email]>: > nice idea! > > Here are some suggestions: > > - Let boolean messages start with "is" such as "isPoint:nearRightOf:" > instead of „point:nearRightOf:". Done! > - Make it work for non-fast (normal) dragging also. Had a short look and decided this was for another day. ;-) Especially since I always use fast drag. Does anyone use non-fast drag? > - Remove hardcoded "10" to a snap-threshold preference or at least some > named method that returns that constant value. Done. I introduced a method. > - Do some #bench to measure the impact of the additonal calls to #clearArea, > #dragToEdgesSelectorFor:in:, etc. because this might be relevant for the > "fast drag mode" --- I think that the impact of the additional calculations > should be manageable. I am not sure how to bench that. However, I moved the call to #clearArea outside the block, so it is only called once when you start dragging. This should not be a problem because I cannot think of a way the display might be resized while you are dragging a window. > - What about snapping to the edges of other windows nearby? :-) I had thought about this. This is a different feature, though. Cheers, Bernhard |
Hey Bernhard.
"Does anyone use non-fast drag?" --- Yes, me. All the time. I want to see the contents of a window all the time to find out easier which size I need for a window. It's like a preview of fast drag before I do mouse-up. ;-) Best, Marcel |
Free forum by Nabble | Edit this page |