Skip to content

Commit fb06f77

Browse files
committed
ToAnnulusCircularLayoutConstraints have now a measurer that use a strategy to compute the sector angle from the chord or the arc
1 parent bacb9f0 commit fb06f77

11 files changed

+279
-81
lines changed

src/Toplo-Examples/ToSandBox.class.st

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,7 +1808,6 @@ ToSandBox class >> example_CircularMenuItemList [
18081808
space root layout: BlFrameLayout new.
18091809

18101810
rootMenu := ToCircularMenuList new.
1811-
rootMenu uniformSectors: true.
18121811
rootMenu addItem: (ToMenuItem new
18131812
labelText: 'X1';
18141813
yourself).
@@ -1834,7 +1833,6 @@ ToSandBox class >> example_CircularMenuItemListWithSubmenu [
18341833
space root layout: BlFrameLayout new.
18351834

18361835
rootMenu := ToCircularMenuList new.
1837-
rootMenu uniformSectors: true.
18381836
rootMenu addItem: (ToMenuItem new
18391837
labelText: 'X1';
18401838
yourself).
@@ -1852,7 +1850,7 @@ ToSandBox class >> example_CircularMenuItemListWithSubmenu [
18521850

18531851
subMenu := ToCircularMenuList new.
18541852
subMenu innerRadialRatio: 0.5.
1855-
subMenu uniformSectors: false.
1853+
18561854
subMenu addItem: (ToMenuItem new
18571855
labelText: 'XX1';
18581856
yourself).
@@ -1877,37 +1875,40 @@ ToSandBox class >> example_CircularMenuPane [
18771875
iconProvider := ToMaterialDesignIconProvider.
18781876
circularMenu := ToCircularMenuPane new.
18791877
circularMenu layoutRadius: 150.
1880-
"circularMenu startAngleOffset: 45."
1878+
18811879
circularMenu innerRadialRatio: 0.1.
18821880
circularMenu outerRadialRatio: 0.95.
18831881

18841882
item := ToCircularMenu new icon:
18851883
(iconProvider iconNamed: 'filled_checklist').
1886-
item uniformSectors: false.
1884+
18871885
item encompassing: true.
18881886
item layoutRadius: 80.
1887+
18891888
sub := ToMenuItem new labelText: 'Sub 1'.
18901889
item addItem: sub.
1890+
sub constraints annulus sectorAngleInDegrees: 40.
18911891

18921892
sub := ToCircularMenu new labelText: 'Sub 2'.
1893-
sub uniformSectors: false.
1894-
sub layoutRadius: 30.
1893+
sub layoutRadius: 40.
1894+
item addItem: sub.
1895+
sub constraints annulus sectorAngleInDegrees: 40.
1896+
18951897
subsub := ToMenuItem new labelText: 'X1'.
1896-
subsub constraints annulus angleGap: 10.
1898+
subsub constraints annulus sectorAngleInDegrees: 10.
18971899
sub addItem: subsub.
18981900
subsub := ToMenuItem new labelText: 'X2'.
1899-
subsub constraints annulus angleGap: 10.
1901+
subsub constraints annulus sectorChordLength: 50.
19001902
sub addItem: subsub.
19011903
subsub := ToMenuItem new labelText: 'X3'.
1902-
subsub constraints annulus angleGap: 10.
1904+
subsub constraints annulus sectorArcLength: 100.
19031905
sub addItem: subsub.
19041906

1905-
item addItem: sub.
19061907
circularMenu addItem: item.
1907-
19081908
item := ToCircularMenu new icon:
19091909
(iconProvider iconNamed: 'outlined_morehoriz').
19101910
item layoutRadius: 70.
1911+
19111912
sub := ToMenuItem new labelText: 'SubMenu 1'.
19121913
item addItem: sub.
19131914
sub := ToMenuItem new labelText: 'SubMenu 2'.

src/Toplo-Widget-Circular/TToAnnulusCircularLayoutUser.trait.st

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,3 @@ TToAnnulusCircularLayoutUser >> startAngleOffset: anAngleInDgrees [
5353

5454
self stateHolder startAngleOffset: anAngleInDgrees
5555
]
56-
57-
{ #category : #'t - annulus circular layout user' }
58-
TToAnnulusCircularLayoutUser >> uniformSectors [
59-
60-
^ self stateHolder uniformSectors
61-
]
62-
63-
{ #category : #'t - annulus circular layout user' }
64-
TToAnnulusCircularLayoutUser >> uniformSectors: aBoolean [
65-
66-
self uniformSectors = aBoolean ifTrue: [ ^ self ].
67-
self stateHolder uniformSectors: aBoolean.
68-
self requestLayout
69-
]

src/Toplo-Widget-Circular/ToAnnulusCircularLayout.class.st

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ Class {
33
#superclass : #BlBasicLayout,
44
#traits : 'TToAnnulusSectorLayoutState',
55
#classTraits : 'TToAnnulusSectorLayoutState classTrait',
6-
#instVars : [
7-
'uniformSectors'
8-
],
96
#category : #'Toplo-Widget-Circular-Annulus'
107
}
118

@@ -59,38 +56,50 @@ ToAnnulusCircularLayout >> centroidOf: anElement in: aContainer [
5956
{ #category : #layout }
6057
ToAnnulusCircularLayout >> layout: anElement in: aBounds context: aBlElementBoundsUpdateContext [
6158

62-
| radius angleGap angleDeg |
63-
anElement children isEmpty ifTrue: [ ^ self ].
64-
65-
radius := self innerRadialRatio + self outerRadialRatio / 2.
66-
angleGap := 360 / anElement children size.
67-
angleDeg := self startAngle + self startAngleOffset.
68-
69-
anElement childrenDo: [ :each |
70-
| centroid edgePoint pointFromCenter |
59+
| radius defaultGap sectorStartAngle remainder sectors numberWithGap |
60+
sectors := anElement children accountedByLayout.
61+
sectors isEmpty ifTrue: [ ^ self ].
62+
63+
radius := aBounds extent x / 2.
64+
remainder := 360.
65+
numberWithGap := 0.
66+
sectors do: [ :each |
67+
(each constraints annulus sectorAngleInDegreesWithRadius: radius)
68+
ifNotNil: [ :gap |
69+
remainder := remainder - gap min: 0.
70+
numberWithGap := numberWithGap + 1 ] ].
71+
72+
defaultGap := numberWithGap < sectors size
73+
ifTrue: [ remainder / (sectors size - numberWithGap) ]
74+
ifFalse: [ 0 ].
75+
sectorStartAngle := self startAngle + self startAngleOffset.
76+
77+
sectors do: [ :each |
78+
| centroid edgePoint pointFromCenter sectorGap |
7179
centroid := self centroidOf: each in: anElement.
7280
edgePoint := self
73-
pointOnPeripheryFromCenter:
74-
anElement measuredBounds center
81+
pointOnPeripheryFromCenter: aBounds center
7582
through: centroid
7683
in: anElement.
7784

7885
each constraints annulusSector centroid: centroid.
7986
each constraints annulusSector edgePoint: edgePoint.
8087
each extent: anElement measuredExtent.
8188

82-
self uniformSectors ifFalse: [
83-
angleGap := each constraints annulus expliciteAngleGap ].
89+
sectorGap := (each constraints annulus
90+
sectorAngleInDegreesWithRadius: radius)
91+
ifNotNil: [ :gap | gap ]
92+
ifNil: [ defaultGap ].
93+
8494
each
8595
innerRadialRatio: self innerRadialRatio;
8696
outerRadialRatio: self outerRadialRatio;
87-
startAngle: angleDeg;
88-
endAngle: angleDeg + angleGap.
89-
angleDeg := angleDeg + angleGap.
97+
startAngle: sectorStartAngle;
98+
endAngle: sectorStartAngle + sectorGap.
99+
sectorStartAngle := sectorStartAngle + sectorGap.
90100

91101
pointFromCenter := self
92-
pointFromCenter:
93-
anElement measuredBounds center
102+
pointFromCenter: aBounds center
94103
through: centroid
95104
atDistance: 100 ].
96105
super
@@ -200,15 +209,3 @@ ToAnnulusCircularLayout >> trianglePointsIn: container startAngle: aStartAngle e
200209
pStart.
201210
pEnd }
202211
]
203-
204-
{ #category : #accessing }
205-
ToAnnulusCircularLayout >> uniformSectors [
206-
207-
^ uniformSectors ifNil: [ uniformSectors := true ]
208-
]
209-
210-
{ #category : #accessing }
211-
ToAnnulusCircularLayout >> uniformSectors: aBoolean [
212-
213-
uniformSectors := aBoolean
214-
]

src/Toplo-Widget-Circular/ToAnnulusCircularLayoutConstraints.class.st

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,46 @@ Class {
22
#name : #ToAnnulusCircularLayoutConstraints,
33
#superclass : #BlLayoutConstraints,
44
#instVars : [
5-
'angleGap',
6-
'angleWeight'
5+
'sectorMeasurer'
76
],
87
#category : #'Toplo-Widget-Circular-Annulus'
98
}
109

1110
{ #category : #accessing }
12-
ToAnnulusCircularLayoutConstraints >> angleGap [
11+
ToAnnulusCircularLayoutConstraints >> sectorAngleInDegrees: aNumber [
1312

14-
^ angleGap
13+
sectorMeasurer := ToAnnulusSectorAngleMeasurer withAngleInDegrees:
14+
aNumber
1515
]
1616

1717
{ #category : #accessing }
18-
ToAnnulusCircularLayoutConstraints >> angleGap: anObject [
18+
ToAnnulusCircularLayoutConstraints >> sectorAngleInDegreesWithRadius: r [
1919

20-
angleGap := anObject
20+
^ sectorMeasurer ifNotNil: [ :m | m angleInDegreesWithRadius: r ]
2121
]
2222

2323
{ #category : #accessing }
24-
ToAnnulusCircularLayoutConstraints >> angleWeight [
24+
ToAnnulusCircularLayoutConstraints >> sectorArcLength: aNumber [
2525

26-
^ angleWeight
26+
sectorMeasurer := ToAnnulusSectorAngleMeasurer withArcLength:
27+
aNumber
2728
]
2829

2930
{ #category : #accessing }
30-
ToAnnulusCircularLayoutConstraints >> angleWeight: anObject [
31+
ToAnnulusCircularLayoutConstraints >> sectorChordLength: aNumber [
3132

32-
angleWeight := anObject
33+
sectorMeasurer := ToAnnulusSectorAngleMeasurer withChordLength:
34+
aNumber
3335
]
3436

3537
{ #category : #accessing }
36-
ToAnnulusCircularLayoutConstraints >> expliciteAngleGap [
38+
ToAnnulusCircularLayoutConstraints >> sectorMeasurer [
3739

38-
^ angleGap ifNil: [
39-
angleWeight ifNotNil: [ :w | 360 * w ] ifNil: [ 0 ] ]
40+
^ sectorMeasurer
41+
]
42+
43+
{ #category : #accessing }
44+
ToAnnulusCircularLayoutConstraints >> sectorMeasurer: aMeasurer [
45+
46+
sectorMeasurer := aMeasurer
4047
]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
Class {
2+
#name : #ToAnnulusSectorAngleMeasureStrategy,
3+
#superclass : #ToAnnulusSectorMeasureStrategy,
4+
#instVars : [
5+
'angleInDegrees'
6+
],
7+
#category : #'Toplo-Widget-Circular-SectorMeasurer'
8+
}
9+
10+
{ #category : #accessing }
11+
ToAnnulusSectorAngleMeasureStrategy >> angleInDegrees [
12+
13+
^ angleInDegrees
14+
]
15+
16+
{ #category : #accessing }
17+
ToAnnulusSectorAngleMeasureStrategy >> angleInDegrees: anAngleInDegrees [
18+
19+
(anAngleInDegrees isNumber and: [
20+
anAngleInDegrees >= 0 and: anAngleInDegrees <= 360 ]) ifFalse: [
21+
self error: 'Angle must be between 0 and 360.' ].
22+
angleInDegrees := anAngleInDegrees
23+
]
24+
25+
{ #category : #measuring }
26+
ToAnnulusSectorAngleMeasureStrategy >> angleInDegreesWithRadius: r [
27+
28+
^ angleInDegrees
29+
]
30+
31+
{ #category : #measuring }
32+
ToAnnulusSectorAngleMeasureStrategy >> arcLengthWithRadius: r [
33+
34+
^ r * angleInDegrees degreesToRadians
35+
]
36+
37+
{ #category : #measuring }
38+
ToAnnulusSectorAngleMeasureStrategy >> chordLengthWithRadius: r [
39+
40+
^ 2 * r * (angleInDegrees * 0.5) degreesToRadians sin
41+
]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Class {
2+
#name : #ToAnnulusSectorAngleMeasurer,
3+
#superclass : #Object,
4+
#instVars : [
5+
'measureStrategy'
6+
],
7+
#category : #'Toplo-Widget-Circular-SectorMeasurer'
8+
}
9+
10+
{ #category : #'instance ' }
11+
ToAnnulusSectorAngleMeasurer class >> withAngleInDegrees: anAngleInDegrees [
12+
13+
^ self new measureStrategy:
14+
(ToAnnulusSectorAngleMeasureStrategy new angleInDegrees:
15+
anAngleInDegrees)
16+
]
17+
18+
{ #category : #'instance ' }
19+
ToAnnulusSectorAngleMeasurer class >> withArcLength: aNumber [
20+
21+
^ self new measureStrategy:
22+
(ToAnnulusSectorArcMeasureStrategy new arcLength: aNumber)
23+
]
24+
25+
{ #category : #'instance ' }
26+
ToAnnulusSectorAngleMeasurer class >> withChordLength: aNumber [
27+
28+
^ self new measureStrategy:
29+
(ToAnnulusSectorChordMeasureStrategy new chordLength: aNumber)
30+
]
31+
32+
{ #category : #measuring }
33+
ToAnnulusSectorAngleMeasurer >> angleInDegreesWithRadius: r [
34+
35+
^ measureStrategy angleInDegreesWithRadius: r
36+
]
37+
38+
{ #category : #measuring }
39+
ToAnnulusSectorAngleMeasurer >> arcLengthWithRadius: r [
40+
41+
^ measureStrategy arcLengthWithRadius: r
42+
]
43+
44+
{ #category : #measuring }
45+
ToAnnulusSectorAngleMeasurer >> chordLengthWithRadius: r [
46+
47+
^ measureStrategy chordLengthWithRadius: r
48+
]
49+
50+
{ #category : #accessing }
51+
ToAnnulusSectorAngleMeasurer >> measureStrategy [
52+
53+
^ measureStrategy
54+
]
55+
56+
{ #category : #accessing }
57+
ToAnnulusSectorAngleMeasurer >> measureStrategy: anArcMeasureStrategy [
58+
59+
measureStrategy := anArcMeasureStrategy
60+
]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
Class {
2+
#name : #ToAnnulusSectorArcMeasureStrategy,
3+
#superclass : #ToAnnulusSectorMeasureStrategy,
4+
#instVars : [
5+
'arcLength'
6+
],
7+
#category : #'Toplo-Widget-Circular-SectorMeasurer'
8+
}
9+
10+
{ #category : #measuring }
11+
ToAnnulusSectorArcMeasureStrategy >> angleInDegreesWithRadius: r [
12+
13+
^ (arcLength / r) radiansToDegrees
14+
]
15+
16+
{ #category : #accessing }
17+
ToAnnulusSectorArcMeasureStrategy >> arcLength [
18+
19+
^ arcLength
20+
]
21+
22+
{ #category : #accessing }
23+
ToAnnulusSectorArcMeasureStrategy >> arcLength: aNumber [
24+
25+
aNumber >= 0 ifFalse: [ self error: 'Arc must be a positive number' ].
26+
arcLength := aNumber
27+
]
28+
29+
{ #category : #measuring }
30+
ToAnnulusSectorArcMeasureStrategy >> arcLengthWithRadius: r [
31+
32+
^ arcLength
33+
]
34+
35+
{ #category : #measuring }
36+
ToAnnulusSectorArcMeasureStrategy >> chordLengthWithRadius: r [
37+
38+
| angleRad |
39+
angleRad := arcLength / r.
40+
^ 2 * r * (angleRad * 0.5) sin
41+
]

0 commit comments

Comments
 (0)