Better Squeak UIs, "Skin Clicks" ?

Arjen van Elteren ak.elteren at quicknet.nl
Fri Jan 12 21:12:16 UTC 2001


Hi 

I like the ideas behind the future UI. I think it looks
really great. 

After some hours of coding I've now implemented a
basic morph which supportes some of the features.
I've used the current gradient implementation but
I will be looking into the change set provided by bert.

The current implementation is seperate from the SystemWindow
hierarchy so you can add it to your system and don't
have to worry about breaking anything important.

Some features;
* Scalable rounded corners 
* Stairs in the label
* One morph can be fitted into the hole by dragging a morph on to the frame
* Inactive windows have smaller decorations

TODO items;
* Collapsing
* Menu with a nice squeak logo as button
* Integrate different gradient style

I release this mainly because I want to know if this is the way to go...
(I like it alot so far)

Arjen

PS it adds a property to the World for it's project data, is this the right
way to go ?

-------------- next part --------------
'From Squeak2.9alpha of 13 June 2000 [latest update: #3193] on 12 January 2001 at 9:58:33 pm'!
"Change Set:		AlternativeLook
Date:			12 January 2001
Author:			AvE

This set contains basic support for the Viviarium look. It does not change anything
in the base system so you can easily try it out.   "!

Morph subclass: #KozijnMorph
	instanceVariableNames: 'cornerGlyphs oldColor frameWidth frameHeight title contentMorph level '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Look-Kernel'!
KozijnMorph class
	instanceVariableNames: ''!

!KozijnMorph methodsFor: 'event handling' stamp: 'AvE 1/12/2001 20:54'!
handlesMouseDown: evt
	"If I am not the topWindow, then I will only respond to dragging by the title bar.
	Any other click will only bring me to the top"
	(self contentBounds containsPoint: (self globalPointToLocal: evt cursorPoint))
		ifFalse: [^ false].
	^ level ~~ 1.! !

!KozijnMorph methodsFor: 'event handling' stamp: 'AvE 1/12/2001 20:57'!
mouseDown: evt
	| |
	level == 1 ifFalse: [self activate].
	! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:54'!
activate
	((self windowLevels at: 1) includes: self) ifTrue:[ ^self].
	level > 0 ifTrue:[( self windowLevels  at: level) remove: self ifAbsent:[nil]].
	level _ 1.
	self insertAtLevel: level frame: self.
	! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:32'!
frameHeightAtLevel: anInteger
	^(#(45 35 25 ) at: anInteger)! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:53'!
insertAtLevel: anInteger frame: aMorph 
	| maxItems item |
	maxItems _ self maxItemsAtLevel: anInteger.
	(anInteger < self windowLevels size
			and: [(self windowLevels at: anInteger) size >= maxItems])
		ifTrue: ["Remove an item at this level and insert it into a higher level"
			nil.
			item _ (self windowLevels at: anInteger) someElement.
			(self windowLevels at: anInteger)
				remove: item.
			self insertAtLevel: anInteger + 1 frame: item].
	(self windowLevels at: anInteger)
		add: aMorph.
	aMorph insertedIntoLevel: anInteger! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:33'!
insertedIntoLevel: anInteger 
	level _ anInteger.
	level == 1
		ifTrue: [self comeToFront.
			contentMorph isNil ifFalse:[ contentMorph unlock]]
		ifFalse:[contentMorph isNil ifFalse:[contentMorph lock]].
	self
		frameHeight: (self frameHeightAtLevel: anInteger).! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:31'!
maxItemsAtLevel: anInteger
	"How many items can fit into one level ?"
	anInteger == 1 ifTrue: [^1]
		ifFalse:[^ 3].
	! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:54'!
removeFromLevel
	| item |
	(self windowLevels at: level) remove: self.
	level <  self windowLevels  size ifFalse:[^self].
	( self windowLevels  at: (level + 1) ) size > 0 ifTrue:[ 
		item _ ( self windowLevels  at: (level+1)) someElement.
		item removeFromLevel.
		self insertAtLevel: level frame: item.
	].
	! !

!KozijnMorph methodsFor: 'window handling' stamp: 'AvE 1/12/2001 21:53'!
windowLevels
	"Look for the levels in the world morph"
	| windowLevels |
	(World hasProperty: #kozijnWindowLevels)
		ifFalse: [windowLevels _ Array new: 3.
			1
				to: 3
				do: [:i | windowLevels at: i put: Set new].
			World setProperty: #kozijnWindowLevels toValue: windowLevels].
	^ World valueOfProperty: #kozijnWindowLevels! !

!KozijnMorph methodsFor: 'submorphs-add/remove' stamp: 'AvE 1/12/2001 20:41'!
delete
	self removeFromLevel.
	super delete.! !

!KozijnMorph methodsFor: 'submorphs-add/remove' stamp: 'AvE 1/12/2001 19:54'!
privateRemoveMorph: aMorph
	aMorph == contentMorph ifTrue:[ contentMorph _ nil].
	^ super privateRemoveMorph: aMorph.! !

!KozijnMorph methodsFor: 'dropping/grabbing' stamp: 'AvE 1/12/2001 19:59'!
acceptDroppingMorph: aMorph event: evt 
	contentMorph ~~ nil
		ifTrue: [self replaceSubmorph: contentMorph by: aMorph]
		ifFalse: [self addMorph: aMorph].
	contentMorph _ aMorph.
	aMorph position: self contentBounds origin.
	self extent: aMorph extent + (2 * self frameWidth @ (self frameHeight + self frameWidth)).
	contentMorph extent: self contentBounds extent! !

!KozijnMorph methodsFor: 'dropping/grabbing' stamp: 'AvE 1/12/2001 21:55'!
justDroppedInto: aMorph event: anEvent
	(( self windowLevels  at: 1) includes:self) ifFalse: [self activate].
	^super justDroppedInto: aMorph event: anEvent! !

!KozijnMorph methodsFor: 'dropping/grabbing' stamp: 'AvE 1/12/2001 21:07'!
wantsDroppedMorph: aMorph event: evt 
	"Return true if the receiver wishes to accept the given morph, which is  
	being dropped by a hand in response to the given event. Note that for  
	a successful drop operation both parties need to agree. The symmetric  
	check is done automatically via aMorph wantsToBeDroppedInto: self."
	(aMorph isKindOf: self class) ifTrue:[^false].
	^ self dropEnabled
		and: [(self contentBounds
				containsPoint: (self globalPointToLocal: evt cursorPoint)) not]! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 16:24'!
bottomSize
	^ (self frameWidth / 1.5) asInteger! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 15:27'!
dark
	^self color darker darker! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 16:11'!
frameHeight
	^ frameHeight! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 20:23'!
frameHeight: anInteger 
	| delta realHeight |
	realHeight _ anInteger // 3 * 3 + 3.
	delta _ frameHeight - realHeight.
	frameHeight _ realHeight.
	self buildCornerGlyphs.
	self position: self position + (0 @ delta);
		 extent: self extent - (0 @ delta).
	! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 16:11'!
frameWidth
	^ frameWidth! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 16:18'!
frameWidth: anInteger
	| delta |
	delta _ frameWidth - anInteger.
	frameWidth _ anInteger.
	self buildCornerGlyphs.
	self position: self position + (delta @ 0);
		 extent: self extent - ( 2*delta @ delta)! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 15:27'!
light
	^self color alphaMixed: 0.4 with: Color white.! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 21:26'!
title
	title contents! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 21:26'!
title: aString
	title contents: aString! !

!KozijnMorph methodsFor: 'accessing' stamp: 'AvE 1/12/2001 15:58'!
topSize
	^self frameWidth! !

!KozijnMorph methodsFor: 'geometry' stamp: 'AvE 1/12/2001 19:45'!
contentBounds
	^ self topLeft + (self frameWidth @ self frameHeight) corner: self bottomRight - self frameWidth asPoint! !

!KozijnMorph methodsFor: 'geometry' stamp: 'AvE 1/12/2001 19:59'!
extent: aPoint 
	aPoint x < (self frameWidth * 2 + self frameHeight)
		ifTrue: [^ self].
	aPoint y < (self frameWidth + self frameHeight)
		ifTrue: [^ self].
	super extent: aPoint.
	contentMorph == nil
		ifFalse: [contentMorph extent: self contentBounds extent]! !

!KozijnMorph methodsFor: 'geometry' stamp: 'AvE 1/12/2001 20:25'!
position: aPoint 
	super position: aPoint.
	contentMorph == nil
		ifFalse: [contentMorph position: (self contentBounds origin)]! !

!KozijnMorph methodsFor: 'drawing' stamp: 'AvE 1/12/2001 19:45'!
drawInnerFrameOn: canvas 
	canvas frameAndFillRectangle:(self contentBounds insetBy:-2)
			fillColor: Color transparent
			borderWidth: 2
			topLeftColor: self dark
			bottomRightColor: self light.! !

!KozijnMorph methodsFor: 'drawing' stamp: 'AvE 1/12/2001 21:31'!
drawOn: canvas	
	self drawOuterFrameOn: canvas.	
	self drawStairsOn: canvas.
	self drawInnerFrameOn: canvas.
		
	! !

!KozijnMorph methodsFor: 'drawing' stamp: 'AvE 1/12/2001 21:31'!
drawOuterFrameOn: canvas 
	"Draws a nice frame"
	canvas
		fillRectangle: (self topLeft + (self topSize @ 0) corner: self topRight - (self topSize @ (-1 * self  frameHeight)))
		color: self color.
	canvas
		fillRectangle: (self topLeft + (0 @ self topSize) corner: self bottomLeft + (self frameWidth @(-1 * self bottomSize)))
		color: self color.
	canvas
		fillRectangle: (self bottomLeft + (self bottomSize @ (-1 * self frameWidth)) corner: self bottomRight - (self bottomSize @ 0))
		color: self color.
	canvas
		fillRectangle: (self topRight - (self frameWidth @ (-1*self topSize) ) corner: self bottomRight - (0 @ self bottomSize))
		color: self color.
	canvas
		paintImage: (cornerGlyphs at: 1)
		at: self topLeft.
	canvas
		paintImage: (cornerGlyphs at: 2)
		at: self topRight - (self topSize @ 0).
	canvas
		paintImage: (cornerGlyphs at: 3)
		at: self bottomLeft - (0 @ self bottomSize).
	canvas
		paintImage: (cornerGlyphs at: 4)
		at: self bottomRight - (self bottomSize asPoint).
	canvas
		line: self topLeft + (self topSize @ 0)
		to: self topRight - (self topSize @ 0)
		color: self light.
	canvas
		line: self topLeft + (0 @ self topSize)
		to: self bottomLeft - (0 @ self bottomSize)
		color: self light.
	canvas
		line: self bottomLeft + (self bottomSize @ -1)
		to: self bottomRight - (self bottomSize @ 1)
		color: self dark.
	canvas
		line: self topRight + (-1 @ self topSize)
		to: self bottomRight - (1 @ self bottomSize)
		color: self dark.
	! !

!KozijnMorph methodsFor: 'drawing' stamp: 'AvE 1/12/2001 17:33'!
drawStairsOn: canvas 
	| position width color1 color2 style height |
	height _ self frameHeight - 3 // 3.
	width _ (self extent x // 3) + (height * 3).
	position _ self topRight - (width + 1 @ -1).
	color1 _ self dark.
	color2 _ self color.
	style _ GradientFillStyle ramp: {0.0 -> color1. 1.0 -> color2}.
	0 to: 2 do: [:i | 
			style origin: position + (i * height @ (height * i + 1)).
			width _  width - height.
			style direction: width @ 0.
			style normal: 0 @ width.
			style radial: false.
			canvas
				fillRectangle: (position extent: width @ height)
				fillStyle: style.
			canvas line: position -(1 at 0) to: position-(1 at 0) + (0 at height) color: self dark.
			position _ position + (height asPoint).
			canvas line: position - (height at 0) to: position color: self light.
			]! !

!KozijnMorph methodsFor: 'initialization' stamp: 'AvE 1/12/2001 21:25'!
initialize
	super initialize.
	frameWidth _ 13.
	frameHeight _ 45.
	self color: Color lightGreen.
	self buildCornerGlyphs.
	self enableDrop: true.
	self extent: 200 at 100.
	level _ 0.
	self activate.
	title _ StringMorph contents: 'Window Title'.
	title position: self position + (self frameWidth @3).
	title extent: (self extent x * 4 // 5 @ (self frameHeight - 5)).
	self addMorph: title.
! !

!KozijnMorph methodsFor: 'caching' stamp: 'AvE 1/12/2001 19:24'!
buildCornerGlyph: size borderColor: borderColor
	| form rect canvas |
	form _ Form extent: size @ size depth: Display depth.
	rect _ 0 @ 0 corner: size @ size.
	color _ self color.
	canvas _ form getCanvas asBalloonCanvas.
	canvas aaLevel:2.
	canvas
		fillOval: rect
		color: self color
		borderWidth: 1
		borderColor: borderColor.
	^ form! !

!KozijnMorph methodsFor: 'caching' stamp: 'AvE 1/12/2001 15:50'!
buildCornerGlyphs
	| circles |
	cornerGlyphs _ Array new: 4.
	"First build some corner circles"
	circles _ Array new: 4.
	circles
		at: 1
		put: (self buildCornerGlyph: self topSize * 2 borderColor: self light).
	circles
		at: 2
		put: (self buildCornerGlyph: self topSize * 2 borderColor: self dark).
	circles
		at: 3
		put: (self buildCornerGlyph: self bottomSize * 2 borderColor: self light).
	circles
		at: 4
		put: (self buildCornerGlyph: self bottomSize * 2 borderColor: self dark).
	cornerGlyphs
		at: 1
		put: ((circles at: 1)
				contentsOfArea: (0 @ 0 corner: self topSize asPoint)).
	cornerGlyphs
		at: 2
		put: ((circles at: 1)
				contentsOfArea: (self topSize @ 0 corner: self topSize * 2 @ self topSize)).
	cornerGlyphs
		at: 3
		put: ((circles at: 3)
				contentsOfArea: (0 @ self bottomSize corner: self bottomSize @ (self bottomSize * 2))).
	cornerGlyphs
		at: 4
		put: ((circles at: 4)
				contentsOfArea: (self bottomSize asPoint corner: (self bottomSize * 2) asPoint)).
	oldColor _ color! !

!KozijnMorph methodsFor: 'caching' stamp: 'AvE 1/12/2001 15:32'!
changed
	super changed.
	color = oldColor
		ifFalse:[self buildCornerGlyphs].
	! !

KozijnMorph class removeSelector: #initialize!


More information about the Squeak-dev mailing list