diff --git a/src/Pyramid-Bloc/PyramidElementsManipulationHelper.class.st b/src/Pyramid-Bloc/PyramidElementsManipulationHelper.class.st new file mode 100644 index 00000000..9f604d73 --- /dev/null +++ b/src/Pyramid-Bloc/PyramidElementsManipulationHelper.class.st @@ -0,0 +1,79 @@ +Class { + #name : #PyramidElementsManipulationHelper, + #superclass : #Object, + #category : #'Pyramid-Bloc-utils' +} + +{ #category : #'as yet unclassified' } +PyramidElementsManipulationHelper class >> accumulateChildrenOf: aBlElement in: aCollection [ + + aCollection add: aBlElement. + aBlElement childrenDo: [ :each | + self accumulateChildrenOf: each in: aCollection ] +] + +{ #category : #'as yet unclassified' } +PyramidElementsManipulationHelper class >> accumulateParentsOf: aCollectionOfBlElement in: result [ + + | elementToTest onCollection nextCollection shouldKeepIt | + shouldKeepIt := true. + aCollectionOfBlElement isEmpty ifTrue: [ ^ self ]. + aCollectionOfBlElement size = 1 ifTrue: [ + result add: aCollectionOfBlElement first. + ^ self ]. + + elementToTest := aCollectionOfBlElement first. + onCollection := aCollectionOfBlElement allButFirst. + nextCollection := OrderedCollection new. + + onCollection do: [ :each | + (each hasParent: elementToTest) ifFalse: [ + nextCollection add: each ]. + (shouldKeepIt and: [ elementToTest hasParent: each ]) ifTrue: [ + shouldKeepIt := false ] ]. + shouldKeepIt ifTrue: [ result add: elementToTest ]. + self accumulateParentsOf: nextCollection in: result +] + +{ #category : #'as yet unclassified' } +PyramidElementsManipulationHelper class >> flattenChildrenOfCollection: aCollection [ +"Consider: +A1->A2-A3. +B1->B2->B3. + +col := { A1 . B2 } + +PyramidElementsManipulationHelper flattenChildrenOfCollection: col +returns +{ A1 . A2 . A3 . B2 . B3 } +" + + | ret | + ret := OrderedCollection new. + aCollection do: [ :each | self accumulateChildrenOf: each in: ret ]. + ^ ret +] + +{ #category : #'as yet unclassified' } +PyramidElementsManipulationHelper class >> onlyParents: aCollectionOfBlElement [ + "return a collection whithout any parent-child relation. + Example: + consider this as all elements + A1->A2->A3 + B1->B2->B3. + C1->C2->C3. + D1->D2->D3. + + selection := {A1 . B1 . B2 . C1 . C3}. + PyramidElementsManipulationHelper onlyParents: selection + returns: { A1 . B1 . C1 } + " + + | result | + aCollectionOfBlElement isEmpty ifTrue: [ ^ { } ]. + aCollectionOfBlElement size = 1 ifTrue: [ + ^ { aCollectionOfBlElement first } ]. + result := OrderedCollection new. + self accumulateParentsOf: aCollectionOfBlElement in: result. + ^ result asArray +] diff --git a/src/Pyramid-Bloc/PyramidElementsManipulationHelperTest.class.st b/src/Pyramid-Bloc/PyramidElementsManipulationHelperTest.class.st new file mode 100644 index 00000000..4db331ec --- /dev/null +++ b/src/Pyramid-Bloc/PyramidElementsManipulationHelperTest.class.st @@ -0,0 +1,80 @@ +Class { + #name : #PyramidElementsManipulationHelperTest, + #superclass : #TestCase, + #category : #'Pyramid-Bloc-utils' +} + +{ #category : #'as yet unclassified' } +PyramidElementsManipulationHelperTest >> arrayOf3Elements [ + + | e1 e2 e3| + e1 := BlElement new. + e2 := BlElement new. + e3 := BlElement new. + + e1 addChild: e2. + e2 addChild: e3. + ^ { e1 . e2 . e3 } +] + +{ #category : #'as yet unclassified' } +PyramidElementsManipulationHelperTest >> arrayOfElements [ + +" +A1 -> A2 -> A3. +B1 -> B2 -> B3. +C1 -> C2 -> C3. +D1 -> D2 -> D3. +" + + |arrayA arrayB arrayC arrayD| + + arrayA := self arrayOf3Elements. + arrayB := self arrayOf3Elements. + arrayC := self arrayOf3Elements. + arrayD := self arrayOf3Elements. + +^ { arrayA. arrayB. arrayC. arrayD } + +] + +{ #category : #tests } +PyramidElementsManipulationHelperTest >> testFlattenChildrenOfCollection [ + + | arrayOfElements test result | + arrayOfElements := self arrayOfElements. + test := { + (arrayOfElements at: 1) first. + (arrayOfElements at: 2) first firstChild }. + result := PyramidElementsManipulationHelper + flattenChildrenOfCollection: test. + self assert: result size equals: 5. + self assert: (result includesAll: { + (arrayOfElements at: 1) first. + (arrayOfElements at: 1) first firstChild. + (arrayOfElements at: 1) first firstChild firstChild. + (arrayOfElements at: 2) first firstChild. + (arrayOfElements at: 2) first firstChild firstChild }) +] + +{ #category : #tests } +PyramidElementsManipulationHelperTest >> testOnlyParents [ + "selection := {A1 . B1 . B2 . C1 . C3}. + PyramidElementsManipulationHelper onlyParents: selection + returns: { A1 . B1 . C1 }" + + | arrayOfElements test result | + arrayOfElements := self arrayOfElements. + test := { + (arrayOfElements at: 1) first. + (arrayOfElements at: 2) first. + (arrayOfElements at: 2) first firstChild. + (arrayOfElements at: 3) first. + (arrayOfElements at: 3) first firstChild firstChild }. + result := PyramidElementsManipulationHelper onlyParents: test. + self assert: result size equals: 3. + self assert: (result includesAll: { + (arrayOfElements at: 1) first. + (arrayOfElements at: 2) first . + (arrayOfElements at: 3) first}) +] diff --git a/src/Pyramid-Bloc/PyramidLogo.class.st b/src/Pyramid-Bloc/PyramidLogo.class.st index f9ae2c86..c294c7c5 100644 --- a/src/Pyramid-Bloc/PyramidLogo.class.st +++ b/src/Pyramid-Bloc/PyramidLogo.class.st @@ -9,7 +9,7 @@ PyramidLogo class >> logoMedium [ "This class has been generated using Pyramid. By: YannLEGOFF - 2023-07-31 13:44:18" + 2023-08-07 13:52:07" ^ '[ @@ -43,7 +43,13 @@ PyramidLogo class >> logoMedium [ #geometry : BlPolygonGeometry { #extent : Point [ 50.0, 50.0 ], #pathCache : BlPathCache { - #geometry : @12 + #geometry : @12, + #strokedBounds : BlBounds { + #left : -0.5, + #top : -0.5, + #right : 30.5, + #bottom : 60.5 + } }, #vertices : [ Point [ 0.0, 34.0 ], @@ -82,11 +88,7 @@ PyramidLogo class >> logoMedium [ #identifier : #C } }, - #layout : BlBasicLayout { }, - #eventDispatcher : BlElementEventDispatcher { - #owner : @2, - #handlers : [ ] - } + #layout : BlBasicLayout { } }, BlElement { #children : BlChildrenArray [ ], @@ -111,7 +113,13 @@ PyramidLogo class >> logoMedium [ #geometry : BlPolygonGeometry { #extent : Point [ 50.0, 50.0 ], #pathCache : BlPathCache { - #geometry : @42 + #geometry : @41, + #strokedBounds : BlBounds { + #left : 29.5, + #top : -0.5, + #right : 70.5, + #bottom : 60.5 + } }, #vertices : [ Point [ 70.0, 30.0 ], @@ -121,14 +129,14 @@ PyramidLogo class >> logoMedium [ }, #border : BlBorder { #paint : BlColorPaint { - #color : @21 + #color : @22 }, #width : 1, #style : BlStrokeStyle { - #lineCap : @23, - #lineJoin : @24, + #lineCap : @24, + #lineJoin : @25, #miterLimit : 4.0, - #dashArray : @25, + #dashArray : @26, #dashOffset : 0.0 }, #opacity : 1.0 @@ -138,18 +146,14 @@ PyramidLogo class >> logoMedium [ #color : Color [ #white ] } }, - #outskirts : @29 + #outskirts : @30 }, #userData : IdentityDictionary { #elementId : BlElementNamedId { #identifier : #D } }, - #layout : @32, - #eventDispatcher : BlElementEventDispatcher { - #owner : @35, - #handlers : [ ] - } + #layout : @33 } ]' ] diff --git a/src/Pyramid-Bloc/PyramidSearchAndSelectPresenter.class.st b/src/Pyramid-Bloc/PyramidSearchAndSelectPresenter.class.st index a3d0a5f5..b2debdf7 100644 --- a/src/Pyramid-Bloc/PyramidSearchAndSelectPresenter.class.st +++ b/src/Pyramid-Bloc/PyramidSearchAndSelectPresenter.class.st @@ -67,7 +67,7 @@ PyramidSearchAndSelectPresenter >> codeIsForAll [ self projectModel ifNil: [ ^ self ]. self codePresenter interactionModel: (SpCodeObjectInteractionModel on: - (PyramidTreeToFlat flattenChildrenOfCollection: + (PyramidElementsManipulationHelper flattenChildrenOfCollection: self projectModel roots)) ] diff --git a/src/Pyramid-Bloc/PyramidSelectionWidgetBorderBuilder.class.st b/src/Pyramid-Bloc/PyramidSelectionWidgetBorderBuilder.class.st new file mode 100644 index 00000000..9c015116 --- /dev/null +++ b/src/Pyramid-Bloc/PyramidSelectionWidgetBorderBuilder.class.st @@ -0,0 +1,177 @@ +Class { + #name : #PyramidSelectionWidgetBorderBuilder, + #superclass : #Object, + #category : #'Pyramid-Bloc-plugin-space-extensions' +} + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> borderElementWithMainColor: aMainColor andSecondaryColor: aSecondaryColor [ + + ^ BlElement new + clipChildren: false; + background: aMainColor; + border: (BlBorderBuilder new + dashArray: self defaultDashArray; + width: self defaultWidth; + paint: aSecondaryColor) build; + yourself +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> bottomChild [ + + ^ (self borderElementWithMainColor: self mainOtherColor andSecondaryColor: self secondaryOtherColor) + constraintsDo: [ :c | + c vertical exact: self defaultWidth. + c horizontal matchParent. + c frame vertical alignBottom ] +] + +{ #category : #building } +PyramidSelectionWidgetBorderBuilder >> build [ + + ^ BlElement new + id: #borders; + clipChildren: false; + constraintsDo: [ :c | + c vertical matchParent. + c horizontal matchParent ]; + layout: BlFrameLayout new; + addChild: self topChild; + addChild: self leftChild; + addChild: self bottomChild; + addChild: self rightChild; + yourself +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> defaultDashArray [ + + ^ #( 3 7 ) +] + +{ #category : #accessing } +PyramidSelectionWidgetBorderBuilder >> defaultWidth [ + + ^ 2 +] + +{ #category : #'user interface' } +PyramidSelectionWidgetBorderBuilder >> labelWithColor: aColor [. + + ^ BlTextElement new + background: aColor; + geometry: (BlRoundedRectangleGeometry cornerRadius: 8); + padding: (BlInsets all: 2); + text: '' asRopedText ; + yourself +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> leftChild [ + + | leftChild | + leftChild := (self + borderElementWithMainColor: self mainLeftColor + andSecondaryColor: self secondaryLeftColor). + leftChild + constraintsDo: [ :c | + c horizontal exact: self defaultWidth. + c vertical matchParent. + c frame horizontal alignLeft ]. + leftChild addChild: (self leftLabelFor: leftChild). + ^ leftChild +] + +{ #category : #'user interface' } +PyramidSelectionWidgetBorderBuilder >> leftLabelFor: aBlElement [ + + | label | + label := self labelWithColor: self mainLeftColor. + label transformDo: [ :t | t rotateBy: -90 ]. + + aBlElement when: BlElementExtentChangedEvent do: [ :evt | + label text: (aBlElement height < 50 + ifTrue: [ '' asRopedText ] + ifFalse: [ aBlElement height printString asRopedText ]). + label requestLayout. + label position: -22 @ (aBlElement height - 20 / 2) ]. + ^ label +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> mainLeftColor [ + + ^ Color green +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> mainOtherColor [ + + ^ Color yellow +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> mainTopColor [ + + ^ Color red +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> rightChild [ + + ^ (self borderElementWithMainColor: self mainOtherColor andSecondaryColor: self secondaryOtherColor) + constraintsDo: [ :c | + c horizontal exact: self defaultWidth. + c vertical matchParent. + c frame horizontal alignRight ] +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> secondaryLeftColor [ + + ^ self mainLeftColor muchDarker +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> secondaryOtherColor [ + + ^ self mainOtherColor muchDarker +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> secondaryTopColor [ + + ^ self mainTopColor muchDarker +] + +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetBorderBuilder >> topChild [ + + | topChild | + topChild := self + borderElementWithMainColor: self mainTopColor + andSecondaryColor: self secondaryTopColor. + topChild + constraintsDo: [ :c | + c vertical exact: self defaultWidth. + c horizontal matchParent. + c frame vertical alignTop ]. + topChild addChild: (self topLabelFor: topChild). + ^ topChild +] + +{ #category : #'user interface' } +PyramidSelectionWidgetBorderBuilder >> topLabelFor: aBlElement [ + + | label | + label := self labelWithColor: self mainTopColor. + + aBlElement when: BlElementExtentChangedEvent do: [ :evt | + label text: (aBlElement width < 50 + ifTrue: [ '' asRopedText ] + ifFalse: [ aBlElement width printString asRopedText ]). + label requestLayout. + label position: aBlElement width - 20 / 2 @ -13 ]. + ^ label +] diff --git a/src/Pyramid-Bloc/PyramidSelectionWidgetExtension.class.st b/src/Pyramid-Bloc/PyramidSelectionWidgetExtension.class.st index ff17a378..3dc00391 100644 --- a/src/Pyramid-Bloc/PyramidSelectionWidgetExtension.class.st +++ b/src/Pyramid-Bloc/PyramidSelectionWidgetExtension.class.st @@ -26,6 +26,10 @@ PyramidSelectionWidgetExtension >> centerDragEnd: anEvent [ self isDragging: false. self usePositionOffsetCommand: anEvent position - self dragOrigin. self widgetElement transformDo: [ :t | t translateBy: 0 @ 0 ]. + self widgetElement childrenDo: [ :child | + child + childNamed: #drag_ghost + ifFound: [ :ghost | ghost visibility: BlVisibility hidden ] ] ] { #category : #'as yet unclassified' } @@ -45,7 +49,8 @@ PyramidSelectionWidgetExtension >> centerDragStart: anEvent [ self isDragging: true. self dragOrigin: anEvent position. - anEvent consumed: true + anEvent consumed: true. + self widgetElement childrenDo: [ :child | child childNamed: #drag_ghost ifFound: [ :ghost | ghost visibility: BlVisibility visible ] ] ] { #category : #accessing } @@ -118,50 +123,45 @@ PyramidSelectionWidgetExtension >> isDragging: anObject [ { #category : #'as yet unclassified' } PyramidSelectionWidgetExtension >> makeMonoSelectionFor: aBlElement [ - | monoSelection formElement | - aBlElement requestParentLayout. - aBlElement computeLayout. - - formElement := (aBlElement exportAsForm collectColors: [ :color | - | l | - l := color luminance. - Color - r: color red - g: color green - b: color blue - alpha: (color alpha min: self alphaFactor) ]) - asElement. - - monoSelection := BlElement new - border: (BlBorderBuilder new - width: 1; - paint: Color black; - build); - size: aBlElement size + (self offset * 2) asPoint; - position: aBlElement position - self offset asPoint; - yourself. - monoSelection addChild: (formElement - position: self offset asPoint; - yourself). - - formElement - when: BlPrimaryMouseDownEvent - do: [ :evt | self centerDragStart: evt ]. - formElement - when: BlMouseEvent - do: [ :evt | self centerDragEvent: evt ]. - formElement - when: BlPrimaryMouseUpEvent - do: [ :evt | self centerDragEnd: evt ]. - + | monoSelection eventElement dragGhostElement borderElement | + monoSelection := BlOverlayElement on: aBlElement. + monoSelection clipChildren: false. + + dragGhostElement := BlElement new + id: #drag_ghost; + visibility: BlVisibility hidden; + background: + (aBlElement exportAsForm dimmed: 0.5); + constraintsDo: [ :c | + c vertical matchParent. + c horizontal matchParent ]; + yourself. + eventElement := BlElement new + id: #drag_event; + constraintsDo: [ :c | + c vertical matchParent. + c horizontal matchParent ]; + zIndex: 100; + when: BlPrimaryMouseDownEvent + do: [ :evt | self centerDragStart: evt ]; + when: BlMouseEvent + do: [ :evt | self centerDragEvent: evt ]; + when: BlPrimaryMouseUpEvent + do: [ :evt | self centerDragEnd: evt ]; + yourself. + borderElement := PyramidSelectionWidgetBorderBuilder new build. + + monoSelection addChild: dragGhostElement. + monoSelection addChild: borderElement. + monoSelection addChild: eventElement. ^ monoSelection ] { #category : #removing } PyramidSelectionWidgetExtension >> makeNewSelection [ - self projectModel selection do: [ :each | - self widgetElement addChild: (self makeMonoSelectionFor: each) ] + self projectModel selection do: [ :each | self widgetElement addChild: + (self makeMonoSelectionFor: each) ] ] { #category : #'as yet unclassified' } @@ -183,11 +183,18 @@ PyramidSelectionWidgetExtension >> projectModel: aProjectModel [ self makeNewSelection. ] +{ #category : #'as yet unclassified' } +PyramidSelectionWidgetExtension >> pyramidElementsChanged [ + + self removeSelection. + self makeNewSelection +] + { #category : #'as yet unclassified' } PyramidSelectionWidgetExtension >> pyramidSelectionChanged [ self removeSelection. - self makeNewSelection. + self makeNewSelection ] { #category : #removing } @@ -201,7 +208,7 @@ PyramidSelectionWidgetExtension >> usePositionOffsetCommand: aPosition [ self commandExecutor use: PyramidPositionOffsetCommand new - on: self projectModel selection asArray + on: (PyramidElementsManipulationHelper onlyParents: self projectModel selection asArray) with: aPosition ] diff --git a/src/Pyramid-Bloc/PyramidTreeToFlat.class.st b/src/Pyramid-Bloc/PyramidTreeToFlat.class.st deleted file mode 100644 index ce4ab30e..00000000 --- a/src/Pyramid-Bloc/PyramidTreeToFlat.class.st +++ /dev/null @@ -1,23 +0,0 @@ -Class { - #name : #PyramidTreeToFlat, - #superclass : #Object, - #category : #'Pyramid-Bloc-utils' -} - -{ #category : #'as yet unclassified' } -PyramidTreeToFlat class >> accumulateChildrenOf: aBlElement in: aCollection [ - - aCollection add: aBlElement. - aBlElement childrenDo: [ :each | - self accumulateChildrenOf: each in: aCollection ] -] - -{ #category : #'as yet unclassified' } -PyramidTreeToFlat class >> flattenChildrenOfCollection: aCollection [ - - | ret | - ret := OrderedCollection new. - aCollection do: [ :each | - self accumulateChildrenOf: each in: ret ]. - ^ ret -] diff --git a/src/Pyramid/PyramidProjectModel.class.st b/src/Pyramid/PyramidProjectModel.class.st index 36275a80..ef8ee8b2 100644 --- a/src/Pyramid/PyramidProjectModel.class.st +++ b/src/Pyramid/PyramidProjectModel.class.st @@ -13,7 +13,7 @@ Class { { #category : #accessing } PyramidProjectModel >> allElements [ - ^ PyramidTreeToFlat flattenChildrenOfCollection: + ^ PyramidElementsManipulationHelper flattenChildrenOfCollection: self roots. ]