import 'package:flutter/material.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 createState() => _ToolbarWidgetState(); } class _ToolbarWidgetState extends State { List> fontSizeDropdownItems= []; List> qrSizeDropdownItems= []; @override void initState() { // TODO: implement initState super.initState(); populateFontSizeDropdownItems(); populateQrSizeDropdownItems(); } //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); }); } @override Widget build(BuildContext context) { final editorProvider = Provider.of(context); return Container( padding: EdgeInsets.symmetric(horizontal: 16), color: Colors.white, width: MediaQuery.of(context).size.width, height: 150, child: ListView( children: Provider.of(context).insertElementMode ? insertElementSection() : elementPropertiesSection(editorProvider), ), ); } List insertElementSection() { return [ Text('Insert Element'), SizedBox(height: 20), ElevatedButton( onPressed: Provider.of(context, listen: false).addTextElement, child: Text('Add Text Element') ), ElevatedButton( onPressed: Provider.of(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(context, listen: false).addProductNameElement, child: Text('Add Product Name Element') ), ElevatedButton( onPressed: Provider.of(context, listen: false).addVariantNameElement, child: Text('Add Variant Name Element') ), ElevatedButton( onPressed: Provider.of(context, listen: false).addProductionCodeElement, child: Text('Add Production Code Element') ), ElevatedButton( onPressed: Provider.of(context, listen: false).addProductionDateElement, child: Text('Add Production Date Element') ), ElevatedButton( onPressed: Provider.of(context, listen: false).addSerialNumberElement, child: Text('Add Serial Number Element') ), ]; } List elementPropertiesSection(Editor editorProvider) { final element = Provider.of(context).selectedElm; return [ Text('Properties'), SizedBox(height: 20), Text('Selected elements: ${Provider.of(context).selectedElmType}'), Text('Top: ${Provider.of(context, listen: true).selectedElm!.position.top}, Left: ${Provider.of(context, listen: true).selectedElm!.position.left}}'), SizedBox(height: 12), ...Provider.of(context).isVariableElement ? _variablePropertiesSection(editorProvider, element) : _commonPropertiesSection(editorProvider, element), ]; } List _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 _commonPropertiesSection(Editor editorProvider, ElementProperty? element) { return [ // ? Value Editor if([ElementType.text, ElementType.textbox].contains(editorProvider.selectedElm!.type)) TextField( readOnly: element!.isLocked, controller: element!.valueController, onTap: editorProvider.enableEdit, onEditingComplete: () { FocusManager.instance.primaryFocus?.unfocus(); editorProvider.disableEdit(); print('kepenjet'); }, onChanged: (value) { setState(() { }); }, ), if (editorProvider.selectedElm!.type != ElementType.qr) _buildElementRotatorButton(), // ? Font Resizer (Only show when selected element is [ElementType.text, ElementType.textbox]) if (Provider.of(context).shouldShowFontResizer) _buildFontResizerWidget(element), // ? Qr Resizer (Only show when selected element is ElementType.qr) if (Provider.of(context).shouldShowQrResizer) _buildQrResizerWidget(element), // ? Lock Element _buildElementPositionLockerButton(), // ? Delete elm button (only show when type is not ElementType.qr) if (Provider.of(context).shouldShowDeleteElementButton) _buildElementRemoverButton() ]; } Widget _buildFontResizerWidget(ElementProperty? element) { return Row( children: [ DropdownButton( value: element?.fontScale, items: fontSizeDropdownItems, onChanged: (val) { print('dropdown value: $val'); Provider.of(context, listen: false).changeFontSize(val); } ), IconButton.filled( onPressed: Provider.of(context, listen: false).incrementFontSize, icon: Icon(Icons.add) ), IconButton.filled( onPressed: Provider.of(context, listen: false).decrementFontSize, icon: Icon(Icons.remove) ), ], ); } Widget _buildQrResizerWidget(ElementProperty? element) { return Row( children: [ DropdownButton( value: element?.qrScale, items: qrSizeDropdownItems, onChanged: (val) { print('dropdown value: $val'); Provider.of(context, listen: false).changeQrSize(val); } ), IconButton.filled( onPressed: Provider.of(context, listen: false).incrementQrSize, icon: Icon(Icons.add) ), IconButton.filled( onPressed: Provider.of(context, listen: false).decrementQrSize, icon: Icon(Icons.remove) ), ], ); } Widget _buildElementRotatorButton() { return ElevatedButton( onPressed: Provider.of(context).rotate, child: Text('Rotate') ); } Widget _buildElementRemoverButton() { return ElevatedButton( style: ButtonStyle( backgroundColor: WidgetStatePropertyAll(Theme.of(context).colorScheme.errorContainer) ), onPressed: () async => Provider.of(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(context, listen: false).toggleLockElement(); FocusScope.of(context).unfocus(); }, child: Text( Provider.of(context).selectedElm!.isLocked ? 'Unlock Element' : 'Lock Element', ) ); } }