saminsohag

texts are selectable now

1 -import 'dart:math';  
2 -  
3 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
4 -import 'package:flutter/rendering.dart';  
5 -  
6 -enum CustomRbSlot {  
7 - rb,  
8 - child,  
9 -}  
10 2
11 -class CustomRb  
12 - extends SlottedMultiChildRenderObjectWidget<CustomRbSlot, RenderBox> { 3 +class CustomRb extends StatelessWidget {
13 const CustomRb({ 4 const CustomRb({
14 super.key, 5 super.key,
15 this.spacing = 5, 6 this.spacing = 5,
@@ -23,268 +14,73 @@ class CustomRb @@ -23,268 +14,73 @@ class CustomRb
23 final TextDirection textDirection; 14 final TextDirection textDirection;
24 15
25 @override 16 @override
26 - Widget? childForSlot(CustomRbSlot slot) {  
27 - switch (slot) {  
28 - case CustomRbSlot.rb:  
29 - return Radio(  
30 - value: value,  
31 - groupValue: true,  
32 - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,  
33 - onChanged: (value) {},  
34 - );  
35 - case CustomRbSlot.child:  
36 - return child;  
37 - }  
38 - }  
39 -  
40 - @override  
41 - SlottedContainerRenderObjectMixin<CustomRbSlot, RenderBox> createRenderObject(  
42 - BuildContext context) {  
43 - return RenderCustomRb(spacing, textDirection);  
44 - }  
45 -  
46 - @override  
47 - void updateRenderObject(  
48 - BuildContext context, covariant RenderCustomRb renderObject) {  
49 - renderObject.spacing = spacing;  
50 - renderObject.textDirection = textDirection; 17 + Widget build(BuildContext context) {
  18 + return Directionality(
  19 + textDirection: textDirection,
  20 + child: Row(
  21 + textBaseline: TextBaseline.alphabetic,
  22 + crossAxisAlignment: CrossAxisAlignment.baseline,
  23 + children: [
  24 + Text.rich(
  25 + WidgetSpan(
  26 + alignment: PlaceholderAlignment.middle,
  27 + child: Padding(
  28 + padding:
  29 + EdgeInsetsDirectional.only(start: spacing, end: spacing),
  30 + child: Radio(
  31 + value: value,
  32 + groupValue: true,
  33 + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
  34 + onChanged: (value) {},
  35 + ),
  36 + ),
  37 + ),
  38 + ),
  39 + Expanded(
  40 + child: child,
  41 + )
  42 + ],
  43 + ),
  44 + );
51 } 45 }
52 -  
53 - @override  
54 - Iterable<CustomRbSlot> get slots => CustomRbSlot.values;  
55 } 46 }
56 47
57 -class RenderCustomRb extends RenderBox  
58 - with SlottedContainerRenderObjectMixin<CustomRbSlot, RenderBox> {  
59 - RenderCustomRb(this._spacing, this._textDirection);  
60 - double _spacing;  
61 - TextDirection _textDirection;  
62 - set textDirection(TextDirection value) {  
63 - if (_textDirection == value) {  
64 - return;  
65 - }  
66 - _textDirection = value;  
67 - markNeedsLayout();  
68 - }  
69 -  
70 - set spacing(double value) {  
71 - if (_spacing == value) {  
72 - return;  
73 - }  
74 - _spacing = value;  
75 - markNeedsLayout();  
76 - }  
77 -  
78 - RenderBox? get rb => childForSlot(CustomRbSlot.rb);  
79 - RenderBox? get body => childForSlot(CustomRbSlot.child);  
80 -  
81 - Size _layoutBox(RenderBox box, BoxConstraints constraints) {  
82 - box.layout(constraints, parentUsesSize: true);  
83 - return box.size;  
84 - }  
85 -  
86 - @override  
87 - void performLayout() {  
88 - if (rb == null || body == null) {  
89 - size = constraints.constrain(const Size(50, 10));  
90 - return;  
91 - }  
92 - rb;  
93 - Size rbSize =  
94 - _layoutBox(rb!, const BoxConstraints(maxWidth: 50, maxHeight: 20));  
95 - Size bodySize = _layoutBox(  
96 - body!,  
97 - BoxConstraints(  
98 - maxWidth: constraints.maxWidth - rbSize.width - _spacing));  
99 - if (_textDirection == TextDirection.ltr) {  
100 - body!.parentData = BoxParentData()  
101 - ..offset = Offset(rbSize.width + _spacing, 0);  
102 - rb!.parentData = BoxParentData()  
103 - ..offset = Offset(  
104 - 0,  
105 - body!.computeDistanceToActualBaseline(TextBaseline.alphabetic)! -  
106 - rb!.size.height / 1.5,  
107 - );  
108 - } else {  
109 - body!.parentData = BoxParentData()..offset = Offset(-_spacing, 0);  
110 - rb!.parentData = BoxParentData()  
111 - ..offset = Offset(  
112 - bodySize.width,  
113 - body!.computeDistanceToActualBaseline(TextBaseline.alphabetic)! -  
114 - rb!.size.height / 1.5,  
115 - );  
116 - }  
117 - size = constraints.constrain(Size(bodySize.width + rbSize.width + _spacing,  
118 - max(rbSize.height, bodySize.height)));  
119 - }  
120 -  
121 - @override  
122 - void paint(PaintingContext context, Offset offset) {  
123 - context.paintChild(  
124 - body!, offset + (body!.parentData as BoxParentData).offset);  
125 - context.paintChild(rb!, offset + (rb!.parentData as BoxParentData).offset);  
126 - }  
127 -  
128 - @override  
129 - bool hitTestSelf(Offset position) {  
130 - return true;  
131 - }  
132 -  
133 - @override  
134 - bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {  
135 - for (final RenderBox child in children) {  
136 - final BoxParentData parentData = child.parentData! as BoxParentData;  
137 - final bool isHit = result.addWithPaintOffset(  
138 - offset: parentData.offset,  
139 - position: position,  
140 - hitTest: (BoxHitTestResult result, Offset transformed) {  
141 - assert(transformed == position - parentData.offset);  
142 - return child.hitTest(result, position: transformed);  
143 - },  
144 - );  
145 - if (isHit) {  
146 - return true;  
147 - }  
148 - }  
149 - return false;  
150 - }  
151 -}  
152 -  
153 -enum CustomCbSlot {  
154 - cb,  
155 - child,  
156 -}  
157 -  
158 -class CustomCb  
159 - extends SlottedMultiChildRenderObjectWidget<CustomCbSlot, RenderBox> {  
160 - const CustomCb(  
161 - {super.key,  
162 - this.spacing = 5,  
163 - this.textDirection = TextDirection.ltr,  
164 - required this.child,  
165 - required this.value}); 48 +class CustomCb extends StatelessWidget {
  49 + const CustomCb({
  50 + super.key,
  51 + this.spacing = 5,
  52 + required this.child,
  53 + this.textDirection = TextDirection.ltr,
  54 + required this.value,
  55 + });
166 final Widget child; 56 final Widget child;
167 - final TextDirection textDirection;  
168 final bool value; 57 final bool value;
169 final double spacing; 58 final double spacing;
  59 + final TextDirection textDirection;
170 60
171 @override 61 @override
172 - Widget? childForSlot(CustomCbSlot slot) {  
173 - switch (slot) {  
174 - case CustomCbSlot.cb:  
175 - return Checkbox(value: value, onChanged: (value) {});  
176 - case CustomCbSlot.child:  
177 - return child;  
178 - }  
179 - }  
180 -  
181 - @override  
182 - SlottedContainerRenderObjectMixin<CustomCbSlot, RenderBox> createRenderObject(  
183 - BuildContext context) {  
184 - return RenderCustomCb(spacing, textDirection);  
185 - }  
186 -  
187 - @override  
188 - void updateRenderObject(  
189 - BuildContext context, covariant RenderCustomCb renderObject) {  
190 - renderObject.spacing = spacing;  
191 - renderObject.textDirection = textDirection;  
192 - }  
193 -  
194 - @override  
195 - Iterable<CustomCbSlot> get slots => CustomCbSlot.values;  
196 -}  
197 -  
198 -class RenderCustomCb extends RenderBox  
199 - with SlottedContainerRenderObjectMixin<CustomCbSlot, RenderBox> {  
200 - RenderCustomCb(this._spacing, this._textDirection);  
201 - double _spacing;  
202 - TextDirection _textDirection;  
203 - set textDirection(TextDirection value) {  
204 - if (_textDirection == value) {  
205 - return;  
206 - }  
207 - _textDirection = value;  
208 - markNeedsLayout();  
209 - }  
210 -  
211 - set spacing(double value) {  
212 - if (_spacing == value) {  
213 - return;  
214 - }  
215 - _spacing = value;  
216 - markNeedsLayout();  
217 - }  
218 -  
219 - RenderBox? get rb => childForSlot(CustomCbSlot.cb);  
220 - RenderBox? get body => childForSlot(CustomCbSlot.child);  
221 -  
222 - Size _layoutBox(RenderBox box, BoxConstraints constraints) {  
223 - box.layout(constraints, parentUsesSize: true);  
224 - return box.size;  
225 - }  
226 -  
227 - @override  
228 - void performLayout() {  
229 - if (rb == null || body == null) {  
230 - size = constraints.constrain(const Size(50, 10));  
231 - return;  
232 - }  
233 - rb;  
234 - Size rbSize =  
235 - _layoutBox(rb!, const BoxConstraints(maxWidth: 50, maxHeight: 20));  
236 - Size bodySize = _layoutBox(  
237 - body!,  
238 - BoxConstraints(  
239 - maxWidth: constraints.maxWidth - rbSize.width - _spacing));  
240 - if (_textDirection == TextDirection.ltr) {  
241 - body!.parentData = BoxParentData()  
242 - ..offset = Offset(rbSize.width + _spacing, 0);  
243 - rb!.parentData = BoxParentData()  
244 - ..offset = Offset(  
245 - 0,  
246 - body!.computeDistanceToActualBaseline(TextBaseline.alphabetic)! -  
247 - rb!.size.height / 1.5);  
248 - } else {  
249 - body!.parentData = BoxParentData()..offset = Offset(-_spacing, 0);  
250 - rb!.parentData = BoxParentData()  
251 - ..offset = Offset(  
252 - bodySize.width,  
253 - body!.computeDistanceToActualBaseline(TextBaseline.alphabetic)! -  
254 - rb!.size.height / 1.5);  
255 - }  
256 - size = constraints.constrain(Size(bodySize.width + rbSize.width + _spacing,  
257 - max(rbSize.height, bodySize.height)));  
258 - }  
259 -  
260 - @override  
261 - void paint(PaintingContext context, Offset offset) {  
262 - context.paintChild(  
263 - body!, offset + (body!.parentData as BoxParentData).offset);  
264 - context.paintChild(rb!, offset + (rb!.parentData as BoxParentData).offset);  
265 - }  
266 -  
267 - @override  
268 - bool hitTestSelf(Offset position) {  
269 - return true;  
270 - }  
271 -  
272 - @override  
273 - bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {  
274 - for (final RenderBox child in children) {  
275 - final BoxParentData parentData = child.parentData! as BoxParentData;  
276 - final bool isHit = result.addWithPaintOffset(  
277 - offset: parentData.offset,  
278 - position: position,  
279 - hitTest: (BoxHitTestResult result, Offset transformed) {  
280 - assert(transformed == position - parentData.offset);  
281 - return child.hitTest(result, position: transformed);  
282 - },  
283 - );  
284 - if (isHit) {  
285 - return true;  
286 - }  
287 - }  
288 - return false; 62 + Widget build(BuildContext context) {
  63 + return Directionality(
  64 + textDirection: textDirection,
  65 + child: Row(
  66 + textBaseline: TextBaseline.alphabetic,
  67 + crossAxisAlignment: CrossAxisAlignment.baseline,
  68 + children: [
  69 + Text.rich(
  70 + WidgetSpan(
  71 + alignment: PlaceholderAlignment.middle,
  72 + child: Padding(
  73 + padding:
  74 + EdgeInsetsDirectional.only(start: spacing, end: spacing),
  75 + child: Checkbox(value: value, onChanged: (value) {}),
  76 + ),
  77 + ),
  78 + ),
  79 + Expanded(
  80 + child: child,
  81 + )
  82 + ],
  83 + ),
  84 + );
289 } 85 }
290 } 86 }
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 -import 'package:flutter/rendering.dart';  
3 2
4 -class UnorderedListView extends SingleChildRenderObjectWidget {  
5 - const UnorderedListView(  
6 - {super.key,  
7 - this.spacing = 6,  
8 - this.padding = 10,  
9 - this.bulletColor,  
10 - this.bulletSize = 4,  
11 - this.textDirection = TextDirection.ltr,  
12 - required super.child}); 3 +class UnorderedListView extends StatelessWidget {
  4 + const UnorderedListView({
  5 + super.key,
  6 + this.spacing = 8,
  7 + this.padding = 12,
  8 + this.bulletColor,
  9 + this.bulletSize = 4,
  10 + this.textDirection = TextDirection.ltr,
  11 + required this.child,
  12 + });
13 final double bulletSize; 13 final double bulletSize;
14 final double spacing; 14 final double spacing;
15 final double padding; 15 final double padding;
16 final TextDirection textDirection; 16 final TextDirection textDirection;
17 final Color? bulletColor; 17 final Color? bulletColor;
18 -  
19 - @override  
20 - RenderObject createRenderObject(BuildContext context) {  
21 - return UnorderedListRenderObject(  
22 - spacing,  
23 - padding,  
24 - bulletColor ?? Theme.of(context).colorScheme.onSurface,  
25 - textDirection,  
26 - bulletSize, 18 + final Widget child;
  19 +
  20 + @override
  21 + Widget build(BuildContext context) {
  22 + return Directionality(
  23 + textDirection: textDirection,
  24 + child: Row(
  25 + textBaseline: TextBaseline.alphabetic,
  26 + crossAxisAlignment: CrossAxisAlignment.baseline,
  27 + children: [
  28 + if (bulletSize == 0)
  29 + SizedBox(
  30 + width: spacing + padding,
  31 + )
  32 + else
  33 + Text.rich(
  34 + WidgetSpan(
  35 + alignment: PlaceholderAlignment.middle,
  36 + child: Padding(
  37 + padding:
  38 + EdgeInsetsDirectional.only(start: padding, end: spacing),
  39 + child: Container(
  40 + width: bulletSize,
  41 + height: bulletSize,
  42 + decoration: BoxDecoration(
  43 + color: bulletColor,
  44 + shape: BoxShape.circle,
  45 + ),
  46 + ),
  47 + ),
  48 + ),
  49 + ),
  50 + Expanded(
  51 + child: child,
  52 + )
  53 + ],
  54 + ),
27 ); 55 );
28 } 56 }
29 -  
30 - @override  
31 - void updateRenderObject(  
32 - BuildContext context, covariant UnorderedListRenderObject renderObject) {  
33 - renderObject.bulletColor =  
34 - bulletColor ?? Theme.of(context).colorScheme.onSurface;  
35 - renderObject.bulletSize = bulletSize;  
36 - renderObject.spacing = spacing;  
37 - renderObject.padding = padding;  
38 - renderObject.textDirection = textDirection;  
39 - }  
40 } 57 }
41 58
42 -class UnorderedListRenderObject extends RenderProxyBox {  
43 - UnorderedListRenderObject(  
44 - double spacing,  
45 - double padding,  
46 - Color bulletColor,  
47 - TextDirection textDirection,  
48 - this._bulletSize, {  
49 - RenderBox? child,  
50 - }) : _bulletColor = bulletColor,  
51 - _spacing = spacing,  
52 - _padding = padding,  
53 - _textDirection = textDirection,  
54 - super(child);  
55 - double _spacing;  
56 - double _padding;  
57 - Offset _bulletOffset = Offset.zero;  
58 - TextDirection _textDirection;  
59 - set spacing(double value) {  
60 - if (_spacing == value) {  
61 - return;  
62 - }  
63 - _spacing = value;  
64 - markNeedsLayout();  
65 - }  
66 -  
67 - set padding(double value) {  
68 - if (_padding == value) {  
69 - return;  
70 - }  
71 - _padding = value;  
72 - markNeedsLayout();  
73 - }  
74 -  
75 - set textDirection(TextDirection value) {  
76 - if (_textDirection == value) {  
77 - return;  
78 - }  
79 - _textDirection = value;  
80 - markNeedsLayout();  
81 - markNeedsPaint();  
82 - }  
83 -  
84 - Color _bulletColor;  
85 - double _bulletSize;  
86 - set bulletSize(double value) {  
87 - if (_bulletSize == value) {  
88 - return;  
89 - }  
90 - _bulletSize = value;  
91 - markNeedsLayout();  
92 - }  
93 -  
94 - set bulletColor(Color value) {  
95 - if (_bulletColor == value) {  
96 - return;  
97 - }  
98 - _bulletColor = value;  
99 - markNeedsLayout();  
100 - }  
101 -  
102 - @override  
103 - double computeMinIntrinsicWidth(double height) {  
104 - child!.layout(  
105 - BoxConstraints(  
106 - maxWidth:  
107 - constraints.maxWidth - _spacing - 6 - _bulletSize - _padding,  
108 - ),  
109 - parentUsesSize: true);  
110 - return child!.size.width;  
111 - }  
112 -  
113 - @override  
114 - double computeMaxIntrinsicWidth(double height) {  
115 - child!.layout(  
116 - BoxConstraints(  
117 - maxWidth:  
118 - constraints.maxWidth - _spacing - 6 - _bulletSize - _padding,  
119 - ),  
120 - parentUsesSize: true);  
121 - return child!.size.width;  
122 - }  
123 -  
124 - @override  
125 - double computeMinIntrinsicHeight(double width) {  
126 - child!.layout(  
127 - BoxConstraints(  
128 - maxWidth:  
129 - constraints.maxWidth - _spacing - 6 - _bulletSize - _padding,  
130 - ),  
131 - parentUsesSize: true);  
132 - return child!.size.height;  
133 - }  
134 -  
135 - @override  
136 - double computeMaxIntrinsicHeight(double width) {  
137 - child!.layout(  
138 - BoxConstraints(  
139 - maxWidth:  
140 - constraints.maxWidth - _spacing - 6 - _bulletSize - _padding,  
141 - ),  
142 - parentUsesSize: true);  
143 - return child!.size.height;  
144 - }  
145 -  
146 - @override  
147 - void performLayout() {  
148 - super.performLayout();  
149 - if (child == null) {  
150 - return;  
151 - }  
152 - child!.layout(  
153 - BoxConstraints(  
154 - maxWidth:  
155 - constraints.maxWidth - _spacing - 6 - _bulletSize - _padding,  
156 - ),  
157 - parentUsesSize: true);  
158 - if (_textDirection == TextDirection.ltr) {  
159 - child!.parentData = BoxParentData()  
160 - ..offset = Offset(_spacing + _padding + 6 + _bulletSize, 0);  
161 - var value =  
162 - child!.computeDistanceToActualBaseline(TextBaseline.alphabetic);  
163 - _bulletOffset = Offset(4 + _padding, value! - _bulletSize);  
164 - } else {  
165 - child!.parentData = BoxParentData()  
166 - ..offset = Offset(-_spacing - _padding + 6 + _bulletSize, 0);  
167 - var value =  
168 - child!.computeDistanceToActualBaseline(TextBaseline.alphabetic);  
169 - _bulletOffset =  
170 - Offset(child!.size.width - 4 + _padding, value! - _bulletSize);  
171 - }  
172 - size = constraints.constrain(Size(  
173 - child!.size.width + _spacing + _padding + 6 + _bulletSize,  
174 - child!.size.height));  
175 - }  
176 -  
177 - @override  
178 - void paint(PaintingContext context, Offset offset) {  
179 - if (child == null) {  
180 - return;  
181 - }  
182 - if (_textDirection == TextDirection.ltr) {  
183 - context.paintChild(  
184 - child!, offset + (child!.parentData as BoxParentData).offset);  
185 - context.canvas.drawCircle(  
186 - offset + _bulletOffset, _bulletSize, Paint()..color = _bulletColor);  
187 - } else {  
188 - context.paintChild(  
189 - child!, offset + (child!.parentData as BoxParentData).offset);  
190 - context.canvas.drawCircle(  
191 - offset + _bulletOffset, _bulletSize, Paint()..color = _bulletColor);  
192 - }  
193 - }  
194 -  
195 - @override  
196 - bool hitTestSelf(Offset position) {  
197 - return false;  
198 - }  
199 -  
200 - @override  
201 - bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {  
202 - Offset offset = (child!.parentData as BoxParentData).offset;  
203 - return result.addWithPaintOffset(  
204 - offset: offset,  
205 - position: position,  
206 - hitTest: (result, newOffset) {  
207 - return child?.hitTest(result, position: newOffset) ?? false;  
208 - },  
209 - );  
210 - }  
211 -  
212 - @override  
213 - bool hitTest(BoxHitTestResult result, {required Offset position}) {  
214 - return hitTestChildren(result, position: position);  
215 - }  
216 -}  
217 -  
218 -class OrderedListView extends SingleChildRenderObjectWidget { 59 +class OrderedListView extends StatelessWidget {
219 final String no; 60 final String no;
220 final double spacing; 61 final double spacing;
221 final double padding; 62 final double padding;
@@ -224,196 +65,36 @@ class OrderedListView extends SingleChildRenderObjectWidget { @@ -224,196 +65,36 @@ class OrderedListView extends SingleChildRenderObjectWidget {
224 this.spacing = 6, 65 this.spacing = 6,
225 this.padding = 10, 66 this.padding = 10,
226 TextStyle? style, 67 TextStyle? style,
227 - required super.child, 68 + required this.child,
228 this.textDirection = TextDirection.ltr, 69 this.textDirection = TextDirection.ltr,
229 required this.no}) 70 required this.no})
230 : _style = style; 71 : _style = style;
231 final TextStyle? _style; 72 final TextStyle? _style;
232 final TextDirection textDirection; 73 final TextDirection textDirection;
233 -  
234 - TextStyle getStyle(BuildContext context) {  
235 - if (_style == null || _style!.inherit) {  
236 - return DefaultTextStyle.of(context).style.merge(_style);  
237 - }  
238 - return _style!;  
239 - }  
240 -  
241 - @override  
242 - RenderObject createRenderObject(BuildContext context) {  
243 - return OrderedListRenderObject(  
244 - no,  
245 - spacing,  
246 - padding,  
247 - textDirection,  
248 - getStyle(context),  
249 - );  
250 - }  
251 -  
252 - @override  
253 - void updateRenderObject(  
254 - BuildContext context, covariant OrderedListRenderObject renderObject) {  
255 - renderObject.no = no;  
256 - renderObject.spacing = spacing;  
257 - renderObject.padding = padding;  
258 - renderObject.style = getStyle(context);  
259 - renderObject.textDirection = textDirection;  
260 - }  
261 -}  
262 -  
263 -class OrderedListRenderObject extends RenderProxyBox {  
264 - OrderedListRenderObject(  
265 - String no,  
266 - double spacing,  
267 - double padding,  
268 - TextDirection textDirection,  
269 - TextStyle style, {  
270 - RenderBox? child,  
271 - }) : _no = no,  
272 - _style = style,  
273 - _spacing = spacing,  
274 - _padding = padding,  
275 - _textDirection = textDirection,  
276 - super(child);  
277 - double _spacing;  
278 - double _padding;  
279 - TextDirection _textDirection;  
280 - Offset _ptOffset = Offset.zero;  
281 - set spacing(double value) {  
282 - if (_spacing == value) {  
283 - return;  
284 - }  
285 - _spacing = value;  
286 - markNeedsLayout();  
287 - }  
288 -  
289 - set padding(double value) {  
290 - if (_padding == value) {  
291 - return;  
292 - }  
293 - _padding = value;  
294 - markNeedsLayout();  
295 - }  
296 -  
297 - set textDirection(TextDirection value) {  
298 - if (_textDirection == value) {  
299 - return;  
300 - }  
301 - _textDirection = value;  
302 - markNeedsLayout();  
303 - markNeedsPaint();  
304 - }  
305 -  
306 - TextStyle _style;  
307 - set style(TextStyle value) {  
308 - _style = value;  
309 - markNeedsLayout();  
310 - }  
311 -  
312 - String _no;  
313 - set no(String value) {  
314 - if (_no == value) {  
315 - return;  
316 - }  
317 - _no = value;  
318 - markNeedsLayout();  
319 - }  
320 -  
321 - @override  
322 - double computeMinIntrinsicHeight(double width) {  
323 - pt = TextPainter(  
324 - text: TextSpan(  
325 - text: _no,  
326 - style: _style,  
327 - ),  
328 - textDirection: TextDirection.ltr);  
329 - pt.layout(maxWidth: constraints.maxWidth - 50 - _spacing - _padding);  
330 - return child!  
331 - .computeMinIntrinsicHeight(width - pt.width - _spacing - _padding);  
332 - }  
333 -  
334 - @override  
335 - double computeMaxIntrinsicHeight(double width) {  
336 - pt = TextPainter(  
337 - text: TextSpan(  
338 - text: _no,  
339 - style: _style,  
340 - ),  
341 - textDirection: TextDirection.ltr);  
342 - pt.layout(maxWidth: constraints.maxWidth - 50 - _spacing - _padding);  
343 - return child!  
344 - .computeMaxIntrinsicHeight(width - pt.width - _spacing - _padding);  
345 - }  
346 -  
347 - late TextPainter pt;  
348 - @override  
349 - void performLayout() {  
350 - super.performLayout();  
351 - if (child == null) {  
352 - return;  
353 - }  
354 - pt = TextPainter(  
355 - text: TextSpan(  
356 - text: _no,  
357 - style: _style,  
358 - ),  
359 - textDirection: TextDirection.ltr);  
360 - pt.layout(maxWidth: constraints.maxWidth - 50 - _spacing - _padding);  
361 - child!.layout(  
362 - BoxConstraints(  
363 - maxWidth: constraints.maxWidth - pt.width - _spacing - _padding,  
364 - ),  
365 - parentUsesSize: true);  
366 - if (_textDirection == TextDirection.ltr) {  
367 - child!.parentData = BoxParentData()  
368 - ..offset = Offset(_spacing + _padding + pt.width, 0);  
369 - var value =  
370 - child!.computeDistanceToActualBaseline(TextBaseline.alphabetic);  
371 - _ptOffset = Offset(_padding,  
372 - value! - pt.computeDistanceToActualBaseline(TextBaseline.alphabetic));  
373 - } else {  
374 - child!.parentData = BoxParentData()  
375 - ..offset = Offset(-_spacing - _padding + pt.width, 0);  
376 - var value =  
377 - child!.computeDistanceToActualBaseline(TextBaseline.alphabetic);  
378 - _ptOffset = Offset(child!.size.width + _padding - 4,  
379 - value! - pt.computeDistanceToActualBaseline(TextBaseline.alphabetic));  
380 - }  
381 - size = constraints.constrain(Size(  
382 - child!.size.width + _spacing + _padding + pt.width,  
383 - child!.size.height));  
384 - }  
385 -  
386 - @override  
387 - void paint(PaintingContext context, Offset offset) {  
388 - if (child == null) {  
389 - return;  
390 - }  
391 - context.paintChild(  
392 - child!,  
393 - offset + (child!.parentData as BoxParentData).offset, 74 + final Widget child;
  75 +
  76 + @override
  77 + Widget build(BuildContext context) {
  78 + return Directionality(
  79 + textDirection: textDirection,
  80 + child: Row(
  81 + textBaseline: TextBaseline.alphabetic,
  82 + crossAxisAlignment: CrossAxisAlignment.baseline,
  83 + children: [
  84 + Padding(
  85 + padding: EdgeInsetsDirectional.only(start: padding, end: spacing),
  86 + child: Text.rich(
  87 + TextSpan(
  88 + text: no,
  89 + ),
  90 + style: _style,
  91 + ),
  92 + ),
  93 + Expanded(
  94 + child: child,
  95 + )
  96 + ],
  97 + ),
394 ); 98 );
395 - pt.paint(context.canvas, offset + _ptOffset);  
396 - }  
397 -  
398 - @override  
399 - bool hitTestSelf(Offset position) {  
400 - return false;  
401 - }  
402 -  
403 - @override  
404 - bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {  
405 - Offset offset = (child!.parentData as BoxParentData).offset;  
406 - return result.addWithPaintOffset(  
407 - offset: offset,  
408 - position: position,  
409 - hitTest: (result, newOffset) {  
410 - return child?.hitTest(result, position: newOffset) ?? false;  
411 - },  
412 - );  
413 - }  
414 -  
415 - @override  
416 - bool hitTest(BoxHitTestResult result, {required Offset position}) {  
417 - return hitTestChildren(result, position: position);  
418 } 99 }
419 } 100 }
@@ -12,25 +12,26 @@ import 'md_widget.dart'; @@ -12,25 +12,26 @@ import 'md_widget.dart';
12 /// Markdown components 12 /// Markdown components
13 abstract class MarkdownComponent { 13 abstract class MarkdownComponent {
14 static List<MarkdownComponent> get components => [ 14 static List<MarkdownComponent> get components => [
15 - CodeBlockMd(),  
16 - NewLines(),  
17 - TableMd(),  
18 - HTag(),  
19 - IndentMd(),  
20 - UnOrderedList(),  
21 - OrderedList(),  
22 - RadioButtonMd(),  
23 - CheckBoxMd(),  
24 - HrLine(),  
25 - ImageMd(),  
26 - HighlightedText(),  
27 - BoldMd(),  
28 - ItalicMd(),  
29 - LatexMathMultyLine(),  
30 - LatexMath(),  
31 - ATagMd(),  
32 - SourceTag(),  
33 - ]; 15 + CodeBlockMd(),
  16 + NewLines(),
  17 + TableMd(),
  18 + HTag(),
  19 + IndentMd(),
  20 + UnOrderedList(),
  21 + OrderedList(),
  22 + RadioButtonMd(),
  23 + CheckBoxMd(),
  24 + HrLine(),
  25 + ImageMd(),
  26 + HighlightedText(),
  27 + StrikeMd(),
  28 + BoldMd(),
  29 + ItalicMd(),
  30 + LatexMathMultyLine(),
  31 + LatexMath(),
  32 + ATagMd(),
  33 + SourceTag(),
  34 + ];
34 35
35 /// Generate widget for markdown widget 36 /// Generate widget for markdown widget
36 static List<InlineSpan> generate( 37 static List<InlineSpan> generate(
@@ -329,8 +330,8 @@ class IndentMd extends BlockMd { @@ -329,8 +330,8 @@ class IndentMd extends BlockMd {
329 padding: spaces * 5, 330 padding: spaces * 5,
330 bulletSize: 0, 331 bulletSize: 0,
331 textDirection: config.textDirection, 332 textDirection: config.textDirection,
332 - child: RichText(  
333 - text: TextSpan( 333 + child: Text.rich(
  334 + TextSpan(
334 children: MarkdownComponent.generate( 335 children: MarkdownComponent.generate(
335 context, 336 context,
336 "${match?[2]}", 337 "${match?[2]}",
@@ -358,7 +359,7 @@ class UnOrderedList extends BlockMd { @@ -358,7 +359,7 @@ class UnOrderedList extends BlockMd {
358 bulletColor: 359 bulletColor:
359 config.style?.color ?? DefaultTextStyle.of(context).style.color, 360 config.style?.color ?? DefaultTextStyle.of(context).style.color,
360 padding: 10.0, 361 padding: 10.0,
361 - bulletSize: 0.2 * 362 + bulletSize: 0.4 *
362 (config.style?.fontSize ?? 363 (config.style?.fontSize ??
363 DefaultTextStyle.of(context).style.fontSize ?? 364 DefaultTextStyle.of(context).style.fontSize ??
364 kDefaultFontSize), 365 kDefaultFontSize),
@@ -457,11 +458,40 @@ class BoldMd extends InlineMd { @@ -457,11 +458,40 @@ class BoldMd extends InlineMd {
457 ); 458 );
458 } 459 }
459 } 460 }
  461 +class StrikeMd extends InlineMd {
  462 + @override
  463 + RegExp get exp => RegExp(r"(?<!\*)\~\~(?<!\s)(.+?)(?<!\s)\~\~(?!\*)");
  464 +
  465 + @override
  466 + InlineSpan span(
  467 + BuildContext context,
  468 + String text,
  469 + final GptMarkdownConfig config,
  470 + ) {
  471 + var match = exp.firstMatch(text.trim());
  472 + var conf = config.copyWith(
  473 + style: config.style?.copyWith(
  474 + decoration: TextDecoration.lineThrough,
  475 + decorationColor: config.style?.color,
  476 + ) ??
  477 + const TextStyle(decoration: TextDecoration.lineThrough,
  478 + ));
  479 + return TextSpan(
  480 + children: MarkdownComponent.generate(
  481 + context,
  482 + "${match?[1]}",
  483 + conf,
  484 + ),
  485 + style: conf.style,
  486 + );
  487 + }
  488 +}
460 489
461 /// Italic text component 490 /// Italic text component
462 class ItalicMd extends InlineMd { 491 class ItalicMd extends InlineMd {
463 @override 492 @override
464 - RegExp get exp => RegExp(r"(?<!\*)\*(?<!\s)(.+?)(?<!\s)\*(?!\*)", dotAll: true); 493 + RegExp get exp =>
  494 + RegExp(r"(?<!\*)\*(?<!\s)(.+?)(?<!\s)\*(?!\*)", dotAll: true);
465 495
466 @override 496 @override
467 InlineSpan span( 497 InlineSpan span(