@@ -3,86 +3,118 @@ import SwiftUI
33extension PropertiesPanel {
44 var cameraSection : some View {
55 VStack ( alignment: . leading, spacing: Layout . itemSpacing) {
6- sectionHeader ( icon: " pip " , title: " Camera " )
6+ sectionHeader ( icon: " web.camera " , title: " Camera " )
77
88 toggleRow ( " Enabled " , isOn: $editorState. webcamEnabled)
99
10- Group {
11- toggleRow ( " Mirror " , isOn: $editorState. cameraMirrored)
10+ toggleRow ( " Mirror " , isOn: $editorState. cameraMirrored)
11+ . disabled ( !editorState. webcamEnabled)
12+ . opacity ( editorState. webcamEnabled ? 1 : 0.5 )
13+ }
14+ }
15+
16+ var cameraPositionSection : some View {
17+ VStack ( alignment: . leading, spacing: Layout . itemSpacing) {
18+ sectionHeader ( icon: " arrow.up.and.down.and.arrow.left.and.right " , title: " Position " )
1219
13- HStack ( spacing: 4 ) {
14- ForEach (
15- Array (
16- zip (
17- [ CameraCorner . topLeft, . topRight, . bottomLeft, . bottomRight] ,
18- [ " arrow.up.left " , " arrow.up.right " , " arrow.down.left " , " arrow.down.right " ]
19- )
20- ) ,
21- id: \. 1
22- ) { corner, icon in
23- Button {
24- editorState. setCameraCorner ( corner)
25- } label: {
26- Image ( systemName: icon)
27- . font ( . system( size: 11 ) )
28- . frame ( width: 28 , height: 28 )
29- . background ( ReframedColors . fieldBackground)
30- . clipShape ( RoundedRectangle ( cornerRadius: 4 ) )
31- }
32- . buttonStyle ( . plain)
33- . foregroundStyle ( ReframedColors . primaryText)
20+ HStack ( spacing: 4 ) {
21+ ForEach (
22+ Array (
23+ zip (
24+ [ CameraCorner . topLeft, . topRight, . bottomLeft, . bottomRight] ,
25+ [ " arrow.up.left " , " arrow.up.right " , " arrow.down.left " , " arrow.down.right " ]
26+ )
27+ ) ,
28+ id: \. 1
29+ ) { corner, icon in
30+ Button {
31+ editorState. setCameraCorner ( corner)
32+ } label: {
33+ Image ( systemName: icon)
34+ . font ( . system( size: 11 ) )
35+ . frame ( width: 28 , height: 28 )
36+ . background ( ReframedColors . fieldBackground)
37+ . clipShape ( RoundedRectangle ( cornerRadius: 4 ) )
3438 }
39+ . buttonStyle ( . plain)
40+ . foregroundStyle ( ReframedColors . primaryText)
3541 }
42+ }
43+ }
44+ . disabled ( !editorState. webcamEnabled)
45+ . opacity ( editorState. webcamEnabled ? 1 : 0.5 )
46+ }
3647
37- cameraAspectSection
48+ var cameraAspectRatioSection : some View {
49+ VStack ( alignment: . leading, spacing: Layout . itemSpacing) {
50+ sectionHeader ( icon: " aspectratio " , title: " Aspect Ratio " )
3851
39- SliderRow (
40- label: " Size " ,
41- value: $editorState. cameraLayout. relativeWidth,
42- range: 0.1 ... editorState. maxCameraRelativeWidth,
43- step: 0.01
44- )
45- . onChange ( of: editorState. cameraLayout. relativeWidth) { _, _ in
46- editorState. clampCameraPosition ( )
52+ Picker ( " " , selection: $editorState. cameraAspect) {
53+ ForEach ( CameraAspect . allCases) { aspect in
54+ Text ( aspect. label) . tag ( aspect)
4755 }
48-
49- SliderRow (
50- label: " Radius " ,
51- value: $editorState. cameraCornerRadius,
52- range: 0 ... 50 ,
53- formattedValue: " \( Int ( editorState. cameraCornerRadius) ) % "
54- )
55-
56- SliderRow (
57- label: " Border " ,
58- value: $editorState. cameraBorderWidth,
59- range: 0 ... 10 ,
60- step: 0.5 ,
61- formattedValue: String ( format: " %.1f " , editorState. cameraBorderWidth)
62- )
63-
64- SliderRow (
65- label: " Shadow " ,
66- value: $editorState. cameraShadow,
67- range: 0 ... 100 ,
68- formattedValue: " \( Int ( editorState. cameraShadow) ) "
69- )
7056 }
71- . disabled ( !editorState. webcamEnabled)
72- . opacity ( editorState. webcamEnabled ? 1 : 0.5 )
57+ . pickerStyle ( . segmented)
58+ . labelsHidden ( )
59+ . onChange ( of: editorState. cameraAspect) { _, _ in
60+ editorState. clampCameraPosition ( )
61+ }
7362 }
63+ . disabled ( !editorState. webcamEnabled)
64+ . opacity ( editorState. webcamEnabled ? 1 : 0.5 )
7465 }
7566
76- private var cameraAspectSection : some View {
77- Picker ( " " , selection: $editorState. cameraAspect) {
78- ForEach ( CameraAspect . allCases) { aspect in
79- Text ( aspect. label) . tag ( aspect)
67+ var cameraStyleSection : some View {
68+ VStack ( alignment: . leading, spacing: Layout . itemSpacing) {
69+ sectionHeader ( icon: " paintbrush " , title: " Style " )
70+
71+ SliderRow (
72+ label: " Size " ,
73+ value: $editorState. cameraLayout. relativeWidth,
74+ range: 0.1 ... editorState. maxCameraRelativeWidth,
75+ step: 0.01
76+ )
77+ . onChange ( of: editorState. cameraLayout. relativeWidth) { _, _ in
78+ editorState. clampCameraPosition ( )
8079 }
80+
81+ SliderRow (
82+ label: " Radius " ,
83+ value: $editorState. cameraCornerRadius,
84+ range: 0 ... 50 ,
85+ formattedValue: " \( Int ( editorState. cameraCornerRadius) ) % "
86+ )
87+
88+ SliderRow (
89+ label: " Shadow " ,
90+ value: $editorState. cameraShadow,
91+ range: 0 ... 100 ,
92+ formattedValue: " \( Int ( editorState. cameraShadow) ) "
93+ )
94+
95+ SliderRow (
96+ label: " Border " ,
97+ value: $editorState. cameraBorderWidth,
98+ range: 0 ... 30 ,
99+ step: 0.5 ,
100+ formattedValue: String ( format: " %.1f " , editorState. cameraBorderWidth)
101+ )
102+
103+ borderColorPickerButton
81104 }
82- . pickerStyle ( . segmented)
83- . labelsHidden ( )
84- . onChange ( of: editorState. cameraAspect) { _, _ in
85- editorState. clampCameraPosition ( )
86- }
105+ . disabled ( !editorState. webcamEnabled)
106+ . opacity ( editorState. webcamEnabled ? 1 : 0.5 )
107+ }
108+
109+ private var borderColorPickerButton : some View {
110+ let currentName =
111+ TailwindColors . all. first { $0. color == editorState. cameraBorderColor } ? . name ?? " White "
112+ return TailwindColorPicker (
113+ displayColor: Color ( cgColor: editorState. cameraBorderColor. cgColor) ,
114+ displayName: currentName,
115+ isPresented: $showBorderColorPopover,
116+ isSelected: { $0. color == editorState. cameraBorderColor } ,
117+ onSelect: { editorState. cameraBorderColor = $0. color }
118+ )
87119 }
88120}
0 commit comments