Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.760.mcz ==================== Summary ==================== Name: Morphic-mt.760 Author: mt Time: 26 February 2015, 6:19:14.906 pm UUID: fb8f4f20-e595-d444-a291-58885547c05f Ancestors: Morphic-topa.759 Corner rounding refactored. Does not rely on (spooky) CornerRounder implementation anymore. Many hacks for that CornerRounder could be removed from Morphic. A preference can be used to choose the preferred corner radius for rounded morphs. (Preferences > Morphic > Preferred Corner Radius) Subclasses may override the drawing of corners as needed. See draw* methods. =============== Diff against Morphic-topa.759 =============== Item was removed: - ----- Method: Canvas>>roundCornersOf:during: (in category 'drawing-general') ----- - roundCornersOf: aMorph during: aBlock - ^self roundCornersOf: aMorph in: aMorph bounds during: aBlock! Item was removed: - ----- Method: Canvas>>roundCornersOf:in:during: (in category 'drawing-general') ----- - roundCornersOf: aMorph in: bounds during: aBlock - ^aBlock value! Item was removed: - ----- Method: FormCanvas>>roundCornersOf:in:during: (in category 'drawing-general') ----- - roundCornersOf: aMorph in: bounds during: aBlock - aMorph wantsRoundedCorners ifFalse:[^aBlock value]. - (self seesNothingOutside: (CornerRounder rectWithinCornersOf: bounds)) - ifTrue: ["Don't bother with corner logic if the region is inside them" - ^ aBlock value]. - CornerRounder roundCornersOf: aMorph on: self in: bounds - displayBlock: aBlock - borderWidth: aMorph borderWidthForRounding - corners: aMorph roundedCorners! Item was changed: ----- Method: HandMorph>>fullDrawOn: (in category 'drawing') ----- fullDrawOn: aCanvas "A HandMorph has unusual drawing requirements: 1. the hand itself (i.e., the cursor) appears in front of its submorphs 2. morphs being held by the hand cast a shadow on the world/morphs below The illusion is that the hand plucks up morphs and carries them above the world." "Note: This version caches an image of the morphs being held by the hand for better performance. This cache is invalidated if one of those morphs changes." + | disableCaching subBnds | - | disableCaching subBnds roundCorners rounded | self visible ifFalse: [^self]. (aCanvas isVisible: self fullBounds) ifFalse: [^self]. (self hasProperty: #errorOnDraw) ifTrue:[^self drawErrorOn: aCanvas]. disableCaching := false. disableCaching ifTrue: [self nonCachingFullDrawOn: aCanvas. ^self]. submorphs isEmpty ifTrue: [cacheCanvas := nil. ^self drawOn: aCanvas]. "just draw the hand itself" subBnds := Rectangle merging: (submorphs collect: [:m | m fullBounds]). self updateCacheCanvas: aCanvas. (cacheCanvas isNil or: [cachedCanvasHasHoles and: [cacheCanvas depth = 1]]) ifTrue: ["could not use caching due to translucency; do full draw" self nonCachingFullDrawOn: aCanvas. ^self]. - "--> begin rounded corners hack <---" - roundCorners := cachedCanvasHasHoles == false - and: [submorphs size = 1 and: [submorphs first wantsRoundedCorners]]. - roundCorners - ifTrue: - [rounded := submorphs first. - aCanvas asShadowDrawingCanvas translateBy: self shadowOffset - during: - [:shadowCanvas | - shadowCanvas roundCornersOf: rounded - during: - [(subBnds areasOutside: (rounded boundsWithinCorners - translateBy: self shadowOffset negated)) - do: [:r | shadowCanvas fillRectangle: r color: Color black]]]. - aCanvas roundCornersOf: rounded - during: - [aCanvas - drawImage: cacheCanvas form - at: subBnds origin - sourceRect: cacheCanvas form boundingBox]. - ^self drawOn: aCanvas "draw the hand itself in front of morphs"]. - "--> end rounded corners hack <---" - "draw the shadow" aCanvas asShadowDrawingCanvas translateBy: self shadowOffset during: [:shadowCanvas | cachedCanvasHasHoles ifTrue: ["Have to draw the real shadow of the form" shadowCanvas paintImage: cacheCanvas form at: subBnds origin] ifFalse: ["Much faster if only have to shade the edge of a solid rectangle" (subBnds areasOutside: (subBnds translateBy: self shadowOffset negated)) do: [:r | shadowCanvas fillRectangle: r color: Color black]]]. "draw morphs in front of the shadow using the cached Form" cachedCanvasHasHoles ifTrue: [aCanvas paintImage: cacheCanvas form at: subBnds origin] ifFalse: [aCanvas drawImage: cacheCanvas form at: subBnds origin sourceRect: cacheCanvas form boundingBox]. self drawOn: aCanvas "draw the hand itself in front of morphs"! Item was changed: Object subclass: #Morph instanceVariableNames: 'bounds owner submorphs fullBounds color extension' + classVariableNames: 'PreferredCornerRadius' - classVariableNames: '' poolDictionaries: '' category: 'Morphic-Kernel'! !Morph commentStamp: 'efc 2/26/2003 20:01' prior: 0! A Morph (from the Greek "shape" or "form") is an interactive graphical object. General information on the Morphic system can be found at http://minnow.cc.gatech.edu/squeak/30. Morphs exist in a tree, rooted at a World (generally a PasteUpMorph). The morphs owned by a morph are its submorphs. Morphs are drawn recursively; if a Morph has no owner it never gets drawn. To hide a Morph and its submorphs, set its #visible property to false using the #visible: method. The World (screen) coordinate system is used for most coordinates, but can be changed if there is a TransformMorph somewhere in the owner chain. My instance variables have accessor methods (e.g., #bounds, #bounds:). Most users should use the accessor methods instead of using the instance variables directly. Structure: instance var Type Description bounds Rectangle A Rectangle indicating my position and a size that will enclose me. owner Morph My parent Morph, or nil for the top-level Morph, which is a or nil world, typically a PasteUpMorph. submorphs Array My child Morphs. fullBounds Rectangle A Rectangle minimally enclosing me and my submorphs. color Color My primary color. Subclasses can use this in different ways. extension MorphExtension Allows extra properties to be stored without adding a or nil storage burden to all morphs. By default, Morphs do not position their submorphs. Morphs may position their submorphs directly or use a LayoutPolicy to automatically control their submorph positioning. Although Morph has some support for BorderStyle, most users should use BorderedMorph if they want borders.! Item was added: + ----- Method: Morph class>>preferredCornerRadius (in category 'preferences') ----- + preferredCornerRadius + + <preference: 'Preferred Corner Radius' + category: 'Morphic' + description: 'If a morph wants rounded corners, use this radius. May be overwritten in subclasses.' + type: #Number> + ^ PreferredCornerRadius ifNil: [6]! Item was added: + ----- Method: Morph class>>preferredCornerRadius: (in category 'preferences') ----- + preferredCornerRadius: anInteger + + PreferredCornerRadius := anInteger.! 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 class preferredCornerRadius] + ifFalse: [self bounds] + ! - ^ CornerRounder rectWithinCornersOf: self bounds! Item was changed: ----- Method: Morph>>drawDropHighlightOn: (in category 'drawing') ----- drawDropHighlightOn: aCanvas + self highlightedForDrop ifTrue: [ + self wantsRoundedCorners + ifTrue: [aCanvas frameRoundRect: self fullBounds radius: self class preferredCornerRadius width: 1 color: self dropHighlightColor] + ifFalse: [aCanvas frameRectangle: self fullBounds color: self dropHighlightColor]].! - aCanvas frameRectangle: self fullBounds color: self dropHighlightColor].! Item was changed: ----- Method: Morph>>drawDropShadowOn: (in category 'drawing') ----- drawDropShadowOn: aCanvas aCanvas translateBy: self shadowOffset during: [ :shadowCanvas | + (shadowCanvas isVisible: self bounds) ifTrue: [ + self wantsRoundedCorners + ifTrue: [shadowCanvas fillRoundRect: self bounds radius: self class preferredCornerRadius fillStyle: self shadowColor] + ifFalse: [shadowCanvas fillRectangle: self bounds fillStyle: self shadowColor]]]. - shadowCanvas shadowColor: self shadowColor. - shadowCanvas roundCornersOf: self during: [ - (shadowCanvas isVisible: self bounds) ifTrue: - [shadowCanvas fillRectangle: self bounds fillStyle: self fillStyle]] - ]. ! Item was changed: ----- Method: Morph>>drawMouseDownHighlightOn: (in category 'drawing') ----- drawMouseDownHighlightOn: aCanvas + self highlightedForMouseDown ifTrue: [ + self wantsRoundedCorners + 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]].! - 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 class preferredCornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color] + ifFalse: [aCanvas fillRectangle: self bounds fillStyle: self fillStyle borderStyle: self borderStyle]. + - aCanvas fillRectangle: self bounds fillStyle: self fillStyle borderStyle: self borderStyle. ! Item was changed: ----- Method: Morph>>fullDrawOn: (in category 'drawing') ----- fullDrawOn: aCanvas "Draw the full Morphic structure on the given Canvas" self visible ifFalse: [^ self]. (aCanvas isVisible: self fullBounds) ifFalse:[^self]. (self hasProperty: #errorOnDraw) ifTrue:[^self drawErrorOn: aCanvas]. "Note: At some point we should generalize this into some sort of multi-canvas so that we can cross-optimize some drawing operations." + "Pass 1: Draw eventual drop-shadow" self hasDropShadow ifTrue: [self drawDropShadowOn: aCanvas]. (self hasRolloverBorder and: [(aCanvas seesNothingOutside: self bounds) not]) ifTrue: [self drawRolloverBorderOn: aCanvas]. "Pass 2: Draw receiver itself" + (aCanvas isVisible: self bounds) ifTrue:[aCanvas drawMorph: self]. + self drawSubmorphsOn: aCanvas. + self drawDropHighlightOn: aCanvas. + self drawMouseDownHighlightOn: aCanvas.! - aCanvas roundCornersOf: self during:[ - (aCanvas isVisible: self bounds) ifTrue:[aCanvas drawMorph: self]. - self drawSubmorphsOn: aCanvas. - self drawDropHighlightOn: aCanvas. - self drawMouseDownHighlightOn: aCanvas].! Item was removed: - ----- Method: PluggableCanvas>>roundCornersOf:in:during: (in category 'drawing-general') ----- - roundCornersOf: aMorph in: bounds during: aBlock - aMorph wantsRoundedCorners ifFalse:[^aBlock value]. - (self seesNothingOutside: (CornerRounder rectWithinCornersOf: bounds)) - ifTrue: ["Don't bother with corner logic if the region is inside them" - ^ aBlock value]. - CornerRounder roundCornersOf: aMorph on: self in: bounds - displayBlock: aBlock - borderWidth: aMorph borderWidthForRounding - corners: aMorph roundedCorners! Item was changed: ----- Method: WorldState>>displayWorld:submorphs: (in category 'update cycle') ----- displayWorld: aWorld submorphs: submorphs "Update this world's display." + | deferredUpdateMode handsToDraw allDamage handDamageRects worldDamageRects | - | deferredUpdateMode handsToDraw allDamage | submorphs do: [:m | m fullBounds]. "force re-layout if needed" self checkIfUpdateNeeded ifFalse: [^ self]. "display is already up-to-date" deferredUpdateMode := self doDeferredUpdatingFor: aWorld. deferredUpdateMode ifFalse: [self assuredCanvas]. - canvas roundCornersOf: aWorld during:[ | handDamageRects worldDamageRects | - worldDamageRects := self drawWorld: aWorld submorphs: submorphs invalidAreasOn: canvas. "repair world's damage on canvas" - "self handsDo:[:h| h noticeDamageRects: worldDamageRects]." - handsToDraw := self selectHandsToDrawForDamage: worldDamageRects. - handDamageRects := handsToDraw collect: [:h | h savePatchFrom: canvas]. - allDamage := worldDamageRects, handDamageRects. + worldDamageRects := self drawWorld: aWorld submorphs: submorphs invalidAreasOn: canvas. "repair world's damage on canvas" + "self handsDo:[:h| h noticeDamageRects: worldDamageRects]." + handsToDraw := self selectHandsToDrawForDamage: worldDamageRects. + handDamageRects := handsToDraw collect: [:h | h savePatchFrom: canvas]. + allDamage := worldDamageRects, handDamageRects. + + handsToDraw reverseDo: [:h | canvas fullDrawMorph: h]. "draw hands onto world canvas" + - handsToDraw reverseDo: [:h | canvas fullDrawMorph: h]. "draw hands onto world canvas" - ]. "*make this true to flash damaged areas for testing*" Preferences debugShowDamage ifTrue: [aWorld flashRects: allDamage color: Color black]. canvas finish: allDamage. "quickly copy altered rects of canvas to Display:" deferredUpdateMode ifTrue: [self forceDamageToScreen: allDamage] ifFalse: [canvas showAt: aWorld viewBox origin invalidRects: allDamage]. handsToDraw do: [:h | h restoreSavedPatchOn: canvas]. "restore world canvas under hands" Display deferUpdates: false; forceDisplayUpdate. ! |
Free forum by Nabble | Edit this page |