123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- import 'package:easy_debounce/easy_debounce.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_canvas_editor/history.dart';
- import 'package:flutter_canvas_editor/providers/editor.dart';
- import 'package:flutter_canvas_editor/style/canvas_style.dart';
- import 'package:flutter_canvas_editor/widgets/elements.dart';
- import 'package:provider/provider.dart';
- class ToolbarWidget extends StatefulWidget {
- const ToolbarWidget({
- super.key,
- });
- @override
- State<ToolbarWidget> createState() => _ToolbarWidgetState();
- }
- class _ToolbarWidgetState extends State<ToolbarWidget> {
- List<DropdownMenuItem<int>> fontSizeDropdownItems= [];
- List<DropdownMenuItem<int>> qrSizeDropdownItems= [];
- FocusNode? _focus = FocusNode();
- // String? _lastSavedText;
- @override
- void initState() {
- // TODO: implement initState
- super.initState();
- populateFontSizeDropdownItems();
- populateQrSizeDropdownItems();
- WidgetsBinding.instance.addPostFrameCallback((_) {
- _addFocusNodeListener();
- });
- }
- //functions
- void populateFontSizeDropdownItems() {
- CanvasStyle.fontSizeMap.forEach((key, val) {
- final item = DropdownMenuItem(
- value: key,
- child: Text(key.toString())
- );
- fontSizeDropdownItems.add(item);
- });
- }
- void populateQrSizeDropdownItems() {
- CanvasStyle.qrSizeMap.forEach((key, val) {
- final item = DropdownMenuItem(
- value: key,
- child: Text(key.toString())
- );
- qrSizeDropdownItems.add(item);
- });
- }
- void _addFocusNodeListener() {
- if (Provider.of<Editor>(context, listen: false).selectedElmKey != null && [ElementType.text, ElementType.textbox].contains(Provider.of<Editor>(context, listen: false).selectedElm!.type)) {
- _focus!.addListener(_onTextFieldFocusChange);
- }
- }
- void _onTextFieldFocusChange() {
- print('toolbar onfocus change');
- if (Provider.of<Editor>(context, listen: false).selectedElm?.lastSavedText != Provider.of<Editor>(context, listen: false).selectedElm?.valueController.text) {
- Provider.of<Editor>(context, listen: false).addUndoEntry(CanvasHistoryModifyType.textEdit, Provider.of<Editor>(context, listen: false).elementProperties);
- Provider.of<Editor>(context, listen: false).selectedElm?.lastSavedText = Provider.of<Editor>(context, listen: false).selectedElm?.valueController.text;
- }
- }
- void _removeFocusNodeListener() {
- if ([ElementType.text, ElementType.textbox].contains(Provider.of<Editor>(context).selectedElm!.type)) {
- _focus!.removeListener(_onTextFieldFocusChange);
- }
- }
- @override
- void dispose() {
- // TODO: implement dispose
- _removeFocusNodeListener();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- final editorProvider = Provider.of<Editor>(context);
- return Container(
- padding: EdgeInsets.symmetric(horizontal: 16),
- color: Colors.white,
- width: MediaQuery.of(context).size.width,
- height: 150,
- child: ListView(
- children: Provider.of<Editor>(context).insertElementMode ? insertElementSection() : elementPropertiesSection(editorProvider),
- ),
- );
- }
- List<Widget> insertElementSection() {
- return [
- Text('Insert Element'),
- SizedBox(height: 20),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addTextElement,
- child: Text('Add Text Element')
- ),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addTextboxElement,
- child: Text('Add Textbox Element')
- ),
- SizedBox(height: 24),
- // ? Variable Element Section
- Text('Insert Variable Element'),
- SizedBox(height: 24),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addProductNameElement,
- child: Text('Add Product Name Element')
- ),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addVariantNameElement,
- child: Text('Add Variant Name Element')
- ),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addProductionCodeElement,
- child: Text('Add Production Code Element')
- ),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addProductionDateElement,
- child: Text('Add Production Date Element')
- ),
- ElevatedButton(
- onPressed: Provider.of<Editor>(context, listen: false).addSerialNumberElement,
- child: Text('Add Serial Number Element')
- ),
- ];
- }
- List<Widget> elementPropertiesSection(Editor editorProvider) {
- final element = Provider.of<Editor>(context).selectedElm;
- return [
- Text('Properties'),
- SizedBox(height: 20),
- Text('Selected elements: ${Provider.of<Editor>(context).selectedElmType}'),
- Text('Top: ${Provider.of<Editor>(context, listen: true).selectedElm!.position.top}, Left: ${Provider.of<Editor>(context, listen: true).selectedElm!.position.left}}'),
- SizedBox(height: 12),
-
- ...Provider.of<Editor>(context).isVariableElement ? _variablePropertiesSection(editorProvider, element) : _commonPropertiesSection(editorProvider, element),
-
- ];
- }
- List<Widget> _variablePropertiesSection(Editor editorProvider, ElementProperty? element) {
- return [
- Container(
- margin: EdgeInsets.only(bottom: 16),
- color: Colors.grey[200],
- width: double.infinity,
- child: Text(
- 'This is a variable element, the value shown in editor is a placeholder. The actual value will be generated when printing the label.',
- )
- ),
- _buildElementRotatorButton(),
- // ? Font Resizer
- _buildFontResizerWidget(element),
- _buildElementPositionLockerButton(),
- _buildElementRemoverButton()
- ];
- }
- List<Widget> _commonPropertiesSection(Editor editorProvider, ElementProperty? element) {
- return [
- // ? Value Editor
- if([ElementType.text, ElementType.textbox].contains(editorProvider.selectedElm!.type)) TextField(
- focusNode: _focus,
- readOnly: element!.isLocked,
- controller: element!.valueController,
- onTap: editorProvider.enableEdit,
- onEditingComplete: () {
- FocusManager.instance.primaryFocus?.unfocus();
- editorProvider.disableEdit();
- print('kepenjet');
- },
- onChanged: (newText) {
- if (element.lastSavedText != null && newText != element.lastSavedText) {
- EasyDebounce.debounce(
- 'text-debounce-toolbar${element.id}',
- const Duration(milliseconds: 500),
- () {
- editorProvider.addUndoEntry(CanvasHistoryModifyType.textEdit, editorProvider.elementProperties);
- element.lastSavedText = newText;
- },
-
- );
- }
- setState(() {});
- },
- ),
-
- if (editorProvider.selectedElm!.type != ElementType.qr) _buildElementRotatorButton(),
- // ? Font Resizer (Only show when selected element is [ElementType.text, ElementType.textbox])
- if (Provider.of<Editor>(context).shouldShowFontResizer) _buildFontResizerWidget(element),
- // ? Qr Resizer (Only show when selected element is ElementType.qr)
- if (Provider.of<Editor>(context).shouldShowQrResizer) _buildQrResizerWidget(element),
- // ? Lock Element
- _buildElementPositionLockerButton(),
- // ? Delete elm button (only show when type is not ElementType.qr)
- if (Provider.of<Editor>(context).shouldShowDeleteElementButton) _buildElementRemoverButton()
- ];
- }
- Widget _buildFontResizerWidget(ElementProperty? element) {
- return Row(
- children: [
- DropdownButton<int>(
- value: element?.fontScale,
- items: fontSizeDropdownItems,
- onChanged: (val) {
- print('dropdown value: $val');
- Provider.of<Editor>(context, listen: false).changeFontSize(val);
- }
- ),
- IconButton.filled(
- onPressed: Provider.of<Editor>(context, listen: false).incrementFontSize,
- icon: Icon(Icons.add)
- ),
- IconButton.filled(
- onPressed: Provider.of<Editor>(context, listen: false).decrementFontSize,
- icon: Icon(Icons.remove)
- ),
- ],
- );
- }
- Widget _buildQrResizerWidget(ElementProperty? element) {
- return Row(
- children: [
- DropdownButton<int>(
- value: element?.qrScale,
- items: qrSizeDropdownItems,
- onChanged: (val) {
- print('dropdown value: $val');
- Provider.of<Editor>(context, listen: false).changeQrSize(val);
- }
- ),
- IconButton.filled(
- onPressed: Provider.of<Editor>(context, listen: false).incrementQrSize,
- icon: Icon(Icons.add)
- ),
- IconButton.filled(
- onPressed: Provider.of<Editor>(context, listen: false).decrementQrSize,
- icon: Icon(Icons.remove)
- ),
- ],
- );
- }
- Widget _buildElementRotatorButton() {
- return ElevatedButton(
- onPressed: Provider.of<Editor>(context).rotate,
- child: Text('Rotate')
- );
- }
- Widget _buildElementRemoverButton() {
- return ElevatedButton(
- style: ButtonStyle(
- backgroundColor: WidgetStatePropertyAll(Theme.of(context).colorScheme.errorContainer)
- ),
- onPressed: () async => Provider.of<Editor>(context, listen: false).deleteElement(context),
- child: Text(
- 'Delete Element',
- style: TextStyle(color: Theme.of(context).colorScheme.error),
- )
- );
- }
- Widget _buildElementPositionLockerButton() {
- return ElevatedButton(
- onPressed: () async {
- Provider.of<Editor>(context, listen: false).toggleLockElement();
- FocusScope.of(context).unfocus();
- },
- child: Text(
- Provider.of<Editor>(context).selectedElm!.isLocked ? 'Unlock Element' : 'Lock Element',
- )
- );
- }
- }
|