forked from psk907/fluttermoji
-
Notifications
You must be signed in to change notification settings - Fork 0
/
avatar_maker_customizer.dart
161 lines (142 loc) · 5.33 KB
/
avatar_maker_customizer.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import "package:avatar_maker/src/core/controllers/avatar_maker_controller.dart";
import "package:avatar_maker/src/core/enums/property_category_ids.dart";
import "package:avatar_maker/src/core/models/customized_property_category.dart";
import "package:avatar_maker/src/core/models/property_item.dart";
import "package:avatar_maker/src/core/models/theme_data.dart";
import "package:avatar_maker/src/customizer/widgets/customizer_body.dart";
import "package:flutter/material.dart";
import "package:get/get.dart";
import "package:get/get_state_manager/src/simple/list_notifier.dart";
/// This widget provides the user with a UI for customizing their Avatar_Maker
///
///*****
///Note: \
/// It is advised that a [AvatarMakerCircleAvatar] also be present in the same
/// page to show the user a preview of the changes being made.
class AvatarMakerCustomizer extends StatefulWidget {
/// To define the height of the component.
final double? scaffoldHeight;
/// To define the width of the component.
final double? scaffoldWidth;
/// Configuration for the overall visual theme for this widget
/// and the components within it.
final AvatarMakerThemeData theme;
/// List of all the customized property categories you want to use instead of
/// the default ones.
final List<CustomizedPropertyCategory>? customizedPropertyCategories;
/// Will save the selection automatically everytime the user selects
/// something when set to `true` .
///
/// If set to `false` you may want to implement a [AvatarMakerSaveWidget]
/// in your app to let users save their selection manually.
final bool autosave;
/// Creates a widget UI to customize the AvatarMaker
///
/// You may provide a [AvatarMakerThemeData] instance to adjust the appearance of this
/// widget to your app's theme.
///
/// Accepts optional [scaffoldHeight] and [scaffoldWidth] attributes
/// to override the default layout.
///
///*****
///Note: \
/// It is advised that a [AvatarMakerCircleAvatar] also be present in the same page.
/// to show the user a preview of the changes being made.
AvatarMakerCustomizer({
Key? key,
this.scaffoldHeight,
this.scaffoldWidth,
AvatarMakerThemeData? theme,
this.customizedPropertyCategories,
this.autosave = false,
}) : this.theme = theme ?? AvatarMakerThemeData.defaultTheme,
super(key: key);
@override
_AvatarMakerCustomizerState createState() => _AvatarMakerCustomizerState();
}
class _AvatarMakerCustomizerState extends State<AvatarMakerCustomizer>
with SingleTickerProviderStateMixin {
late AvatarMakerController avatarMakerController;
/// Number of displayed categories in the customizer widget.
late int nbrDisplayedCategories;
late TabController tabController;
/// To easily dispose of the listener on the dispose of the widget.
Disposer? avatarMakerControllerListenerDisposer;
@override
void initState() {
super.initState();
Get.put(AvatarMakerController(
customizedPropertyCategories: widget.customizedPropertyCategories));
final _controller = Get.find<AvatarMakerController>();
nbrDisplayedCategories = _controller.displayedPropertyCategories.length;
setState(() {
avatarMakerController = _controller;
tabController = TabController(
length: nbrDisplayedCategories,
vsync: this,
);
});
tabController.addListener(() {
setState(() {});
});
avatarMakerControllerListenerDisposer = _controller.addListener(() {
setState(() {});
});
}
@override
void dispose() {
// Dispose of the lister for the avatar maker controller.
if (avatarMakerControllerListenerDisposer != null) {
avatarMakerControllerListenerDisposer!();
}
// This ensures that unsaved edits are reverted
avatarMakerController.restoreState();
super.dispose();
}
/// On tap on a option, select the tapped option for the current category
/// selected.
void onTapOption(
PropertyItem newSelectedItem, PropertyCategoryIds categoryId) {
if (avatarMakerController.selectedOptions[categoryId] != newSelectedItem) {
setState(() {
avatarMakerController.selectedOptions[categoryId] = newSelectedItem;
});
avatarMakerController.updatePreview();
if (widget.autosave) {
avatarMakerController.saveAvatarSVG();
}
}
}
/// Move to the previous or the next tab, depending the direction of the
/// array.
/// isLeft = true - Go to the previous tab
/// isLeft = false - Go to the next tab
void onArrowTap(bool isLeft) {
int _currentIndex = tabController.index;
if (isLeft)
tabController
.animateTo(_currentIndex > 0 ? _currentIndex - 1 : _currentIndex);
else
tabController.animateTo(_currentIndex < nbrDisplayedCategories - 1
? _currentIndex + 1
: _currentIndex);
setState(() {});
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return SizedBox(
height:
widget.scaffoldHeight ?? (size.height * widget.theme.heightFactor),
width: widget.scaffoldWidth ?? size.width,
child: CustomizerBody(
avatarMakerController: avatarMakerController,
tabController: tabController,
theme: widget.theme,
scaffoldHeight: widget.scaffoldHeight,
onTapOption: onTapOption,
onArrowTap: onArrowTap,
),
);
}
}