diff --git a/source/GM-TE/GMTEEditorTileMap.class.st b/source/GM-TE/GMTEEditorTileMap.class.st index 430f16ec..e5d34777 100644 --- a/source/GM-TE/GMTEEditorTileMap.class.st +++ b/source/GM-TE/GMTEEditorTileMap.class.st @@ -91,7 +91,7 @@ GMTEEditorTileMap >> handlesMouseOver: anEvent [ { #category : #initialization, - #'squeak_changestamp' : 'Alex M 6/28/2024 20:24' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:04' } GMTEEditorTileMap >> initialize [ @@ -99,7 +99,8 @@ GMTEEditorTileMap >> initialize [ self tileSelectionSet: (GMTETileSelectionSet new); previousTileStates: Dictionary new; - currentTileChanges: Dictionary new + currentTileChanges: Dictionary new; + hasStaticView: false ] { @@ -151,12 +152,15 @@ GMTEEditorTileMap >> mouseLeave: anEvent [ { #category : #'event handling', - #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 17:01' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:52' } GMTEEditorTileMap >> mouseMove: anEvent [ "Implements highlighting of tiles when hovering" | hoveredTileHighlighting activeLayer selectedCoordinates | + super mouseMove: anEvent. + anEvent shiftPressed ifTrue: [^ nil]. + self model singleLayerSelected ifFalse: [^ nil]. activeLayer := self model selectedLayers anyOne. diff --git a/source/GM-TE/GMTETileMap.class.st b/source/GM-TE/GMTETileMap.class.st index 11ad8354..53e504d6 100644 --- a/source/GM-TE/GMTETileMap.class.st +++ b/source/GM-TE/GMTETileMap.class.st @@ -27,7 +27,8 @@ Class { 'tileMatrixStackBackground', 'forceMapSizeRatio', 'backgroundTiles', - 'view' + 'view', + 'hasStaticView' ], #category : #'GM-TE-TileMap' } @@ -55,7 +56,7 @@ GMTETileMap class >> maxLayers [ { #category : #'as yet unclassified', - #'squeak_changestamp' : 'Ivo Zilkenat 7/2/2024 18:05' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:15' } GMTETileMap class >> newFromEditableTileMap: aMap [ @@ -76,6 +77,10 @@ GMTETileMap class >> newFromEditableTileMap: aMap [ "Initially draw background tiles" newMap updateTilesBackground. + newMap resetView. + self flag: 'dragging does not work properly when openedInWorld'. + newMap hasStaticView: false. + ^ newMap ] @@ -213,15 +218,54 @@ GMTETileMap >> borderTileWidth: anObject [ { #category : #view, - #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 00:08' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 15:59' +} +GMTETileMap >> canZoomIn [ + + ^ false +] + +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:04' +} +GMTETileMap >> canZoomInBy: aFloat [ + + ^ self view canChangeSizeBy: (aFloat negated) +] + +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:04' +} +GMTETileMap >> canZoomOutBy: aFloat [ + + ^ self view canChangeSizeBy: aFloat +] + +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 20:46' } GMTETileMap >> centerViewAt: aPoint [ + "Note: aPoint is relative to current view" "Note: center must induce legal view (non-overlapping)" self view moveTo: (self inViewPointToViewCenter: aPoint). self updateMap ] +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 22:31' +} +GMTETileMap >> centerViewAtAbs: aPoint [ + "Note: center must induce legal view (non-overlapping)" + + self view moveTo: (self absPointToViewCenter: aPoint). + self updateMap +] + { #category : #conversion, #'squeak_changestamp' : 'Ivo Zilkenat 6/24/2024 11:09' @@ -479,6 +523,42 @@ GMTETileMap >> getTileFromLayer: aLayer x: x y: y stack: aStack [ +] + +{ + #category : #'event handling', + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:16' +} +GMTETileMap >> handlesMouseMove: anEvent [ + + ^ true +] + +{ + #category : #'event handling', + #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 21:12' +} +GMTETileMap >> handlesMouseWheel: anEvent [ + + ^ true +] + +{ + #category : #accessing, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:04' +} +GMTETileMap >> hasStaticView [ + + ^ hasStaticView +] + +{ + #category : #accessing, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:04' +} +GMTETileMap >> hasStaticView: anObject [ + + hasStaticView := anObject. ] { @@ -535,7 +615,7 @@ GMTETileMap >> inViewPointToViewFraction: aPoint [ { #category : #initialization, - #'squeak_changestamp' : 'Ivo Zilkenat 7/10/2024 18:15' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:04' } GMTETileMap >> initialize [ @@ -545,6 +625,7 @@ GMTETileMap >> initialize [ clipSubmorphs: true; forceMapSizeRatio: false; view: GMTEView new; + hasStaticView: true; "TODO: spike solution. Size 1@1 sets quadratic base image. Generic resizing not working yet" "TODO: default background tiles (must not exist but practical as a visual indicator)" @@ -691,6 +772,45 @@ GMTETileMap >> mapTileWidth: anObject [ mapTileWidth := anObject ] +{ + #category : #'event handling', + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:05' +} +GMTETileMap >> mouseMove: anEvent [ + + self hasStaticView ifTrue: [^ nil]. + anEvent shiftPressed ifFalse: [^ nil]. + anEvent redButtonPressed ifFalse: [^ nil]. + + self moveViewBy: (anEvent startPoint - anEvent position) +] + +{ + #category : #'event handling', + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:05' +} +GMTETileMap >> mouseWheel: anEvent [ + + self flag: 'does not work'. + "anEvent shiftPressed ifFalse: [^ nil]." + + self hasStaticView ifTrue: [^ nil]. + anEvent isWheelDown ifTrue: [self zoomInAt: (anEvent position - self topLeft)]. + anEvent isWheelUp ifTrue: [self zoomOutAt: (anEvent position - self topLeft)] +] + +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:50' +} +GMTETileMap >> moveViewBy: aPoint [ + "Note: aPoint is relative to current view" + "Note: center must induce legal view (non-overlapping)" + + self view moveBy: (self absPointToViewFraction: (aPoint / self viewScaleFactor)). + self updateMap +] + { #category : #updating, #'squeak_changestamp' : 'Ivo Zilkenat 6/24/2024 11:27' @@ -1320,10 +1440,42 @@ GMTETileMap >> vigenerateBackgroundTiles [ { #category : #view, - #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 00:33' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 17:10' +} +GMTETileMap >> zoomAt: aPoint by: aFloat [ + "" + + | newCenter oldMouseCenterOffset aPointAbs oldScaleFactor | + + oldScaleFactor := self viewScaleFactor. + aPointAbs := self inViewPointToAbs: aPoint. + oldMouseCenterOffset := (self inViewPointToAbs: (self extent / 2)) - aPointAbs. + + self view changeSizeBy: (aFloat negated). + + newCenter := (oldScaleFactor / self viewScaleFactor) * oldMouseCenterOffset + aPointAbs. + self centerViewAtAbs: newCenter. + + self flag: 'refactor. This seems to be necessary but highlights only exist for editable tile map'. + "self tileSelectionSet clearAllHighlightings" +] + +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:05' } GMTETileMap >> zoomInAt: aPoint [ - self view shrinkBy: 0.1. - self centerViewAt: aPoint + (self canZoomInBy: 0.1) ifFalse: [^ nil]. + self zoomAt: aPoint by: 0.1 +] + +{ + #category : #view, + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:05' +} +GMTETileMap >> zoomOutAt: aPoint [ + + (self canZoomOutBy: 0.1) ifFalse: [^ nil]. + self zoomAt: aPoint by: -0.1 ] diff --git a/source/GM-TE/GMTEView.class.st b/source/GM-TE/GMTEView.class.st index 9d55a807..de30ac68 100644 --- a/source/GM-TE/GMTEView.class.st +++ b/source/GM-TE/GMTEView.class.st @@ -6,15 +6,30 @@ Class { { #category : #'as yet unclassified', - #'squeak_changestamp' : 'Ivo Zilkenat 7/10/2024 18:17' + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:06' } -GMTEView >> enlargeBy: aFloat [ +GMTEView >> canChangeSizeBy: aFloat [ + + | newExtent | + newExtent := (self extent + (aFloat@aFloat)). + + ((newExtent x <= 0.1) or: [newExtent y <= 0.1]) ifTrue: [^ false]. + ((newExtent x > 1) or: [newExtent y > 1]) ifTrue: [^ false]. + ^ true + +] + +{ + #category : #'as yet unclassified', + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:01' +} +GMTEView >> changeSizeBy: aFloat [ | newExtent | newExtent := (self extent + (aFloat@aFloat)). self flag: 'magic number'. - ((newExtent x > 1) or: [newExtent y > 1]) ifTrue: [^ nil]. + (self canChangeSizeBy: aFloat) ifFalse: [^ nil]. (self isOverlappingOrigin: self origin withExtent: newExtent) ifTrue: [^ nil]. self extent: newExtent @@ -45,13 +60,32 @@ GMTEView >> initialize [ { #category : #'as yet unclassified', - #'squeak_changestamp' : 'Ivo Zilkenat 7/10/2024 18:05' + #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 22:43' } GMTEView >> isOverlappingOrigin: anOrigin withExtent: anExtent [ | corner | corner := anOrigin + anExtent. - ^ (corner x > 1) or: [corner y > 1] + + self flag: 'tmp for testing'. + ^ false. + + "^ (((corner x > 1) or: [corner y > 1]) or: [anOrigin x < 0]) or: [anOrigin y < 0]" +] + +{ + #category : #'as yet unclassified', + #'squeak_changestamp' : 'Ivo Zilkenat 7/12/2024 16:41' +} +GMTEView >> moveBy: aPoint [ + "Set origin but also respect view not overlapping reference view" + + | newOrigin | + newOrigin := self origin + aPoint. + + (self isOverlappingOrigin: newOrigin withExtent: self extent) ifTrue: [^ nil]. + + self origin: newOrigin ] { @@ -68,11 +102,11 @@ GMTEView >> moveTo: anOrigin [ { #category : #'as yet unclassified', - #'squeak_changestamp' : 'Ivo Zilkenat 7/10/2024 18:33' + #'squeak_changestamp' : 'Ivo Zilkenat 7/11/2024 20:35' } GMTEView >> origin: aPoint [ - self setOrigin: aPoint corner: (aPoint + self corner) + self setOrigin: aPoint corner: (aPoint + (self corner - self origin)) ] { @@ -85,21 +119,6 @@ GMTEView >> reset [ ] -{ - #category : #'as yet unclassified', - #'squeak_changestamp' : 'Ivo Zilkenat 7/10/2024 18:16' -} -GMTEView >> shrinkBy: aFloat [ - - | newExtent | - newExtent := (self extent - (aFloat@aFloat)). - - self flag: 'magic number'. - ((newExtent x <= 0.1) or: [newExtent y <= 0.1]) ifTrue: [^ nil]. - - self extent: newExtent -] - { #category : #'as yet unclassified', #'squeak_changestamp' : 'Ivo Zilkenat 7/10/2024 22:53'