Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
gpt_markdown
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
saminsohag
2024-11-16 08:50:41 +0600
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
e62829b5ca24c37a6c778f4c13bc0fa8056be14b
e62829b5
1 parent
8812ed66
texts are selectable now
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
187 additions
and
680 deletions
gpt_markdown/lib/custom_widgets/custom_rb_cb.dart
gpt_markdown/lib/custom_widgets/unordered_ordered_list.dart
gpt_markdown/lib/markdown_component.dart
gpt_markdown/lib/custom_widgets/custom_rb_cb.dart
View file @
e62829b
import
'dart:math'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
enum
CustomRbSlot
{
rb
,
child
,
}
class
CustomRb
extends
SlottedMultiChildRenderObjectWidget
<
CustomRbSlot
,
RenderBox
>
{
class
CustomRb
extends
StatelessWidget
{
const
CustomRb
({
super
.
key
,
this
.
spacing
=
5
,
...
...
@@ -23,268 +14,73 @@ class CustomRb
final
TextDirection
textDirection
;
@override
Widget
?
childForSlot
(
CustomRbSlot
slot
)
{
switch
(
slot
)
{
case
CustomRbSlot
.
rb
:
return
Radio
(
value:
value
,
groupValue:
true
,
materialTapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
onChanged:
(
value
)
{},
);
case
CustomRbSlot
.
child
:
return
child
;
}
}
@override
SlottedContainerRenderObjectMixin
<
CustomRbSlot
,
RenderBox
>
createRenderObject
(
BuildContext
context
)
{
return
RenderCustomRb
(
spacing
,
textDirection
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
covariant
RenderCustomRb
renderObject
)
{
renderObject
.
spacing
=
spacing
;
renderObject
.
textDirection
=
textDirection
;
Widget
build
(
BuildContext
context
)
{
return
Directionality
(
textDirection:
textDirection
,
child:
Row
(
textBaseline:
TextBaseline
.
alphabetic
,
crossAxisAlignment:
CrossAxisAlignment
.
baseline
,
children:
[
Text
.
rich
(
WidgetSpan
(
alignment:
PlaceholderAlignment
.
middle
,
child:
Padding
(
padding:
EdgeInsetsDirectional
.
only
(
start:
spacing
,
end:
spacing
),
child:
Radio
(
value:
value
,
groupValue:
true
,
materialTapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
onChanged:
(
value
)
{},
),
),
),
),
Expanded
(
child:
child
,
)
],
),
);
}
@override
Iterable
<
CustomRbSlot
>
get
slots
=>
CustomRbSlot
.
values
;
}
class
RenderCustomRb
extends
RenderBox
with
SlottedContainerRenderObjectMixin
<
CustomRbSlot
,
RenderBox
>
{
RenderCustomRb
(
this
.
_spacing
,
this
.
_textDirection
);
double
_spacing
;
TextDirection
_textDirection
;
set
textDirection
(
TextDirection
value
)
{
if
(
_textDirection
==
value
)
{
return
;
}
_textDirection
=
value
;
markNeedsLayout
();
}
set
spacing
(
double
value
)
{
if
(
_spacing
==
value
)
{
return
;
}
_spacing
=
value
;
markNeedsLayout
();
}
RenderBox
?
get
rb
=>
childForSlot
(
CustomRbSlot
.
rb
);
RenderBox
?
get
body
=>
childForSlot
(
CustomRbSlot
.
child
);
Size
_layoutBox
(
RenderBox
box
,
BoxConstraints
constraints
)
{
box
.
layout
(
constraints
,
parentUsesSize:
true
);
return
box
.
size
;
}
@override
void
performLayout
()
{
if
(
rb
==
null
||
body
==
null
)
{
size
=
constraints
.
constrain
(
const
Size
(
50
,
10
));
return
;
}
rb
;
Size
rbSize
=
_layoutBox
(
rb
!,
const
BoxConstraints
(
maxWidth:
50
,
maxHeight:
20
));
Size
bodySize
=
_layoutBox
(
body
!,
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
rbSize
.
width
-
_spacing
));
if
(
_textDirection
==
TextDirection
.
ltr
)
{
body
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
rbSize
.
width
+
_spacing
,
0
);
rb
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
0
,
body
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
)!
-
rb
!.
size
.
height
/
1.5
,
);
}
else
{
body
!.
parentData
=
BoxParentData
()..
offset
=
Offset
(-
_spacing
,
0
);
rb
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
bodySize
.
width
,
body
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
)!
-
rb
!.
size
.
height
/
1.5
,
);
}
size
=
constraints
.
constrain
(
Size
(
bodySize
.
width
+
rbSize
.
width
+
_spacing
,
max
(
rbSize
.
height
,
bodySize
.
height
)));
}
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
context
.
paintChild
(
body
!,
offset
+
(
body
!.
parentData
as
BoxParentData
).
offset
);
context
.
paintChild
(
rb
!,
offset
+
(
rb
!.
parentData
as
BoxParentData
).
offset
);
}
@override
bool
hitTestSelf
(
Offset
position
)
{
return
true
;
}
@override
bool
hitTestChildren
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
for
(
final
RenderBox
child
in
children
)
{
final
BoxParentData
parentData
=
child
.
parentData
!
as
BoxParentData
;
final
bool
isHit
=
result
.
addWithPaintOffset
(
offset:
parentData
.
offset
,
position:
position
,
hitTest:
(
BoxHitTestResult
result
,
Offset
transformed
)
{
assert
(
transformed
==
position
-
parentData
.
offset
);
return
child
.
hitTest
(
result
,
position:
transformed
);
},
);
if
(
isHit
)
{
return
true
;
}
}
return
false
;
}
}
enum
CustomCbSlot
{
cb
,
child
,
}
class
CustomCb
extends
SlottedMultiChildRenderObjectWidget
<
CustomCbSlot
,
RenderBox
>
{
const
CustomCb
(
{
super
.
key
,
this
.
spacing
=
5
,
this
.
textDirection
=
TextDirection
.
ltr
,
required
this
.
child
,
required
this
.
value
});
class
CustomCb
extends
StatelessWidget
{
const
CustomCb
({
super
.
key
,
this
.
spacing
=
5
,
required
this
.
child
,
this
.
textDirection
=
TextDirection
.
ltr
,
required
this
.
value
,
});
final
Widget
child
;
final
TextDirection
textDirection
;
final
bool
value
;
final
double
spacing
;
final
TextDirection
textDirection
;
@override
Widget
?
childForSlot
(
CustomCbSlot
slot
)
{
switch
(
slot
)
{
case
CustomCbSlot
.
cb
:
return
Checkbox
(
value:
value
,
onChanged:
(
value
)
{});
case
CustomCbSlot
.
child
:
return
child
;
}
}
@override
SlottedContainerRenderObjectMixin
<
CustomCbSlot
,
RenderBox
>
createRenderObject
(
BuildContext
context
)
{
return
RenderCustomCb
(
spacing
,
textDirection
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
covariant
RenderCustomCb
renderObject
)
{
renderObject
.
spacing
=
spacing
;
renderObject
.
textDirection
=
textDirection
;
}
@override
Iterable
<
CustomCbSlot
>
get
slots
=>
CustomCbSlot
.
values
;
}
class
RenderCustomCb
extends
RenderBox
with
SlottedContainerRenderObjectMixin
<
CustomCbSlot
,
RenderBox
>
{
RenderCustomCb
(
this
.
_spacing
,
this
.
_textDirection
);
double
_spacing
;
TextDirection
_textDirection
;
set
textDirection
(
TextDirection
value
)
{
if
(
_textDirection
==
value
)
{
return
;
}
_textDirection
=
value
;
markNeedsLayout
();
}
set
spacing
(
double
value
)
{
if
(
_spacing
==
value
)
{
return
;
}
_spacing
=
value
;
markNeedsLayout
();
}
RenderBox
?
get
rb
=>
childForSlot
(
CustomCbSlot
.
cb
);
RenderBox
?
get
body
=>
childForSlot
(
CustomCbSlot
.
child
);
Size
_layoutBox
(
RenderBox
box
,
BoxConstraints
constraints
)
{
box
.
layout
(
constraints
,
parentUsesSize:
true
);
return
box
.
size
;
}
@override
void
performLayout
()
{
if
(
rb
==
null
||
body
==
null
)
{
size
=
constraints
.
constrain
(
const
Size
(
50
,
10
));
return
;
}
rb
;
Size
rbSize
=
_layoutBox
(
rb
!,
const
BoxConstraints
(
maxWidth:
50
,
maxHeight:
20
));
Size
bodySize
=
_layoutBox
(
body
!,
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
rbSize
.
width
-
_spacing
));
if
(
_textDirection
==
TextDirection
.
ltr
)
{
body
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
rbSize
.
width
+
_spacing
,
0
);
rb
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
0
,
body
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
)!
-
rb
!.
size
.
height
/
1.5
);
}
else
{
body
!.
parentData
=
BoxParentData
()..
offset
=
Offset
(-
_spacing
,
0
);
rb
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
bodySize
.
width
,
body
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
)!
-
rb
!.
size
.
height
/
1.5
);
}
size
=
constraints
.
constrain
(
Size
(
bodySize
.
width
+
rbSize
.
width
+
_spacing
,
max
(
rbSize
.
height
,
bodySize
.
height
)));
}
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
context
.
paintChild
(
body
!,
offset
+
(
body
!.
parentData
as
BoxParentData
).
offset
);
context
.
paintChild
(
rb
!,
offset
+
(
rb
!.
parentData
as
BoxParentData
).
offset
);
}
@override
bool
hitTestSelf
(
Offset
position
)
{
return
true
;
}
@override
bool
hitTestChildren
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
for
(
final
RenderBox
child
in
children
)
{
final
BoxParentData
parentData
=
child
.
parentData
!
as
BoxParentData
;
final
bool
isHit
=
result
.
addWithPaintOffset
(
offset:
parentData
.
offset
,
position:
position
,
hitTest:
(
BoxHitTestResult
result
,
Offset
transformed
)
{
assert
(
transformed
==
position
-
parentData
.
offset
);
return
child
.
hitTest
(
result
,
position:
transformed
);
},
);
if
(
isHit
)
{
return
true
;
}
}
return
false
;
Widget
build
(
BuildContext
context
)
{
return
Directionality
(
textDirection:
textDirection
,
child:
Row
(
textBaseline:
TextBaseline
.
alphabetic
,
crossAxisAlignment:
CrossAxisAlignment
.
baseline
,
children:
[
Text
.
rich
(
WidgetSpan
(
alignment:
PlaceholderAlignment
.
middle
,
child:
Padding
(
padding:
EdgeInsetsDirectional
.
only
(
start:
spacing
,
end:
spacing
),
child:
Checkbox
(
value:
value
,
onChanged:
(
value
)
{}),
),
),
),
Expanded
(
child:
child
,
)
],
),
);
}
}
...
...
gpt_markdown/lib/custom_widgets/unordered_ordered_list.dart
View file @
e62829b
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
class
UnorderedListView
extends
SingleChildRenderObjectWidget
{
const
UnorderedListView
(
{
super
.
key
,
this
.
spacing
=
6
,
this
.
padding
=
10
,
this
.
bulletColor
,
this
.
bulletSize
=
4
,
this
.
textDirection
=
TextDirection
.
ltr
,
required
super
.
child
});
class
UnorderedListView
extends
StatelessWidget
{
const
UnorderedListView
({
super
.
key
,
this
.
spacing
=
8
,
this
.
padding
=
12
,
this
.
bulletColor
,
this
.
bulletSize
=
4
,
this
.
textDirection
=
TextDirection
.
ltr
,
required
this
.
child
,
});
final
double
bulletSize
;
final
double
spacing
;
final
double
padding
;
final
TextDirection
textDirection
;
final
Color
?
bulletColor
;
@override
RenderObject
createRenderObject
(
BuildContext
context
)
{
return
UnorderedListRenderObject
(
spacing
,
padding
,
bulletColor
??
Theme
.
of
(
context
).
colorScheme
.
onSurface
,
textDirection
,
bulletSize
,
final
Widget
child
;
@override
Widget
build
(
BuildContext
context
)
{
return
Directionality
(
textDirection:
textDirection
,
child:
Row
(
textBaseline:
TextBaseline
.
alphabetic
,
crossAxisAlignment:
CrossAxisAlignment
.
baseline
,
children:
[
if
(
bulletSize
==
0
)
SizedBox
(
width:
spacing
+
padding
,
)
else
Text
.
rich
(
WidgetSpan
(
alignment:
PlaceholderAlignment
.
middle
,
child:
Padding
(
padding:
EdgeInsetsDirectional
.
only
(
start:
padding
,
end:
spacing
),
child:
Container
(
width:
bulletSize
,
height:
bulletSize
,
decoration:
BoxDecoration
(
color:
bulletColor
,
shape:
BoxShape
.
circle
,
),
),
),
),
),
Expanded
(
child:
child
,
)
],
),
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
covariant
UnorderedListRenderObject
renderObject
)
{
renderObject
.
bulletColor
=
bulletColor
??
Theme
.
of
(
context
).
colorScheme
.
onSurface
;
renderObject
.
bulletSize
=
bulletSize
;
renderObject
.
spacing
=
spacing
;
renderObject
.
padding
=
padding
;
renderObject
.
textDirection
=
textDirection
;
}
}
class
UnorderedListRenderObject
extends
RenderProxyBox
{
UnorderedListRenderObject
(
double
spacing
,
double
padding
,
Color
bulletColor
,
TextDirection
textDirection
,
this
.
_bulletSize
,
{
RenderBox
?
child
,
})
:
_bulletColor
=
bulletColor
,
_spacing
=
spacing
,
_padding
=
padding
,
_textDirection
=
textDirection
,
super
(
child
);
double
_spacing
;
double
_padding
;
Offset
_bulletOffset
=
Offset
.
zero
;
TextDirection
_textDirection
;
set
spacing
(
double
value
)
{
if
(
_spacing
==
value
)
{
return
;
}
_spacing
=
value
;
markNeedsLayout
();
}
set
padding
(
double
value
)
{
if
(
_padding
==
value
)
{
return
;
}
_padding
=
value
;
markNeedsLayout
();
}
set
textDirection
(
TextDirection
value
)
{
if
(
_textDirection
==
value
)
{
return
;
}
_textDirection
=
value
;
markNeedsLayout
();
markNeedsPaint
();
}
Color
_bulletColor
;
double
_bulletSize
;
set
bulletSize
(
double
value
)
{
if
(
_bulletSize
==
value
)
{
return
;
}
_bulletSize
=
value
;
markNeedsLayout
();
}
set
bulletColor
(
Color
value
)
{
if
(
_bulletColor
==
value
)
{
return
;
}
_bulletColor
=
value
;
markNeedsLayout
();
}
@override
double
computeMinIntrinsicWidth
(
double
height
)
{
child
!.
layout
(
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
_spacing
-
6
-
_bulletSize
-
_padding
,
),
parentUsesSize:
true
);
return
child
!.
size
.
width
;
}
@override
double
computeMaxIntrinsicWidth
(
double
height
)
{
child
!.
layout
(
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
_spacing
-
6
-
_bulletSize
-
_padding
,
),
parentUsesSize:
true
);
return
child
!.
size
.
width
;
}
@override
double
computeMinIntrinsicHeight
(
double
width
)
{
child
!.
layout
(
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
_spacing
-
6
-
_bulletSize
-
_padding
,
),
parentUsesSize:
true
);
return
child
!.
size
.
height
;
}
@override
double
computeMaxIntrinsicHeight
(
double
width
)
{
child
!.
layout
(
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
_spacing
-
6
-
_bulletSize
-
_padding
,
),
parentUsesSize:
true
);
return
child
!.
size
.
height
;
}
@override
void
performLayout
()
{
super
.
performLayout
();
if
(
child
==
null
)
{
return
;
}
child
!.
layout
(
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
_spacing
-
6
-
_bulletSize
-
_padding
,
),
parentUsesSize:
true
);
if
(
_textDirection
==
TextDirection
.
ltr
)
{
child
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
_spacing
+
_padding
+
6
+
_bulletSize
,
0
);
var
value
=
child
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
);
_bulletOffset
=
Offset
(
4
+
_padding
,
value
!
-
_bulletSize
);
}
else
{
child
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(-
_spacing
-
_padding
+
6
+
_bulletSize
,
0
);
var
value
=
child
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
);
_bulletOffset
=
Offset
(
child
!.
size
.
width
-
4
+
_padding
,
value
!
-
_bulletSize
);
}
size
=
constraints
.
constrain
(
Size
(
child
!.
size
.
width
+
_spacing
+
_padding
+
6
+
_bulletSize
,
child
!.
size
.
height
));
}
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
==
null
)
{
return
;
}
if
(
_textDirection
==
TextDirection
.
ltr
)
{
context
.
paintChild
(
child
!,
offset
+
(
child
!.
parentData
as
BoxParentData
).
offset
);
context
.
canvas
.
drawCircle
(
offset
+
_bulletOffset
,
_bulletSize
,
Paint
()..
color
=
_bulletColor
);
}
else
{
context
.
paintChild
(
child
!,
offset
+
(
child
!.
parentData
as
BoxParentData
).
offset
);
context
.
canvas
.
drawCircle
(
offset
+
_bulletOffset
,
_bulletSize
,
Paint
()..
color
=
_bulletColor
);
}
}
@override
bool
hitTestSelf
(
Offset
position
)
{
return
false
;
}
@override
bool
hitTestChildren
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
Offset
offset
=
(
child
!.
parentData
as
BoxParentData
).
offset
;
return
result
.
addWithPaintOffset
(
offset:
offset
,
position:
position
,
hitTest:
(
result
,
newOffset
)
{
return
child
?.
hitTest
(
result
,
position:
newOffset
)
??
false
;
},
);
}
@override
bool
hitTest
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
return
hitTestChildren
(
result
,
position:
position
);
}
}
class
OrderedListView
extends
SingleChildRenderObjectWidget
{
class
OrderedListView
extends
StatelessWidget
{
final
String
no
;
final
double
spacing
;
final
double
padding
;
...
...
@@ -224,196 +65,36 @@ class OrderedListView extends SingleChildRenderObjectWidget {
this
.
spacing
=
6
,
this
.
padding
=
10
,
TextStyle
?
style
,
required
super
.
child
,
required
this
.
child
,
this
.
textDirection
=
TextDirection
.
ltr
,
required
this
.
no
})
:
_style
=
style
;
final
TextStyle
?
_style
;
final
TextDirection
textDirection
;
TextStyle
getStyle
(
BuildContext
context
)
{
if
(
_style
==
null
||
_style
!.
inherit
)
{
return
DefaultTextStyle
.
of
(
context
).
style
.
merge
(
_style
);
}
return
_style
!;
}
@override
RenderObject
createRenderObject
(
BuildContext
context
)
{
return
OrderedListRenderObject
(
no
,
spacing
,
padding
,
textDirection
,
getStyle
(
context
),
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
covariant
OrderedListRenderObject
renderObject
)
{
renderObject
.
no
=
no
;
renderObject
.
spacing
=
spacing
;
renderObject
.
padding
=
padding
;
renderObject
.
style
=
getStyle
(
context
);
renderObject
.
textDirection
=
textDirection
;
}
}
class
OrderedListRenderObject
extends
RenderProxyBox
{
OrderedListRenderObject
(
String
no
,
double
spacing
,
double
padding
,
TextDirection
textDirection
,
TextStyle
style
,
{
RenderBox
?
child
,
})
:
_no
=
no
,
_style
=
style
,
_spacing
=
spacing
,
_padding
=
padding
,
_textDirection
=
textDirection
,
super
(
child
);
double
_spacing
;
double
_padding
;
TextDirection
_textDirection
;
Offset
_ptOffset
=
Offset
.
zero
;
set
spacing
(
double
value
)
{
if
(
_spacing
==
value
)
{
return
;
}
_spacing
=
value
;
markNeedsLayout
();
}
set
padding
(
double
value
)
{
if
(
_padding
==
value
)
{
return
;
}
_padding
=
value
;
markNeedsLayout
();
}
set
textDirection
(
TextDirection
value
)
{
if
(
_textDirection
==
value
)
{
return
;
}
_textDirection
=
value
;
markNeedsLayout
();
markNeedsPaint
();
}
TextStyle
_style
;
set
style
(
TextStyle
value
)
{
_style
=
value
;
markNeedsLayout
();
}
String
_no
;
set
no
(
String
value
)
{
if
(
_no
==
value
)
{
return
;
}
_no
=
value
;
markNeedsLayout
();
}
@override
double
computeMinIntrinsicHeight
(
double
width
)
{
pt
=
TextPainter
(
text:
TextSpan
(
text:
_no
,
style:
_style
,
),
textDirection:
TextDirection
.
ltr
);
pt
.
layout
(
maxWidth:
constraints
.
maxWidth
-
50
-
_spacing
-
_padding
);
return
child
!
.
computeMinIntrinsicHeight
(
width
-
pt
.
width
-
_spacing
-
_padding
);
}
@override
double
computeMaxIntrinsicHeight
(
double
width
)
{
pt
=
TextPainter
(
text:
TextSpan
(
text:
_no
,
style:
_style
,
),
textDirection:
TextDirection
.
ltr
);
pt
.
layout
(
maxWidth:
constraints
.
maxWidth
-
50
-
_spacing
-
_padding
);
return
child
!
.
computeMaxIntrinsicHeight
(
width
-
pt
.
width
-
_spacing
-
_padding
);
}
late
TextPainter
pt
;
@override
void
performLayout
()
{
super
.
performLayout
();
if
(
child
==
null
)
{
return
;
}
pt
=
TextPainter
(
text:
TextSpan
(
text:
_no
,
style:
_style
,
),
textDirection:
TextDirection
.
ltr
);
pt
.
layout
(
maxWidth:
constraints
.
maxWidth
-
50
-
_spacing
-
_padding
);
child
!.
layout
(
BoxConstraints
(
maxWidth:
constraints
.
maxWidth
-
pt
.
width
-
_spacing
-
_padding
,
),
parentUsesSize:
true
);
if
(
_textDirection
==
TextDirection
.
ltr
)
{
child
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(
_spacing
+
_padding
+
pt
.
width
,
0
);
var
value
=
child
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
);
_ptOffset
=
Offset
(
_padding
,
value
!
-
pt
.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
));
}
else
{
child
!.
parentData
=
BoxParentData
()
..
offset
=
Offset
(-
_spacing
-
_padding
+
pt
.
width
,
0
);
var
value
=
child
!.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
);
_ptOffset
=
Offset
(
child
!.
size
.
width
+
_padding
-
4
,
value
!
-
pt
.
computeDistanceToActualBaseline
(
TextBaseline
.
alphabetic
));
}
size
=
constraints
.
constrain
(
Size
(
child
!.
size
.
width
+
_spacing
+
_padding
+
pt
.
width
,
child
!.
size
.
height
));
}
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
==
null
)
{
return
;
}
context
.
paintChild
(
child
!,
offset
+
(
child
!.
parentData
as
BoxParentData
).
offset
,
final
Widget
child
;
@override
Widget
build
(
BuildContext
context
)
{
return
Directionality
(
textDirection:
textDirection
,
child:
Row
(
textBaseline:
TextBaseline
.
alphabetic
,
crossAxisAlignment:
CrossAxisAlignment
.
baseline
,
children:
[
Padding
(
padding:
EdgeInsetsDirectional
.
only
(
start:
padding
,
end:
spacing
),
child:
Text
.
rich
(
TextSpan
(
text:
no
,
),
style:
_style
,
),
),
Expanded
(
child:
child
,
)
],
),
);
pt
.
paint
(
context
.
canvas
,
offset
+
_ptOffset
);
}
@override
bool
hitTestSelf
(
Offset
position
)
{
return
false
;
}
@override
bool
hitTestChildren
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
Offset
offset
=
(
child
!.
parentData
as
BoxParentData
).
offset
;
return
result
.
addWithPaintOffset
(
offset:
offset
,
position:
position
,
hitTest:
(
result
,
newOffset
)
{
return
child
?.
hitTest
(
result
,
position:
newOffset
)
??
false
;
},
);
}
@override
bool
hitTest
(
BoxHitTestResult
result
,
{
required
Offset
position
})
{
return
hitTestChildren
(
result
,
position:
position
);
}
}
...
...
gpt_markdown/lib/markdown_component.dart
View file @
e62829b
...
...
@@ -12,25 +12,26 @@ import 'md_widget.dart';
/// Markdown components
abstract
class
MarkdownComponent
{
static
List
<
MarkdownComponent
>
get
components
=>
[
CodeBlockMd
(),
NewLines
(),
TableMd
(),
HTag
(),
IndentMd
(),
UnOrderedList
(),
OrderedList
(),
RadioButtonMd
(),
CheckBoxMd
(),
HrLine
(),
ImageMd
(),
HighlightedText
(),
BoldMd
(),
ItalicMd
(),
LatexMathMultyLine
(),
LatexMath
(),
ATagMd
(),
SourceTag
(),
];
CodeBlockMd
(),
NewLines
(),
TableMd
(),
HTag
(),
IndentMd
(),
UnOrderedList
(),
OrderedList
(),
RadioButtonMd
(),
CheckBoxMd
(),
HrLine
(),
ImageMd
(),
HighlightedText
(),
StrikeMd
(),
BoldMd
(),
ItalicMd
(),
LatexMathMultyLine
(),
LatexMath
(),
ATagMd
(),
SourceTag
(),
];
/// Generate widget for markdown widget
static
List
<
InlineSpan
>
generate
(
...
...
@@ -329,8 +330,8 @@ class IndentMd extends BlockMd {
padding:
spaces
*
5
,
bulletSize:
0
,
textDirection:
config
.
textDirection
,
child:
RichText
(
text:
TextSpan
(
child:
Text
.
rich
(
TextSpan
(
children:
MarkdownComponent
.
generate
(
context
,
"
${match?[2]}
"
,
...
...
@@ -358,7 +359,7 @@ class UnOrderedList extends BlockMd {
bulletColor:
config
.
style
?.
color
??
DefaultTextStyle
.
of
(
context
).
style
.
color
,
padding:
10.0
,
bulletSize:
0.
2
*
bulletSize:
0.
4
*
(
config
.
style
?.
fontSize
??
DefaultTextStyle
.
of
(
context
).
style
.
fontSize
??
kDefaultFontSize
),
...
...
@@ -457,11 +458,40 @@ class BoldMd extends InlineMd {
);
}
}
class
StrikeMd
extends
InlineMd
{
@override
RegExp
get
exp
=>
RegExp
(
r"(?<!\*)\~\~(?<!\s)(.+?)(?<!\s)\~\~(?!\*)"
);
@override
InlineSpan
span
(
BuildContext
context
,
String
text
,
final
GptMarkdownConfig
config
,
)
{
var
match
=
exp
.
firstMatch
(
text
.
trim
());
var
conf
=
config
.
copyWith
(
style:
config
.
style
?.
copyWith
(
decoration:
TextDecoration
.
lineThrough
,
decorationColor:
config
.
style
?.
color
,
)
??
const
TextStyle
(
decoration:
TextDecoration
.
lineThrough
,
));
return
TextSpan
(
children:
MarkdownComponent
.
generate
(
context
,
"
${match?[1]}
"
,
conf
,
),
style:
conf
.
style
,
);
}
}
/// Italic text component
class
ItalicMd
extends
InlineMd
{
@override
RegExp
get
exp
=>
RegExp
(
r"(?<!\*)\*(?<!\s)(.+?)(?<!\s)\*(?!\*)"
,
dotAll:
true
);
RegExp
get
exp
=>
RegExp
(
r"(?<!\*)\*(?<!\s)(.+?)(?<!\s)\*(?!\*)"
,
dotAll:
true
);
@override
InlineSpan
span
(
...
...
Please
register
or
login
to post a comment