[ENH] rounded corners while dragging

Stephan B. Wessels stephan.wessels at sdrc.com
Tue Nov 23 22:22:04 UTC 1999


--------------38E0A57D0EC8E176232CF2A1
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit


I was tinkering with the cool rounded windows corner code for Morphic and
decided that the rectangles that appear when you drag and resize a window had to
go.

This change set (tested only with 2.7a) will check the same rounded corners
option and if fast dragging is also turned on it will draw the rectangle
outlines with round corners too.

  - Steve

--------------38E0A57D0EC8E176232CF2A1
Content-Type: text/plain; charset=us-ascii;
 name="rounded drag.2.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="rounded drag.2.cs"


'From Squeak2.7alpha of 18 November 1999 [latest update: #1617] on 23 November 1999 at 12:19:44 pm'!

!CornerRounder methodsFor: 'all' stamp: 'sbw 11/20/1999 08:17'!
drawArcCentered: aPoint quadrant: quadrant onForm: aForm rule: aRule fillColor: aColor 
	| segs angle sin cos xn yn xn1 yn1 radius |
	radius _ (cornerOverlays at: 1) boundingBox width.
	segs _ 12.0.
	angle _ 90.0 / segs.
	sin _ (angle * (2 * Float pi / 360.0)) sin.
	cos _ (angle * (2 * Float pi / 360.0)) cos.
	quadrant = 1
		ifTrue: 
			[xn _ radius asFloat.
			yn _ 0.0].
	quadrant = 2
		ifTrue: 
			[xn _ 0.0.
			yn _ 0.0 - radius asFloat].
	quadrant = 3
		ifTrue: 
			[xn _ 0.0 - radius asFloat.
			yn _ 0.0].
	quadrant = 4
		ifTrue: 
			[xn _ 0.0.
			yn _ radius asFloat].
	segs asInteger
		timesRepeat: 
			[xn1 _ xn * cos + (yn * sin).
			yn1 _ yn * cos - (xn * sin).
			self
				drawCornerSpotAt: aPoint + (xn asInteger @ yn asInteger)
				onForm: aForm
				rule: aRule
				fillColor: aColor.
			xn _ xn1.
			yn _ yn1]! !

!CornerRounder methodsFor: 'all' stamp: 'sbw 11/20/1999 07:54'!
drawCornerSpotAt: aPoint onForm: aForm rule: aRule fillColor: aColor 
	aForm
		border: (Rectangle origin: aPoint extent: 2 @ 2)
		width: 1
		rule: aRule
		fillColor: aColor! !

!CornerRounder methodsFor: 'all' stamp: 'sbw 11/20/1999 12:32'!
drawRoundedCornerRectangle: aRectangle onForm: aForm rule: aRule fillColor: aColor 
	| rad wid |
	rad _ (cornerOverlays at: 1) boundingBox width.
	wid _ 2.
	aForm
		border: aRectangle
		width: wid
		rule: aRule
		fillColor: aColor
		skip: rad.
	self
		drawArcCentered: (aRectangle topRight + ((0-rad-2)@(rad-1)))
		quadrant: 1
		onForm: aForm
		rule: aRule
		fillColor: aColor.
	self
		drawArcCentered: (aRectangle topLeft + rad)
		quadrant: 2
		onForm: aForm
		rule: aRule
		fillColor: aColor.
	self
		drawArcCentered: (aRectangle bottomLeft + (rad@(0-rad-1)))
		quadrant: 3
		onForm: aForm
		rule: aRule
		fillColor: aColor.
	self
		drawArcCentered: (aRectangle corner - (rad@(rad+2)))
		quadrant: 4
		onForm: aForm
		rule: aRule
		fillColor: aColor! !


!CornerRounder class methodsFor: 'all' stamp: 'sbw 11/12/1999 18:46'!
drawRoundedCornerRectangle: aRectangle onForm: aForm rule: aRule fillColor: aColor

	| rounder |
	rounder _ CR2.
	rounder drawRoundedCornerRectangle: aRectangle onForm: aForm rule: aRule fillColor: aColor! !


!Form methodsFor: 'bordering' stamp: 'sbw 11/15/1999 22:17'!
border: rect width: borderWidth rule: rule fillColor: fillColor skip: anInteger 
	"Paint a border whose rectangular area is defined by rect. The     
	
	width of the border of each side is borderWidth. Uses fillColor for     
	
	drawing the border."
	| blt |
	blt _ (BitBlt toForm: self) combinationRule: rule;
			 fillColor: fillColor.
	blt sourceOrigin: 0 @ 0.
	"draw upper horiz line."
	blt destOrigin: rect origin + (anInteger @ 0).
	blt width: rect width - (2 * anInteger);
	 height: borderWidth;
	 copyBits.
	"draw lower horiz line."
	blt destY: rect origin y + rect height - borderWidth;
	 copyBits.
	"draw left vert line."
	blt destOrigin: rect origin + (0 @ anInteger).
	blt height: rect height - borderWidth - borderWidth - anInteger;
	 width: borderWidth;
	 copyBits.
	"draw right vert line."
	blt destX: rect corner x - borderWidth;
	 copyBits! !


!Rectangle methodsFor: 'transforming' stamp: 'sbw 11/12/1999 15:12'!
newRectFrom: newRectBlock

	^self newRectFrom: newRectBlock rounded: false! !

!Rectangle methodsFor: 'transforming' stamp: 'sbw 11/13/1999 23:12'!
newRectFrom: newRectBlock rounded: roundedFlag 
	"Track the outline of a new rectangle until mouse button changes.        
	 newFrameBlock produces each new rectangle from the previous"
	| rect newRect buttonStart buttonNow borderWidth fillColor rule |
	borderWidth _ 2.
	fillColor _ Color gray.
	rule _ Form reverse.
	buttonStart _ buttonNow _ Sensor anyButtonPressed.
	rect _ self.
	roundedFlag
		ifTrue: [CornerRounder
				drawRoundedCornerRectangle: rect
								onForm: Display
								rule: rule
								fillColor: fillColor]
		ifFalse: [Display
				border: rect
				width: borderWidth
				rule: rule
				fillColor: fillColor].
	[buttonNow == buttonStart]
		whileTrue: 
			[Processor yield.
			buttonNow _ Sensor anyButtonPressed.
			newRect _ newRectBlock value: rect.
			newRect = rect
				ifFalse: 
					[roundedFlag
						ifTrue: 
							[CornerRounder
								drawRoundedCornerRectangle: rect
								onForm: Display
								rule: rule
								fillColor: fillColor.
							CornerRounder
								drawRoundedCornerRectangle: newRect
								onForm: Display
								rule: rule
								fillColor: fillColor]
						ifFalse: 
							[Display
								border: rect
								width: borderWidth
								rule: rule
								fillColor: fillColor.
							Display
								border: newRect
								width: borderWidth
								rule: rule
								fillColor: fillColor].
					rect _ newRect]].
	roundedFlag
		ifTrue: [CornerRounder
				drawRoundedCornerRectangle: rect
				onForm: Display
				rule: rule
				fillColor: fillColor]
		ifFalse: [Display
				border: rect
				width: borderWidth
				rule: rule
				fillColor: fillColor].
	^ rect! !


!SystemWindow methodsFor: 'resize/collapse' stamp: 'sbw 11/23/1999 12:15'!
spawnReframeHandle: event 
	"The mouse has crossed a pane border.  Spawn a reframe handle."
	| resizer localPt pt ptName newBounds vbtl |
	owner ifNil: [^ self"Don't activate resizer if in a scrollbar"].
	(self isActive not or: [self isCollapsed])
		ifTrue: [^ self].
	((self world ifNil: [^ self]) firstSubmorph isKindOf: NewHandleMorph)
		ifTrue: [^ self].
	paneMorphs do: [:p | ((p fullBounds insetBy: 1)
			containsPoint: event cursorPoint)
			ifTrue: [^ self]].
	pt _ event cursorPoint.
	self bounds forPoint: pt
		closestSideDistLen: [:side :dist :len | "Check for window side adjust"
			dist <= 2 ifTrue: [ptName _ side]].
	ptName ifNil: ["Check for pane border adjust"
		^ self spawnPaneFrameHandle: event].
	#(topLeft bottomRight bottomLeft topRight ) do: [:corner | "Check for window corner adjust"
		(pt dist: (self bounds perform: corner))
			< 20 ifTrue: [ptName _ corner]].
	vbtl _ self world viewBox topLeft.
	resizer _ NewHandleMorph new
				followHand: event hand
				forEachPointDo: 
					[:p | 
					localPt _ self pointFromWorld: p.
					newBounds _ self bounds
								withSideOrCorner: ptName
								setToPoint: localPt
								minExtent: 100 @ 80.
					self fastFramingOn
						ifTrue: 
							["For fast display, only higlight the rectangle 
							during loop"
							newBounds _ (self bounds translateBy: vbtl)
										newRectFrom: [:f | f
												withSideOrCorner: ptName
												setToPoint: (self pointFromWorld: Sensor cursorPoint)
												minExtent: 100 @ 80]
										rounded: Preferences roundedWindowCorners.
							self bounds: (newBounds translateBy: vbtl negated)]
						ifFalse: 
							[self bounds: newBounds.
							(Preferences roundedWindowCorners and: [#(bottom right bottomRight ) includes: ptName])
								ifTrue: 
									["Complete kluge: causes rounded corners 
									to get painted correctly, 
									in spite of not working with top-down 
									displayWorld. "
									ptName = #bottom ifFalse: [self invalidRect: (self bounds topRight - (6 @ 0) extent: 7 @ 7)].
									ptName = #right ifFalse: [self invalidRect: (self bounds bottomLeft - (0 @ 6) extent: 7 @ 7)].
									self invalidRect: (self bounds bottomRight - (6 @ 6) extent: 7 @ 7)]]]
				lastPointDo: [:p | p].
	event hand world addMorph: resizer.
	resizer startStepping! !

!SystemWindow methodsFor: 'events' stamp: 'sbw 11/12/1999 15:13'!
mouseDown: evt
	| cp offset newBounds vbtl |
	TopWindow == self ifFalse: [self activate].
	(Sensor redButtonPressed "If mouse is really still down after activate"
		and: [self labelRect containsPoint: evt cursorPoint]) ifTrue:
		["All copied from super (should use that code)"
		self fastFramingOn 
			ifTrue: [vbtl _ self world viewBox topLeft.
					offset _ self position + vbtl - Sensor cursorPoint.
					newBounds _ (self bounds translateBy: vbtl)
						newRectFrom: [:f | Sensor cursorPoint + offset extent: self extent]
						rounded: Preferences roundedWindowCorners.
					^ self position: newBounds topLeft - vbtl]
			ifFalse: [^ evt hand grabMorph: self topRendererOrSelf]].
	model windowActiveOnFirstClick ifTrue:
		["Normally window keeps control of first click.
		Need explicit transmission for first-click activity."
		cp _ evt cursorPoint.
		submorphs do: [:m | (m containsPoint: cp) ifTrue: [m mouseDown: evt]]]! !



--------------38E0A57D0EC8E176232CF2A1--





More information about the Squeak-dev mailing list