|
@@ -23,6 +23,7 @@ class Editor extends ChangeNotifier {
|
23
|
23
|
|
24
|
24
|
final textboxResizerDeferredPointerHandlerLink = DeferredPointerHandlerLink();
|
25
|
25
|
|
|
26
|
+ String? valueOnStartEditing;
|
26
|
27
|
|
27
|
28
|
|
28
|
29
|
// ? Canvas State
|
|
@@ -55,29 +56,51 @@ class Editor extends ChangeNotifier {
|
55
|
56
|
|
56
|
57
|
|
57
|
58
|
|
58
|
|
- List<ElementProperty> elementProperties = [
|
59
|
|
- ElementProperty(
|
60
|
|
- id: uuid.v4(),
|
61
|
|
- valueController: TextEditingController(text: '{{QRCODE}}'),
|
62
|
|
- type: ElementType.qr,
|
63
|
|
- position: ElementPosition(top: 0, left: 0),
|
64
|
|
- width: 80,
|
65
|
|
- quarterTurns: 0,
|
66
|
|
- elementKey: GlobalKey(),
|
67
|
|
- qrScale: 3
|
68
|
|
- )
|
|
59
|
+ // List<ElementProperty> elementProperties = [
|
|
60
|
+ // ElementProperty(
|
|
61
|
+ // id: uuid.v4(),
|
|
62
|
+ // valueController: TextEditingController(text: '{{QRCODE}}'),
|
|
63
|
+ // type: ElementType.qr,
|
|
64
|
+ // position: ElementPosition(top: 0, left: 0),
|
|
65
|
+ // width: 80,
|
|
66
|
+ // quarterTurns: 0,
|
|
67
|
+ // elementKey: GlobalKey(),
|
|
68
|
+ // qrScale: 3
|
|
69
|
+ // )
|
|
70
|
+ // ];
|
|
71
|
+
|
|
72
|
+ // This list store all changes history, and currentCanvasState (stackState.last)
|
|
73
|
+ List<List<ElementState>> stateStack = [
|
|
74
|
+ // ? default state
|
|
75
|
+ [
|
|
76
|
+ ElementState(
|
|
77
|
+ id: uuid.v4(),
|
|
78
|
+ valueController: TextEditingController(text: '{{QRCODE}}'),
|
|
79
|
+ type: ElementType.qr,
|
|
80
|
+ position: ElementPosition(top: 0, left: 0),
|
|
81
|
+ width: 80,
|
|
82
|
+ quarterTurns: 0,
|
|
83
|
+ elementKey: GlobalKey(),
|
|
84
|
+ qrScale: 3
|
|
85
|
+ )
|
|
86
|
+ ]
|
69
|
87
|
];
|
70
|
88
|
|
|
89
|
+ // current canvas state
|
|
90
|
+ List<ElementState> get currentElementsState => stateStack.last;
|
|
91
|
+
|
71
|
92
|
|
72
|
93
|
|
73
|
94
|
|
74
|
95
|
// ? History stack
|
75
|
|
- List<CanvasHistory> undoStack = [];
|
76
|
|
- List<List<ElementProperty>> redoStack = [];
|
|
96
|
+ // List<CanvasHistory> undoStack = [];
|
|
97
|
+ List<List<ElementState>> redoStack = [];
|
|
98
|
+
|
77
|
99
|
|
|
100
|
+ void setNewElementsState(List<ElementState> newElementsState) {
|
|
101
|
+ _setNewStateTextEdit(newElementsState);
|
78
|
102
|
|
79
|
|
- void addUndoEntry(CanvasHistoryModifyType canvasHistoryType, List<ElementProperty> elementProperties) {
|
80
|
|
- undoStack.add(CanvasHistory(canvasHistoryType, _cloneCurrentState(elementProperties)));
|
|
103
|
+ stateStack.add(newElementsState);
|
81
|
104
|
|
82
|
105
|
redoStack.clear();
|
83
|
106
|
|
|
@@ -85,46 +108,47 @@ class Editor extends ChangeNotifier {
|
85
|
108
|
}
|
86
|
109
|
|
87
|
110
|
void undo() {
|
88
|
|
- addRedoEntry(elementProperties);
|
|
111
|
+ addRedoEntry(stateStack.last);
|
89
|
112
|
|
90
|
113
|
// apply to current state
|
91
|
|
- if (undoStack.last.type == CanvasHistoryModifyType.textEdit && undoStack.last.getState != elementProperties) {
|
92
|
|
- undoStack.removeLast();
|
93
|
|
- }
|
|
114
|
+ // if (undoStack.last.type == CanvasHistoryModifyType.textEdit && undoStack.last.getState != elementProperties) {
|
|
115
|
+ // undoStack.removeLast();
|
|
116
|
+ // }
|
94
|
117
|
|
95
|
|
- elementProperties = undoStack.last.getState;
|
|
118
|
+ // elementProperties = undoStack.last.getState;
|
|
119
|
+
|
|
120
|
+ stateStack.removeLast();
|
96
|
121
|
|
97
|
122
|
// unselect element
|
98
|
|
- if (elementProperties.firstWhereOrNull((e) => e.id == selectedElmId) == null) {
|
|
123
|
+ if (currentElementsState.firstWhereOrNull((e) => e.id == selectedElmId) == null) {
|
99
|
124
|
unSelectElm();
|
100
|
125
|
}
|
101
|
126
|
|
102
|
|
- undoStack.removeLast();
|
103
|
|
-
|
104
|
127
|
notifyListeners();
|
105
|
128
|
}
|
106
|
129
|
|
107
|
130
|
|
108
|
|
- void addRedoEntry(List<ElementProperty> elementProperties) {
|
109
|
|
- redoStack.add(_cloneCurrentState(elementProperties));
|
|
131
|
+ void addRedoEntry(List<ElementState> elementProperties) {
|
|
132
|
+ redoStack.add(_cloneElementsState(elementProperties));
|
110
|
133
|
|
111
|
134
|
notifyListeners();
|
112
|
135
|
}
|
113
|
136
|
|
114
|
137
|
void redo() {
|
115
|
|
- undoStack.add(CanvasHistory(CanvasHistoryModifyType.redo, _cloneCurrentState(elementProperties)));
|
|
138
|
+ // undoStack.add(CanvasHistory(CanvasHistoryModifyType.redo, _cloneCurrentState(elementProperties)));
|
|
139
|
+ stateStack.add(_cloneElementsState(redoStack.last));
|
116
|
140
|
|
117
|
141
|
// apply to current state
|
118
|
|
- elementProperties = redoStack.last;
|
|
142
|
+ // elementProperties = redoStack.last;
|
119
|
143
|
|
120
|
144
|
redoStack.removeLast();
|
121
|
145
|
|
122
|
146
|
notifyListeners();
|
123
|
147
|
}
|
124
|
148
|
|
125
|
|
- List<ElementProperty> _cloneCurrentState(List<ElementProperty> elementProperties) {
|
126
|
|
- List<ElementProperty> clonedElementProperties = elementProperties.map((elementProperty) {
|
127
|
|
- return ElementProperty(
|
|
149
|
+ List<ElementState> _cloneElementsState(List<ElementState> elementProperties) {
|
|
150
|
+ List<ElementState> clonedElementProperties = elementProperties.map((elementProperty) {
|
|
151
|
+ return ElementState(
|
128
|
152
|
id: elementProperty.id,
|
129
|
153
|
valueController: TextEditingController(text: elementProperty.valueController.text),
|
130
|
154
|
type: elementProperty.type,
|
|
@@ -150,7 +174,8 @@ class Editor extends ChangeNotifier {
|
150
|
174
|
canvasProperty.height = height;
|
151
|
175
|
canvasProperty.width = width;
|
152
|
176
|
|
153
|
|
- undoStack.clear();
|
|
177
|
+ // undoStack.clear();
|
|
178
|
+ stateStack = [currentElementsState];
|
154
|
179
|
redoStack.clear();
|
155
|
180
|
|
156
|
181
|
_adjustOutOfBoundElement();
|
|
@@ -161,7 +186,7 @@ class Editor extends ChangeNotifier {
|
161
|
186
|
}
|
162
|
187
|
|
163
|
188
|
void _adjustOutOfBoundElement() {
|
164
|
|
- for (var element in elementProperties) {
|
|
189
|
+ for (var element in currentElementsState) {
|
165
|
190
|
bool isOutOfBoundFromTop = (element.position.top + 10) > canvasProperty.height;
|
166
|
191
|
bool isOutOfBoundFromLeft = (element.position.left + 10) > canvasProperty.width;
|
167
|
192
|
|
|
@@ -182,16 +207,16 @@ class Editor extends ChangeNotifier {
|
182
|
207
|
|
183
|
208
|
}
|
184
|
209
|
|
185
|
|
- void populateElement(List<ElementProperty> elementProperties) {
|
186
|
|
- this.elementProperties.addAll(elementProperties);
|
187
|
|
- // _reservedIdUntil = this.elementProperties.length - 1;
|
188
|
|
- notifyListeners();
|
189
|
|
- }
|
190
|
210
|
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+ // ? Primitive Element
|
191
|
216
|
void addTextElement(){
|
192
|
217
|
String id = uuid.v4();
|
193
|
218
|
|
194
|
|
- ElementProperty element = ElementProperty(
|
|
219
|
+ ElementState newElement = ElementState(
|
195
|
220
|
id: id,
|
196
|
221
|
valueController: TextEditingController(text: 'Double tap to edit text'),
|
197
|
222
|
type: ElementType.text,
|
|
@@ -203,21 +228,20 @@ class Editor extends ChangeNotifier {
|
203
|
228
|
);
|
204
|
229
|
|
205
|
230
|
|
206
|
|
- // Save History
|
207
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
|
231
|
+ // Set State
|
|
232
|
+ // List<ElementState> newElementsState = [..._cloneElementsState(currentElementsState), newElement];
|
|
233
|
+ // setNewElementsState(newElementsState);
|
|
234
|
+ _setAddNewElementState(newElement);
|
208
|
235
|
|
209
|
236
|
|
210
|
|
- elementProperties.add(element);
|
211
|
|
- // _reservedIdUntil = elementProperties.length - 1;r
|
212
|
237
|
notifyListeners();
|
213
|
|
-
|
214
|
238
|
selectElmById(id);
|
215
|
239
|
}
|
216
|
240
|
|
217
|
241
|
void addTextboxElement() {
|
218
|
242
|
String id = uuid.v4();
|
219
|
243
|
|
220
|
|
- ElementProperty element = ElementProperty(
|
|
244
|
+ ElementState newElement = ElementState(
|
221
|
245
|
id: id,
|
222
|
246
|
valueController: TextEditingController(text: 'Double tap to edit text'),
|
223
|
247
|
type: ElementType.textbox,
|
|
@@ -227,21 +251,23 @@ class Editor extends ChangeNotifier {
|
227
|
251
|
elementKey: GlobalKey()
|
228
|
252
|
);
|
229
|
253
|
|
230
|
|
- // Save History
|
231
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
232
|
254
|
|
233
|
|
- elementProperties.add(element);
|
234
|
|
- notifyListeners();
|
|
255
|
+ // Set State
|
|
256
|
+ _setAddNewElementState(newElement);
|
235
|
257
|
|
|
258
|
+ notifyListeners();
|
236
|
259
|
selectElmById(id);
|
237
|
260
|
}
|
238
|
261
|
|
239
|
|
- // ? Variable Element
|
240
|
262
|
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+ // ? Variable Element
|
241
|
267
|
void addProductNameElement() {
|
242
|
268
|
String id = uuid.v4();
|
243
|
269
|
|
244
|
|
- ElementProperty element = ElementProperty(
|
|
270
|
+ ElementState newElement = ElementState(
|
245
|
271
|
id: id,
|
246
|
272
|
valueController: TextEditingController(text: '{{PRODUCTNAME}}'),
|
247
|
273
|
type: ElementType.textbox,
|
|
@@ -252,19 +278,17 @@ class Editor extends ChangeNotifier {
|
252
|
278
|
elementKey: GlobalKey()
|
253
|
279
|
);
|
254
|
280
|
|
255
|
|
- // Save History
|
256
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
|
281
|
+ // Set State
|
|
282
|
+ _setAddNewElementState(newElement);
|
257
|
283
|
|
258
|
|
- elementProperties.add(element);
|
259
|
284
|
notifyListeners();
|
260
|
|
-
|
261
|
285
|
selectElmById(id);
|
262
|
286
|
}
|
263
|
287
|
|
264
|
288
|
void addVariantNameElement() {
|
265
|
289
|
String id = uuid.v4();
|
266
|
290
|
|
267
|
|
- ElementProperty element = ElementProperty(
|
|
291
|
+ ElementState newElement = ElementState(
|
268
|
292
|
id: id,
|
269
|
293
|
valueController: TextEditingController(text: '{{VARIANTNAME}}'),
|
270
|
294
|
type: ElementType.textbox,
|
|
@@ -275,19 +299,17 @@ class Editor extends ChangeNotifier {
|
275
|
299
|
elementKey: GlobalKey()
|
276
|
300
|
);
|
277
|
301
|
|
278
|
|
- // Save History
|
279
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
|
302
|
+ // Set State
|
|
303
|
+ _setAddNewElementState(newElement);
|
280
|
304
|
|
281
|
|
- elementProperties.add(element);
|
282
|
305
|
notifyListeners();
|
283
|
|
-
|
284
|
306
|
selectElmById(id);
|
285
|
307
|
}
|
286
|
308
|
|
287
|
309
|
void addProductionCodeElement() {
|
288
|
310
|
String id = uuid.v4();
|
289
|
311
|
|
290
|
|
- ElementProperty element = ElementProperty(
|
|
312
|
+ ElementState newElement = ElementState(
|
291
|
313
|
id: id,
|
292
|
314
|
valueController: TextEditingController(text: '{{PRODUCTIONCODE}}'),
|
293
|
315
|
type: ElementType.textbox,
|
|
@@ -298,19 +320,17 @@ class Editor extends ChangeNotifier {
|
298
|
320
|
elementKey: GlobalKey()
|
299
|
321
|
);
|
300
|
322
|
|
301
|
|
- // Save History
|
302
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
|
323
|
+ // Set State
|
|
324
|
+ _setAddNewElementState(newElement);
|
303
|
325
|
|
304
|
|
- elementProperties.add(element);
|
305
|
326
|
notifyListeners();
|
306
|
|
-
|
307
|
327
|
selectElmById(id);
|
308
|
328
|
}
|
309
|
329
|
|
310
|
330
|
void addProductionDateElement() {
|
311
|
331
|
String id = uuid.v4();
|
312
|
332
|
|
313
|
|
- ElementProperty element = ElementProperty(
|
|
333
|
+ ElementState newElement = ElementState(
|
314
|
334
|
id: id,
|
315
|
335
|
valueController: TextEditingController(text: '{{PRODUCTIONDATE}}'),
|
316
|
336
|
type: ElementType.text,
|
|
@@ -322,18 +342,16 @@ class Editor extends ChangeNotifier {
|
322
|
342
|
);
|
323
|
343
|
|
324
|
344
|
// Save History
|
325
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
|
345
|
+ _setAddNewElementState(newElement);
|
326
|
346
|
|
327
|
|
- elementProperties.add(element);
|
328
|
347
|
notifyListeners();
|
329
|
|
-
|
330
|
348
|
selectElmById(id);
|
331
|
349
|
}
|
332
|
350
|
|
333
|
351
|
void addSerialNumberElement() {
|
334
|
352
|
String id = uuid.v4();
|
335
|
353
|
|
336
|
|
- ElementProperty element = ElementProperty(
|
|
354
|
+ ElementState newElement = ElementState(
|
337
|
355
|
id: id,
|
338
|
356
|
valueController: TextEditingController(text: '{{SERIALNUMBER}}'),
|
339
|
357
|
type: ElementType.text,
|
|
@@ -344,21 +362,19 @@ class Editor extends ChangeNotifier {
|
344
|
362
|
elementKey: GlobalKey()
|
345
|
363
|
);
|
346
|
364
|
|
347
|
|
- // Save History
|
348
|
|
- addUndoEntry(CanvasHistoryModifyType.add, elementProperties);
|
|
365
|
+ // Set State
|
|
366
|
+ _setAddNewElementState(newElement);
|
349
|
367
|
|
350
|
|
- elementProperties.add(element);
|
351
|
368
|
notifyListeners();
|
352
|
|
-
|
353
|
369
|
selectElmById(id);
|
354
|
370
|
}
|
355
|
|
-
|
|
371
|
+
|
356
|
372
|
|
357
|
373
|
|
358
|
374
|
|
359
|
375
|
|
360
|
376
|
void updateElmPosition(Offset offset) {
|
361
|
|
- ElementProperty? element = selectedElm;
|
|
377
|
+ ElementState? element = selectedElm;
|
362
|
378
|
|
363
|
379
|
if (element == null) return;
|
364
|
380
|
|
|
@@ -369,8 +385,42 @@ class Editor extends ChangeNotifier {
|
369
|
385
|
notifyListeners();
|
370
|
386
|
}
|
371
|
387
|
|
|
388
|
+ // Reset position after drag end
|
|
389
|
+ void resetElmPosition(ElementPosition? elementPosition) {
|
|
390
|
+ ElementState? element = selectedElm;
|
|
391
|
+
|
|
392
|
+ if (element == null) return;
|
|
393
|
+
|
|
394
|
+ if (elementPosition == null) return;
|
|
395
|
+
|
|
396
|
+ element.position = elementPosition;
|
|
397
|
+ }
|
|
398
|
+
|
|
399
|
+ void moveElement(Offset offset) {
|
|
400
|
+ log('[MOVING ELEMENT]');
|
|
401
|
+ ElementState? element = selectedElm;
|
|
402
|
+
|
|
403
|
+ if (element == null) return;
|
|
404
|
+
|
|
405
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
406
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
407
|
+
|
|
408
|
+ newElement.position.top += offset.dy.round();
|
|
409
|
+ newElement.position.left += offset.dx.round();
|
|
410
|
+
|
|
411
|
+ setNewElementsState(newElementsState);
|
|
412
|
+ }
|
|
413
|
+
|
|
414
|
+ ElementPosition getClonedElementPosition(ElementState element) {
|
|
415
|
+ return ElementPosition(
|
|
416
|
+ top: element.position.top,
|
|
417
|
+ left: element.position.left
|
|
418
|
+ );
|
|
419
|
+ }
|
|
420
|
+
|
|
421
|
+
|
372
|
422
|
void updateElmWitdh(double width) {
|
373
|
|
- ElementProperty? element = selectedElm;
|
|
423
|
+ ElementState? element = selectedElm;
|
374
|
424
|
|
375
|
425
|
if (element == null) return;
|
376
|
426
|
|
|
@@ -379,19 +429,51 @@ class Editor extends ChangeNotifier {
|
379
|
429
|
notifyListeners();
|
380
|
430
|
}
|
381
|
431
|
|
|
432
|
+ void commitTextboxResize(double width, double textboxDragStartWidth) {
|
|
433
|
+ if (selectedElm == null) return;
|
|
434
|
+
|
|
435
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
436
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
437
|
+
|
|
438
|
+ newElement.width = width;
|
|
439
|
+
|
|
440
|
+ // reset previous element
|
|
441
|
+ _resetPreviousTextboxWidth(selectedElm!, textboxDragStartWidth);
|
|
442
|
+
|
|
443
|
+ setNewElementsState(newElementsState);
|
|
444
|
+ }
|
|
445
|
+
|
|
446
|
+ void _resetPreviousTextboxWidth(ElementState previousElement, double textboxDragStartWidth) {
|
|
447
|
+ if (selectedElm == null) return;
|
|
448
|
+
|
|
449
|
+ previousElement.width = textboxDragStartWidth;
|
|
450
|
+ }
|
|
451
|
+
|
382
|
452
|
void toggleLockElement() {
|
383
|
453
|
if (selectedElm == null) return;
|
384
|
454
|
|
385
|
|
- // ? Save History
|
386
|
|
- addUndoEntry(CanvasHistoryModifyType.lock, elementProperties);
|
|
455
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
456
|
+ var selectedNewElement = newElementsState.firstWhere((e) => e.id == selectedElm!.id);
|
|
457
|
+
|
|
458
|
+ selectedNewElement.isLocked = !selectedNewElement.isLocked;
|
387
|
459
|
|
388
|
|
- selectedElm!.isLocked = !selectedElm!.isLocked;
|
|
460
|
+ setNewElementsState(newElementsState);
|
|
461
|
+
|
|
462
|
+ // selectedElm!.isLocked = !selectedElm!.isLocked;
|
389
|
463
|
notifyListeners();
|
390
|
464
|
}
|
391
|
465
|
|
|
466
|
+ bool shouldIgnoreTouch(String elementId) {
|
|
467
|
+ if (elementId == selectedElmId) return false;
|
|
468
|
+
|
|
469
|
+ if (selectedElmId == null) return false;
|
|
470
|
+
|
|
471
|
+ return true;
|
|
472
|
+ }
|
392
|
473
|
|
393
|
474
|
void selectElmById(String id) {
|
394
|
475
|
selectedElmId = id;
|
|
476
|
+ valueOnStartEditing = currentElementsState.firstWhere((e) => e.id == selectedElmId).valueController.text;
|
395
|
477
|
notifyListeners();
|
396
|
478
|
}
|
397
|
479
|
|
|
@@ -415,6 +497,7 @@ class Editor extends ChangeNotifier {
|
415
|
497
|
void unSelectElm() {
|
416
|
498
|
selectedElmId = null;
|
417
|
499
|
isEditing = false;
|
|
500
|
+ valueOnStartEditing = null;
|
418
|
501
|
notifyListeners();
|
419
|
502
|
}
|
420
|
503
|
|
|
@@ -424,25 +507,25 @@ class Editor extends ChangeNotifier {
|
424
|
507
|
|
425
|
508
|
// ? Getters
|
426
|
509
|
String get selectedElmType {
|
427
|
|
- if (elementProperties.isNotEmpty && selectedElmId != null) {
|
428
|
|
- final selectedElm = elementProperties.firstWhere((element) => element.id == selectedElmId);
|
|
510
|
+ if (currentElementsState.isNotEmpty && selectedElmId != null) {
|
|
511
|
+ final selectedElm = currentElementsState.firstWhere((element) => element.id == selectedElmId);
|
429
|
512
|
return elementGetter(selectedElm.type);
|
430
|
513
|
}
|
431
|
514
|
|
432
|
515
|
return '';
|
433
|
516
|
}
|
434
|
517
|
|
435
|
|
- ElementProperty? get selectedElm {
|
436
|
|
- if (elementProperties.isNotEmpty && selectedElmId != null) {
|
437
|
|
- return elementProperties.firstWhere((element) => element.id == selectedElmId);
|
|
518
|
+ ElementState? get selectedElm {
|
|
519
|
+ if (currentElementsState.isNotEmpty && selectedElmId != null) {
|
|
520
|
+ return currentElementsState.firstWhereOrNull((element) => element.id == selectedElmId);
|
438
|
521
|
}
|
439
|
522
|
|
440
|
523
|
return null;
|
441
|
524
|
}
|
442
|
525
|
|
443
|
526
|
GlobalKey? get selectedElmKey {
|
444
|
|
- if (elementProperties.isNotEmpty && selectedElmId != null) {
|
445
|
|
- return elementProperties.firstWhere((element) => element.id == selectedElmId).elementKey;
|
|
527
|
+ if (currentElementsState.isNotEmpty && selectedElmId != null) {
|
|
528
|
+ return currentElementsState.firstWhere((element) => element.id == selectedElmId).elementKey;
|
446
|
529
|
}
|
447
|
530
|
|
448
|
531
|
return null;
|
|
@@ -513,23 +596,25 @@ class Editor extends ChangeNotifier {
|
513
|
596
|
|
514
|
597
|
/// Can only rotate [ElementType.text, ElementType.textBox]
|
515
|
598
|
void rotate() {
|
516
|
|
- ElementProperty? element = selectedElm;
|
517
|
|
-
|
518
|
|
- if (element == null) return;
|
|
599
|
+ if (selectedElm == null) return;
|
519
|
600
|
|
520
|
|
- if (element.isLocked) {
|
|
601
|
+ if (selectedElm!.isLocked) {
|
521
|
602
|
_showLockedToast('Cant rotate locked element');
|
522
|
603
|
return;
|
523
|
604
|
}
|
524
|
605
|
|
525
|
|
- if (![ElementType.text, ElementType.textbox].contains(element.type)) return;
|
|
606
|
+ if (![ElementType.text, ElementType.textbox].contains(selectedElm!.type)) return;
|
526
|
607
|
|
527
|
|
- // ? Save history
|
528
|
|
- addUndoEntry(CanvasHistoryModifyType.rotate, elementProperties);
|
|
608
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
609
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+ if (newElement.type == ElementType.text) _rotateText(newElement);
|
|
613
|
+
|
|
614
|
+ if (newElement.type == ElementType.textbox) _rotateTextBox(newElement);
|
529
|
615
|
|
530
|
|
- if (element.type == ElementType.text) _rotateText(element);
|
531
|
616
|
|
532
|
|
- if (element.type == ElementType.textbox) _rotateTextBox(element);
|
|
617
|
+ setNewElementsState(newElementsState);
|
533
|
618
|
|
534
|
619
|
|
535
|
620
|
// Adjust Size
|
|
@@ -544,22 +629,26 @@ class Editor extends ChangeNotifier {
|
544
|
629
|
|
545
|
630
|
}
|
546
|
631
|
|
547
|
|
- void _rotateText(ElementProperty element) {
|
548
|
|
- if (element.quarterTurns < 3) {
|
549
|
|
- element.quarterTurns += 1;
|
550
|
|
- } else {
|
551
|
|
- element.quarterTurns = 0;
|
552
|
|
- }
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+ void editText(TextEditingController controller) {
|
|
636
|
+ if (selectedElm == null) return;
|
|
637
|
+
|
|
638
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
639
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
640
|
+
|
|
641
|
+ newElement.valueController.text = controller.text;
|
|
642
|
+ // newElement.valueController.selection = TextSelection.collapsed(offset: controller.selection.base.offset);
|
|
643
|
+
|
|
644
|
+ setNewElementsState(newElementsState);
|
553
|
645
|
}
|
554
|
646
|
|
555
|
|
- void _rotateTextBox(ElementProperty element) {
|
556
|
|
- if (element.quarterTurns == 0) {
|
557
|
|
- element.quarterTurns = 3;
|
558
|
|
- } else {
|
559
|
|
- element.quarterTurns = 0;
|
560
|
|
- }
|
|
647
|
+ void setValueOnStartEditing(String text) {
|
|
648
|
+ valueOnStartEditing = text;
|
561
|
649
|
}
|
562
|
650
|
|
|
651
|
+
|
563
|
652
|
// FontSize Handler
|
564
|
653
|
void changeFontSize(int? fontSize) {
|
565
|
654
|
if (fontSize == null) return;
|
|
@@ -571,10 +660,13 @@ class Editor extends ChangeNotifier {
|
571
|
660
|
return;
|
572
|
661
|
}
|
573
|
662
|
|
574
|
|
- // ? Save History
|
575
|
|
- addUndoEntry(CanvasHistoryModifyType.resize, elementProperties);
|
|
663
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
664
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
665
|
+
|
|
666
|
+ newElement.fontScale = fontSize;
|
|
667
|
+
|
|
668
|
+ setNewElementsState(newElementsState);
|
576
|
669
|
|
577
|
|
- selectedElm!.fontScale = fontSize;
|
578
|
670
|
notifyListeners();
|
579
|
671
|
}
|
580
|
672
|
|
|
@@ -589,10 +681,16 @@ class Editor extends ChangeNotifier {
|
589
|
681
|
}
|
590
|
682
|
// check if value is allowed for resize
|
591
|
683
|
if (CanvasStyle.fontSizeMap.containsKey(incrementTo)) {
|
592
|
|
- // ? Save History
|
593
|
|
- addUndoEntry(CanvasHistoryModifyType.resize, elementProperties);
|
|
684
|
+ // // ? Save History
|
|
685
|
+ // setNewElementsState(CanvasHistoryModifyType.resize, elementProperties);
|
|
686
|
+
|
|
687
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
688
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
689
|
+
|
|
690
|
+ // selectedElm!.fontScale = incrementTo;
|
|
691
|
+ newElement.fontScale = incrementTo;
|
594
|
692
|
|
595
|
|
- selectedElm!.fontScale = incrementTo;
|
|
693
|
+ setNewElementsState(newElementsState);
|
596
|
694
|
print('kepenjet increase');
|
597
|
695
|
} else {
|
598
|
696
|
print('cant increment');
|
|
@@ -612,15 +710,15 @@ class Editor extends ChangeNotifier {
|
612
|
710
|
}
|
613
|
711
|
// check if value is allowed for resize
|
614
|
712
|
if (CanvasStyle.fontSizeMap.containsKey(decrementTo)) {
|
615
|
|
- // ? Save History
|
616
|
|
- addUndoEntry(CanvasHistoryModifyType.resize, elementProperties);
|
|
713
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
714
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
617
|
715
|
|
618
|
|
- selectedElm!.fontScale = decrementTo;
|
|
716
|
+ newElement.fontScale = decrementTo;
|
|
717
|
+
|
|
718
|
+ setNewElementsState(newElementsState);
|
619
|
719
|
} else {
|
620
|
720
|
print('cant decrement');
|
621
|
721
|
}
|
622
|
|
-
|
623
|
|
- notifyListeners();
|
624
|
722
|
}
|
625
|
723
|
|
626
|
724
|
// Qr Size Handler
|
|
@@ -634,8 +732,13 @@ class Editor extends ChangeNotifier {
|
634
|
732
|
return;
|
635
|
733
|
}
|
636
|
734
|
|
637
|
|
- selectedElm!.qrScale = fontSize;
|
638
|
|
- notifyListeners();
|
|
735
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
736
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
737
|
+
|
|
738
|
+ // selectedElm!.qrScale = fontSize;
|
|
739
|
+ newElement.qrScale = fontSize;
|
|
740
|
+
|
|
741
|
+ setNewElementsState(newElementsState);
|
639
|
742
|
}
|
640
|
743
|
|
641
|
744
|
void incrementQrSize() {
|
|
@@ -651,12 +754,17 @@ class Editor extends ChangeNotifier {
|
651
|
754
|
}
|
652
|
755
|
// check if value is allowed for resize
|
653
|
756
|
if (CanvasStyle.qrSizeMap.containsKey(incrementTo)) {
|
654
|
|
- selectedElm!.qrScale = incrementTo;
|
|
757
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
758
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
759
|
+
|
|
760
|
+ // selectedElm!.qrScale = incrementTo;
|
|
761
|
+ newElement.qrScale = incrementTo;
|
|
762
|
+
|
|
763
|
+ setNewElementsState(newElementsState);
|
655
|
764
|
} else {
|
656
|
765
|
print('cant increment');
|
657
|
766
|
}
|
658
|
767
|
|
659
|
|
- notifyListeners();
|
660
|
768
|
}
|
661
|
769
|
|
662
|
770
|
void decrementQrSize() {
|
|
@@ -674,7 +782,13 @@ class Editor extends ChangeNotifier {
|
674
|
782
|
|
675
|
783
|
// check if value is allowed for resize
|
676
|
784
|
if (CanvasStyle.qrSizeMap.containsKey(decrementTo)) {
|
677
|
|
- selectedElm!.qrScale = decrementTo;
|
|
785
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
786
|
+ var newElement = newElementsState.firstWhere((e) => e.id == selectedElmId);
|
|
787
|
+
|
|
788
|
+ // selectedElm!.qrScale = decrementTo;
|
|
789
|
+ newElement.qrScale = decrementTo;
|
|
790
|
+
|
|
791
|
+ setNewElementsState(newElementsState);
|
678
|
792
|
} else {
|
679
|
793
|
print('cant decrement');
|
680
|
794
|
}
|
|
@@ -713,12 +827,22 @@ class Editor extends ChangeNotifier {
|
713
|
827
|
|
714
|
828
|
if (!shouldDelete) return;
|
715
|
829
|
|
716
|
|
- // ? Save History
|
717
|
|
- addUndoEntry(CanvasHistoryModifyType.remove, elementProperties);
|
|
830
|
+ // // ? Save History
|
|
831
|
+ // setNewElementsState(CanvasHistoryModifyType.remove, elementProperties);
|
718
|
832
|
|
719
|
|
- elementProperties.removeWhere((e) => e.id == selectedElm!.id);
|
720
|
|
- unSelectElm();
|
|
833
|
+ // elementProperties.removeWhere((e) => e.id == selectedElm!.id);
|
|
834
|
+
|
|
835
|
+ List<ElementState> newElementsState = _cloneElementsState(currentElementsState);
|
|
836
|
+ log('selectedElmId: ${selectedElm!.id}');
|
|
837
|
+
|
|
838
|
+ for (var i = 0; i < newElementsState.length; i++) {
|
|
839
|
+ log('element[$i]: ${newElementsState[i].id}');
|
|
840
|
+ }
|
|
841
|
+ newElementsState.removeWhere((e) => e.id == selectedElm!.id);
|
721
|
842
|
|
|
843
|
+ setNewElementsState(newElementsState);
|
|
844
|
+
|
|
845
|
+ unSelectElm();
|
722
|
846
|
notifyListeners();
|
723
|
847
|
}
|
724
|
848
|
|
|
@@ -730,22 +854,6 @@ class Editor extends ChangeNotifier {
|
730
|
854
|
// }
|
731
|
855
|
// }
|
732
|
856
|
|
733
|
|
- // ? helper method
|
734
|
|
- void _showLockedToast(String titleText) {
|
735
|
|
- toastification.show(
|
736
|
|
- title: Text(titleText),
|
737
|
|
- description: Text('unlock to change element property'),
|
738
|
|
- closeButtonShowType: CloseButtonShowType.none,
|
739
|
|
- style: ToastificationStyle.minimal,
|
740
|
|
- type: ToastificationType.warning,
|
741
|
|
- autoCloseDuration: const Duration(seconds: 3),
|
742
|
|
- alignment: Alignment.bottomCenter,
|
743
|
|
- dragToClose: true
|
744
|
|
- );
|
745
|
|
- }
|
746
|
|
-
|
747
|
|
-
|
748
|
|
-
|
749
|
857
|
|
750
|
858
|
// ? Template to JSON
|
751
|
859
|
String buildJSON() {
|
|
@@ -762,9 +870,9 @@ class Editor extends ChangeNotifier {
|
762
|
870
|
}
|
763
|
871
|
};
|
764
|
872
|
|
765
|
|
- for (var element in elementProperties) {
|
|
873
|
+ for (var element in currentElementsState) {
|
766
|
874
|
var elementMap = {
|
767
|
|
- 'id': uuid.v4(),
|
|
875
|
+ 'id': element.id,
|
768
|
876
|
'content': element.valueController.text,
|
769
|
877
|
'height': element.elementKey.currentContext?.size?.height.round() ?? 0,
|
770
|
878
|
'width': element.elementKey.currentContext?.size?.width.round() ?? 0,
|
|
@@ -793,7 +901,7 @@ class Editor extends ChangeNotifier {
|
793
|
901
|
}
|
794
|
902
|
|
795
|
903
|
|
796
|
|
- String _getElementTypeResult(ElementProperty element) {
|
|
904
|
+ String _getElementTypeResult(ElementState element) {
|
797
|
905
|
switch (element.type) {
|
798
|
906
|
case ElementType.text:
|
799
|
907
|
return 'text';
|
|
@@ -819,11 +927,68 @@ class Editor extends ChangeNotifier {
|
819
|
927
|
}
|
820
|
928
|
}
|
821
|
929
|
|
822
|
|
- int _getElementSizeResult(ElementProperty element) {
|
|
930
|
+ int _getElementSizeResult(ElementState element) {
|
823
|
931
|
if (element.type == ElementType.qr) {
|
824
|
932
|
return element.qrScale ?? 1;
|
825
|
933
|
}
|
826
|
934
|
|
827
|
935
|
return element.fontScale;
|
828
|
936
|
}
|
829
|
|
-}
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+ // ? Helper Method
|
|
944
|
+
|
|
945
|
+ void _setAddNewElementState(ElementState newElement) {
|
|
946
|
+ List<ElementState> newElementsState = [..._cloneElementsState(currentElementsState), newElement];
|
|
947
|
+ setNewElementsState(newElementsState);
|
|
948
|
+ }
|
|
949
|
+
|
|
950
|
+ void _rotateText(ElementState element) {
|
|
951
|
+ if (element.quarterTurns < 3) {
|
|
952
|
+ element.quarterTurns += 1;
|
|
953
|
+ } else {
|
|
954
|
+ element.quarterTurns = 0;
|
|
955
|
+ }
|
|
956
|
+ }
|
|
957
|
+
|
|
958
|
+ void _rotateTextBox(ElementState element) {
|
|
959
|
+ if (element.quarterTurns == 0) {
|
|
960
|
+ element.quarterTurns = 3;
|
|
961
|
+ } else {
|
|
962
|
+ element.quarterTurns = 0;
|
|
963
|
+ }
|
|
964
|
+ }
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+ void _showLockedToast(String titleText) {
|
|
968
|
+ toastification.show(
|
|
969
|
+ title: Text(titleText),
|
|
970
|
+ description: Text('unlock to change element property'),
|
|
971
|
+ closeButtonShowType: CloseButtonShowType.none,
|
|
972
|
+ style: ToastificationStyle.minimal,
|
|
973
|
+ type: ToastificationType.warning,
|
|
974
|
+ autoCloseDuration: const Duration(seconds: 3),
|
|
975
|
+ alignment: Alignment.bottomCenter,
|
|
976
|
+ dragToClose: true
|
|
977
|
+ );
|
|
978
|
+ }
|
|
979
|
+
|
|
980
|
+ void _setNewStateTextEdit(List<ElementState> newElementsState) {
|
|
981
|
+ log(selectedElm?.id ?? 'null');
|
|
982
|
+ if (selectedElm == null) return;
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+ var newElement = newElementsState.firstWhereOrNull((e) => e.id == selectedElmId);
|
|
986
|
+
|
|
987
|
+ if (newElement != null && [ElementType.text, ElementType.textbox].contains(newElement.type)) {
|
|
988
|
+ newElement.valueController.selection = TextSelection.collapsed(offset: selectedElm!.valueController.selection.base.offset);
|
|
989
|
+ }
|
|
990
|
+ }
|
|
991
|
+}
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+enum SetActionType { add, remove, move, resize, lock, rotate, textEdit, redo }
|