-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request: Custom appbar with built in functionalities #1
Comments
It is nice to hear that you like my package. I made some changes in the code. Now it's possible to add your buttons with existing functions. Because my package doesn't use a special state management package, we have to update the widgets that are dependent on the editor in a different way. Below is a complete example of how you can archive it with import 'dart:async';
import 'package:flutter/material.dart';
import 'package:pro_image_editor/pro_image_editor.dart';
class Demo extends StatefulWidget {
const Demo({super.key});
@override
State<Demo> createState() => DemoState();
}
class DemoState extends State<Demo> {
final _editorKey = GlobalKey<ProImageEditorState>();
late StreamController _updateAppBarStream;
@override
void initState() {
_updateAppBarStream = StreamController.broadcast();
super.initState();
}
@override
void dispose() {
_updateAppBarStream.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ProImageEditor.network(
'https://picsum.photos/id/237/2000',
key: _editorKey,
onImageEditingComplete: (byte) async {
Navigator.pop(context);
},
onUpdateUI: () {
_updateAppBarStream.add(null);
},
configs: ProImageEditorConfigs(
customWidgets: ImageEditorCustomWidgets(
appBar: AppBar(
automaticallyImplyLeading: false,
foregroundColor: Colors.white,
backgroundColor: Colors.black,
actions: [
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Cancel',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.close),
onPressed: _editorKey.currentState?.closeEditor,
);
}),
const Spacer(),
IconButton(
tooltip: 'Custom Icon',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(
Icons.bug_report,
color: Colors.white,
),
onPressed: () {},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Undo',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: Icon(
Icons.undo,
color: _editorKey.currentState?.canUndo == true ? Colors.white : Colors.white.withAlpha(80),
),
onPressed: _editorKey.currentState?.undoAction,
);
},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Redo',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: Icon(
Icons.redo,
color: _editorKey.currentState?.canRedo == true ? Colors.white : Colors.white.withAlpha(80),
),
onPressed: _editorKey.currentState?.redoAction,
);
},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Done',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.done),
iconSize: 28,
onPressed: _editorKey.currentState?.doneEditing,
);
}),
],
),
appBarPaintingEditor: AppBar(
automaticallyImplyLeading: false,
foregroundColor: Colors.white,
backgroundColor: Colors.black,
actions: [
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.arrow_back),
onPressed: _editorKey.currentState?.paintingEditor.currentState?.close,
);
}),
const SizedBox(width: 80),
const Spacer(),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(
Icons.line_weight_rounded,
color: Colors.white,
),
onPressed: _editorKey.currentState?.paintingEditor.currentState?.openLineWeightBottomSheet,
);
}),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: Icon(
_editorKey.currentState?.paintingEditor.currentState?.fillBackground == true
? Icons.format_color_reset
: Icons.format_color_fill,
color: Colors.white,
),
onPressed: _editorKey.currentState?.paintingEditor.currentState?.toggleFill);
}),
const Spacer(),
IconButton(
tooltip: 'Custom Icon',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(
Icons.bug_report,
color: Colors.white,
),
onPressed: () {},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Undo',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: Icon(
Icons.undo,
color: _editorKey.currentState?.paintingEditor.currentState?.canUndo == true ? Colors.white : Colors.white.withAlpha(80),
),
onPressed: _editorKey.currentState?.paintingEditor.currentState?.undoAction,
);
}),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Redo',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: Icon(
Icons.redo,
color: _editorKey.currentState?.paintingEditor.currentState?.canRedo == true ? Colors.white : Colors.white.withAlpha(80),
),
onPressed: _editorKey.currentState?.paintingEditor.currentState?.redoAction,
);
}),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Done',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.done),
iconSize: 28,
onPressed: _editorKey.currentState?.paintingEditor.currentState?.done,
);
}),
],
),
appBarTextEditor: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
foregroundColor: Colors.white,
actions: [
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.arrow_back),
onPressed: _editorKey.currentState?.textEditor.currentState?.close,
);
}),
const Spacer(),
IconButton(
tooltip: 'Custom Icon',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(
Icons.bug_report,
color: Colors.white,
),
onPressed: () {},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
onPressed: _editorKey.currentState?.textEditor.currentState?.toggleTextAlign,
icon: Icon(
_editorKey.currentState?.textEditor.currentState?.align == TextAlign.left
? Icons.align_horizontal_left_rounded
: _editorKey.currentState?.textEditor.currentState?.align == TextAlign.right
? Icons.align_horizontal_right_rounded
: Icons.align_horizontal_center_rounded,
),
);
}),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
onPressed: _editorKey.currentState?.textEditor.currentState?.toggleBackgroundMode,
icon: const Icon(Icons.layers_rounded),
);
}),
const Spacer(),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.done),
iconSize: 28,
onPressed: _editorKey.currentState?.textEditor.currentState?.done,
);
}),
],
),
appBarCropRotateEditor: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
foregroundColor: Colors.white,
actions: [
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.arrow_back),
onPressed: _editorKey.currentState?.cropRotateEditor.currentState?.close,
);
}),
const Spacer(),
IconButton(
tooltip: 'Custom Icon',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(
Icons.bug_report,
color: Colors.white,
),
onPressed: () {},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
icon: const Icon(Icons.rotate_90_degrees_ccw_outlined),
onPressed: _editorKey.currentState?.cropRotateEditor.currentState?.rotate,
);
}),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
key: const ValueKey('pro-image-editor-aspect-ratio-btn'),
icon: const Icon(Icons.crop),
onPressed: _editorKey.currentState?.cropRotateEditor.currentState?.openAspectRatioOptions,
);
}),
const Spacer(),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.done),
iconSize: 28,
onPressed: _editorKey.currentState?.cropRotateEditor.currentState?.done,
);
}),
],
),
appBarFilterEditor: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
foregroundColor: Colors.white,
actions: [
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.arrow_back),
onPressed: _editorKey.currentState?.filterEditor.currentState?.close,
);
}),
const Spacer(),
IconButton(
tooltip: 'Custom Icon',
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(
Icons.bug_report,
color: Colors.white,
),
onPressed: () {},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
padding: const EdgeInsets.symmetric(horizontal: 8),
icon: const Icon(Icons.done),
iconSize: 28,
onPressed: _editorKey.currentState?.filterEditor.currentState?.done,
);
}),
],
),
),
),
);
}
}
|
Everything working fine. Thank you very much for your prompt response. The only issue is that I get "The getter 'canRedo' isn't defined for the type 'ProImageEditorState'. |
Thank you for your feedback. _editorKey.currentState?.canRedo == true Even though the value is a boolean, on the first frame, the state is null. So, to check if it's true, we need to use To your question if it's possible to modify the import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:pro_image_editor/models/paint_editor/paint_bottom_bar_item.dart';
import 'package:pro_image_editor/models/theme/theme_shared_values.dart';
import 'package:pro_image_editor/pro_image_editor.dart';
import 'package:pro_image_editor/widgets/flat_icon_text_button.dart';
import 'package:pro_image_editor/widgets/pro_image_editor_desktop_mode.dart';
class Demo extends StatefulWidget {
const Demo({super.key});
@override
State<Demo> createState() => DemoState();
}
class DemoState extends State<Demo> {
final _editorKey = GlobalKey<ProImageEditorState>();
late StreamController _updateUIStream;
late ScrollController _bottomBarScrollCtrl;
@override
void initState() {
_updateUIStream = StreamController.broadcast();
_bottomBarScrollCtrl = ScrollController();
super.initState();
}
@override
void dispose() {
_updateUIStream.close();
_bottomBarScrollCtrl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var bottomTextStyle = const TextStyle(fontSize: 10.0, color: Colors.white);
List<PaintModeBottomBarItem> paintModes = [
const PaintModeBottomBarItem(
mode: PaintModeE.freeStyle,
icon: Icons.edit,
label: 'Freestyle',
),
const PaintModeBottomBarItem(
mode: PaintModeE.arrow,
icon: Icons.arrow_right_alt_outlined,
label: 'Arrow',
),
const PaintModeBottomBarItem(
mode: PaintModeE.line,
icon: Icons.horizontal_rule,
label: 'Line',
),
const PaintModeBottomBarItem(
mode: PaintModeE.rect,
icon: Icons.crop_free,
label: 'Rectangle',
),
const PaintModeBottomBarItem(
mode: PaintModeE.circle,
icon: Icons.lens_outlined,
label: 'Circle',
),
const PaintModeBottomBarItem(
mode: PaintModeE.dashLine,
icon: Icons.power_input,
label: 'Dash line',
),
];
return LayoutBuilder(builder: (context, constraints) {
return ProImageEditor.network(
'https://picsum.photos/id/237/2000',
key: _editorKey,
onImageEditingComplete: (byte) async {},
onUpdateUI: () {
_updateUIStream.add(null);
},
configs: ProImageEditorConfigs(
customWidgets: ImageEditorCustomWidgets(
bottomNavigationBar: StreamBuilder(
stream: _updateUIStream.stream,
builder: (_, __) {
return Scrollbar(
controller: _bottomBarScrollCtrl,
scrollbarOrientation: ScrollbarOrientation.top,
thickness: isDesktop ? null : 0,
child: BottomAppBar(
/// kToolbarHeight is important that helperlines will work
height: kToolbarHeight,
color: Colors.black,
padding: EdgeInsets.zero,
child: Center(
child: SingleChildScrollView(
controller: _bottomBarScrollCtrl,
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: min(constraints.maxWidth, 500),
maxWidth: 500,
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FlatIconTextButton(
label: Text('Paint', style: bottomTextStyle),
icon: const Icon(
Icons.edit_rounded,
size: 22.0,
color: Colors.white,
),
onPressed: _editorKey.currentState?.openPaintingEditor,
),
FlatIconTextButton(
label: Text('Text', style: bottomTextStyle),
icon: const Icon(
Icons.text_fields,
size: 22.0,
color: Colors.white,
),
onPressed: _editorKey.currentState?.openTextEditor,
),
FlatIconTextButton(
label: Text('My Button', style: bottomTextStyle.copyWith(color: Colors.amber)),
icon: const Icon(
Icons.new_releases_outlined,
size: 22.0,
color: Colors.amber,
),
onPressed: () {},
),
FlatIconTextButton(
label: Text('Crop/ Rotate', style: bottomTextStyle),
icon: const Icon(
Icons.crop_rotate_rounded,
size: 22.0,
color: Colors.white,
),
onPressed: _editorKey.currentState?.openCropEditor,
),
FlatIconTextButton(
label: Text('Filter', style: bottomTextStyle),
icon: const Icon(
Icons.filter,
size: 22.0,
color: Colors.white,
),
onPressed: _editorKey.currentState?.openFilterEditor,
),
FlatIconTextButton(
label: Text('Emoji', style: bottomTextStyle),
icon: const Icon(
Icons.sentiment_satisfied_alt_rounded,
size: 22.0,
color: Colors.white,
),
onPressed: _editorKey.currentState?.openEmojiEditor,
),
/* Be careful with the sticker editor. It's important you add
your own logic how to load items in `stickerEditorConfigs`.
FlatIconTextButton(
key: const ValueKey('open-sticker-editor-btn'),
label: Text('Sticker', style: bottomTextStyle),
icon: const Icon(
Icons.layers_outlined,
size: 22.0,
color: Colors.white,
),
onPressed: _editorKey.currentState?.openStickerEditor,
), */
],
),
),
),
),
),
),
);
}),
bottomBarPaintingEditor: StreamBuilder(
stream: _updateUIStream.stream,
builder: (_, __) {
return Scrollbar(
controller: _bottomBarScrollCtrl,
scrollbarOrientation: ScrollbarOrientation.top,
thickness: isDesktop ? null : 0,
child: BottomAppBar(
height: kToolbarHeight,
color: Colors.black,
padding: EdgeInsets.zero,
child: Center(
child: SingleChildScrollView(
controller: _bottomBarScrollCtrl,
scrollDirection: Axis.horizontal,
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: min(MediaQuery.of(context).size.width, 500),
maxWidth: 500,
),
child: Wrap(
direction: Axis.horizontal,
alignment: WrapAlignment.spaceAround,
children: <Widget>[
FlatIconTextButton(
label: Text('My Button', style: bottomTextStyle.copyWith(color: Colors.amber)),
icon: const Icon(
Icons.new_releases_outlined,
size: 22.0,
color: Colors.amber,
),
onPressed: () {},
),
...List.generate(
paintModes.length,
(index) => Builder(
builder: (_) {
var item = paintModes[index];
var color = _editorKey.currentState?.paintingEditor.currentState?.paintMode == item.mode
? imageEditorPrimaryColor
: const Color(0xFFEEEEEE);
return FlatIconTextButton(
label: Text(
item.label,
style: TextStyle(fontSize: 10.0, color: color),
),
icon: Icon(item.icon, color: color),
onPressed: () {
_editorKey.currentState?.paintingEditor.currentState?.setMode(item.mode);
setState(() {});
},
);
},
),
),
],
),
),
),
),
),
);
},
),
),
),
);
});
}
}
|
Yeah you were right. The getters are there after upgrading to 2.2.0. the only issue is that now I get an error when applying changes from the navigator : |
Thank you for your feedback. |
Sure no problem, I am currently working on Android Emulator Api version 33. final _editor = GlobalKey<ProImageEditorState>();
late StreamController _updateAppBarStream;
@override
void initState() {
super.initState();
_updateAppBarStream = StreamController.broadcast();
cameraController.getStickers();
}
@override
void dispose() {
_updateAppBarStream.close();
super.dispose();
}
ProImageEditor.file(
File(cameraController.editAsset.value.path),
key: _editor,
onImageEditingComplete:
(Uint8List bytes) async {
final directory =
await getApplicationDocumentsDirectory();
if (!File(
"${directory.path}/${cameraController.editAsset.value.name}")
.existsSync()) {
File(directory.path +
cameraController
.editAsset.value.name)
.createSync(recursive: true);
}
File("${directory.path}/${cameraController.editAsset.value.name}")
.writeAsBytesSync(bytes);
var index = cameraController.selectedFiles
.indexWhere((element) =>
element.path ==
cameraController
.editAsset.value.path);
cameraController.selectedFiles[index] = XFile(
"${directory.path}/${cameraController.editAsset.value.name}");
cameraController.selectedFiles.refresh();
Get.back();
return;
},
configs: ProImageEditorConfigs(
activePreferredOrientations: [
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
],
i18n: const I18n(
various: I18nVarious(),
paintEditor: I18nPaintingEditor(),
textEditor: I18nTextEditor(),
cropRotateEditor: I18nCropRotateEditor(),
filterEditor: I18nFilterEditor(
filters: I18nFilters()),
emojiEditor: I18nEmojiEditor(),
stickerEditor: I18nStickerEditor(),
// More translations...
),
helperLines: const HelperLines(
showVerticalLine: true,
showHorizontalLine: true,
showRotateLine: true,
hitVibration: true,
),
customWidgets: ImageEditorCustomWidgets(
appBar: AppBar(
automaticallyImplyLeading: false,
leading: Row(children: [
GestureDetector(
child: const Icon(Icons.chevron_left,
size: 25.0, color: Colors.white),
onTap: () {
Get.back();
},
),
isImage
? const SizedBox()
: GestureDetector(
onTap: () {
var index = cameraController
.selectedFiles
.indexWhere((element) =>
element.path ==
cameraController
.editAsset
.value
.path);
cameraController.selectedFiles
.removeAt(index);
cameraController.selectedFiles
.refresh();
cameraController.fetchAssets();
Get.back();
},
child: Icon(
FluentIcons.delete_48_regular,
color: white,
size: 25,
))
]),
foregroundColor: Colors.white,
backgroundColor: dark,
actions: [
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Undo',
padding: const EdgeInsets.symmetric(
horizontal: 8),
icon: Icon(
FluentIcons.arrow_undo_48_regular,
color: _editor
.currentState
?.paintingEditor
.currentState
?.canUndo ==
true
? Colors.white
: Colors.white.withAlpha(80),
),
onPressed: _editor
.currentState?.undoAction,
);
},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Redo',
padding: const EdgeInsets.symmetric(
horizontal: 8),
icon: Icon(
FluentIcons.arrow_redo_48_regular,
color: _editor
.currentState
?.paintingEditor
.currentState
?.canRedo ==
true
? Colors.white
: Colors.white.withAlpha(80),
),
onPressed: _editor
.currentState?.redoAction,
);
},
),
StreamBuilder(
stream: _updateAppBarStream.stream,
builder: (_, __) {
return IconButton(
tooltip: 'Done',
padding:
const EdgeInsets.symmetric(
horizontal: 8),
icon: const Icon(FluentIcons
.checkmark_48_regular),
iconSize: 28,
onPressed: _editor
.currentState?.doneEditing,
);
}),
],
)),
imageEditorTheme: ImageEditorTheme(
layerHoverCursor: SystemMouseCursors.move,
helperLine: HelperLineTheme(
horizontalColor: green,
verticalColor: green,
rotateColor: red,
),
paintingEditor: const PaintingEditorTheme(),
textEditor: const TextEditorTheme(),
cropRotateEditor:
const CropRotateEditorTheme(),
filterEditor: const FilterEditorTheme(),
emojiEditor: const EmojiEditorTheme(),
stickerEditor: const StickerEditorTheme(),
background: dark,
loadingDialogTextColor: light,
uiOverlayStyle: SystemUiOverlayStyle(
statusBarColor: dark,
statusBarIconBrightness: Brightness.light,
systemNavigationBarIconBrightness:
Brightness.light,
statusBarBrightness: Brightness.dark,
systemNavigationBarColor: dark,
),
),
icons: const ImageEditorIcons(
paintingEditor: IconsPaintingEditor(
bottomNavBar:
FluentIcons.paint_bucket_24_regular,
lineWeight: FluentIcons
.line_thickness_24_regular,
freeStyle: FluentIcons.pen_48_regular,
arrow:
FluentIcons.arrow_right_48_regular,
line: FluentIcons
.line_horizontal_1_28_regular,
fill: FluentIcons.color_fill_28_filled,
noFill:
FluentIcons.color_fill_28_regular,
rectangle: FluentIcons
.rectangle_landscape_48_regular,
circle: FluentIcons.circle_48_regular,
dashLine:
FluentIcons.line_dashes_48_regular),
textEditor: IconsTextEditor(),
cropRotateEditor: IconsCropRotateEditor(),
filterEditor: IconsFilterEditor(),
emojiEditor: IconsEmojiEditor(),
stickerEditor: IconsStickerEditor(),
closeEditor:
FluentIcons.chevron_left_48_regular,
doneIcon: FluentIcons.checkmark_48_regular,
applyChanges:
FluentIcons.checkmark_48_regular,
backButton:
FluentIcons.arrow_left_48_regular,
undoAction:
FluentIcons.arrow_undo_48_regular,
redoAction:
FluentIcons.arrow_redo_48_regular,
removeElementZone:
FluentIcons.delete_48_regular,
),
paintEditorConfigs:
const PaintEditorConfigs(),
textEditorConfigs: const TextEditorConfigs(),
cropRotateEditorConfigs:
const CropRotateEditorConfigs(),
filterEditorConfigs: const FilterEditorConfigs(
// filterList: [
// ColorFilterGenerator(
// name: "CustomFilter",
// filters: [
// ColorFilterAddons.brightness(.1),
// ColorFilterAddons.contrast(.1),
// ColorFilterAddons.saturation(.15),
// ])
// ]
),
emojiEditorConfigs:
const EmojiEditorConfigs(),
stickerEditorConfigs: StickerEditorConfigs(
enabled: true,
buildStickers: (setLayer) {
return ClipRRect(
borderRadius:
const BorderRadius.vertical(
top: Radius.circular(20)),
child: Container(
color: const Color.fromARGB(
255, 224, 239, 251),
child: Obx(
() => GridView.builder(
padding:
const EdgeInsets.all(16),
gridDelegate:
const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemCount: cameraController
.stickers.length,
shrinkWrap: true,
itemBuilder: (context, index) {
Widget widget = ClipRRect(
borderRadius:
BorderRadius.circular(
7),
child: Image.network(
cameraController
.stickers[index]
.stickerImage!,
width: 120,
height: 120,
fit: BoxFit.cover,
),
);
return GestureDetector(
onTap: () =>
setLayer(widget),
child: MouseRegion(
cursor: SystemMouseCursors
.click,
child: widget,
),
);
},
),
),
));
},
),
designMode: ImageEditorDesignModeE.material,
heroTag: 'hero',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: green,
brightness: Brightness.dark,
),
),
),
) I did not put the whole build method as I have a lot of unrelated stuff in there. But this is the usage of the library |
Thanks for sharing. |
Yes everything good now. Thank you very much for all the support and keep up the good work! |
I want to thank you for this awesome package. We have the following scenario: We would like to put some custom buttons on the appbar and still have the built in functionalities.(undo,redo, apply) Is there a way we can achieve this?
The text was updated successfully, but these errors were encountered: