creek
The AI Image Editor of 2030git clone https://github.com/maydayv7/creek
lib/ui/pages/canvas_toolbar/text_tools_overlay.dart (6162B)
1import 'package:flutter/material.dart';
2import 'package:flutter_colorpicker/flutter_colorpicker.dart';
3import '../../styles/variables.dart';
4
5class TextToolsOverlay extends StatelessWidget {
6 final bool isActive;
7 final bool isTextSelected;
8 final Color currentColor;
9 final double currentFontSize;
10 final VoidCallback onClose;
11 final VoidCallback onAddText;
12 final Function(Color) onColorChanged;
13 final Function(double) onFontSizeChanged;
14
15 const TextToolsOverlay({
16 super.key,
17 required this.isActive,
18 required this.isTextSelected,
19 required this.currentColor,
20 required this.currentFontSize,
21 required this.onClose,
22 required this.onAddText,
23 required this.onColorChanged,
24 required this.onFontSizeChanged,
25 });
26
27 @override
28 Widget build(BuildContext context) {
29 if (!isActive) return const SizedBox.shrink();
30
31 return Positioned(
32 bottom: 100 + MediaQuery.of(context).padding.bottom,
33 left: 0,
34 right: 0,
35 child: Center(
36 child: Container(
37 margin: const EdgeInsets.symmetric(horizontal: 20),
38 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
39 decoration: BoxDecoration(
40 color: Colors.white,
41 borderRadius: BorderRadius.circular(30),
42 boxShadow: [
43 BoxShadow(
44 color: Colors.black.withOpacity(0.15),
45 blurRadius: 12,
46 offset: const Offset(0, 6),
47 ),
48 ],
49 ),
50 // Prevent overflow if screen is narrow
51 child: SingleChildScrollView(
52 scrollDirection: Axis.horizontal,
53 child: Row(
54 mainAxisSize: MainAxisSize.min,
55 children: [
56 IconButton(
57 icon: const Icon(
58 Icons.check_circle,
59 color: Variables.textPrimary,
60 ),
61 onPressed: onClose,
62 tooltip: "Done",
63 ),
64 Container(width: 1, height: 20, color: Variables.borderSubtle),
65 const SizedBox(width: 8),
66 IconButton(
67 icon: const Icon(
68 Icons.add_circle_outline,
69 color: Variables.textPrimary,
70 ),
71 onPressed: onAddText,
72 tooltip: "Add Text",
73 ),
74
75 if (isTextSelected) ...[
76 const SizedBox(width: 8),
77 Container(
78 width: 1,
79 height: 20,
80 color: Variables.borderSubtle,
81 ),
82 const SizedBox(width: 12),
83 const Icon(
84 Icons.text_fields,
85 size: 18,
86 color: Variables.textSecondary,
87 ),
88 SizedBox(
89 width: 100,
90 child: SliderTheme(
91 data: SliderThemeData(
92 trackHeight: 2,
93 thumbShape: const RoundSliderThumbShape(
94 enabledThumbRadius: 6,
95 ),
96 activeTrackColor: Variables.textPrimary,
97 inactiveTrackColor: Variables.borderSubtle,
98 thumbColor: Colors.black,
99 overlayShape: SliderComponentShape.noOverlay,
100 ),
101 child: Slider(
102 value: currentFontSize.clamp(10.0, 200.0),
103 min: 10.0,
104 max: 200.0,
105 onChanged: onFontSizeChanged,
106 ),
107 ),
108 ),
109 const SizedBox(width: 12),
110 GestureDetector(
111 onTap: () => _showColorPicker(context),
112 child: Container(
113 width: 24,
114 height: 24,
115 decoration: BoxDecoration(
116 color: currentColor,
117 shape: BoxShape.circle,
118 border: Border.all(
119 color: Variables.borderSubtle,
120 width: 1,
121 ),
122 ),
123 ),
124 ),
125 const SizedBox(width: 8),
126 ],
127 ],
128 ),
129 ),
130 ),
131 ),
132 );
133 }
134
135 void _showColorPicker(BuildContext context) {
136 showModalBottomSheet(
137 context: context,
138 backgroundColor: Colors.transparent,
139 builder:
140 (ctx) => Container(
141 padding: const EdgeInsets.all(24),
142 decoration: const BoxDecoration(
143 color: Colors.white,
144 borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
145 ),
146 child: SafeArea(
147 child: Column(
148 mainAxisSize: MainAxisSize.min,
149 children: [
150 Text(
151 "Text Color",
152 style: Variables.headerStyle.copyWith(fontSize: 16),
153 ),
154 const SizedBox(height: 20),
155 BlockPicker(
156 pickerColor: currentColor,
157 onColorChanged: (c) {
158 onColorChanged(c);
159 Navigator.pop(ctx);
160 },
161 layoutBuilder:
162 (context, colors, child) => SizedBox(
163 width: 300,
164 height: 160,
165 child: GridView.count(
166 crossAxisCount: 5,
167 crossAxisSpacing: 10,
168 mainAxisSpacing: 10,
169 children: [
170 for (Color color in colors) child(color),
171 ],
172 ),
173 ),
174 ),
175 ],
176 ),
177 ),
178 ),
179 );
180 }
181}