====================================== UI Components and Integration ====================================== SpWML provides several ways to integrate with Flutter, depending on your needs. SpWMLView (Recommended for Screens) ===================================== Added in version 46.4.0. This is the most efficient way to build a complete screen. It automatically handles the lifecycle of the **StateManager** and supports asynchronous asset loading. .. code-block:: dart @override Widget build(BuildContext context) { return SpWMLView( pathBuilder: (_) => "assets/layout.spwml", onSetup: (context, builder, scope) { final btn = builder.getSID("myButton") as BtnElement; btn.setCallback(() { // Your logic }); }, ); } SpWML (Basic Widget) ===================== Use this when you want to display a SpWML string immediately as a widget. Since the **SpWML** class inherits from **StatelessWidget**, you can use it directly in the widget tree. However, this class cannot control the state. If you want to include buttons or other elements, you will need either SpWMLView or SpWMLBuilder. .. code-block:: dart // Simple usage child: SpWML("(h1)Example text") SpWMLDialog ============ Makes it easy to create complex, stateful dialogs without defining new classes. This class replaces the content portion of a Flutter alert dialog with SpWML. If you need a more aesthetically pleasing dialog, you can use SpWMLView and wrap it in a Dialog. Bottom sheets and other elements can be customized in a similar way. .. code-block:: dart SpWMLBuilder b = SpWMLBuilder(layout); b.setStateManager(Manager class stored in class variables etc.); // or b.setManager(the manager class you want to use); showDialog( context: context, builder: (context) { return SpWMLDialog( b, const Text('Dialog title'), width: 320, // The dialog width cancelBtnCallback: (close) { close(); }, okBtnCallback: (close) { close(); }, ); }); Advanced: SpWMLBuilder ======================= The **SpWMLBuilder** is the core engine. Use it directly for manual manipulations, such as replacing blocks with custom Flutter widgets before building. .. code-block:: dart SpWMLBuilder b = SpWMLBuilder(layout); // Embedding Flutter widgets into SpWML "block" b.replace("target_sid", MyCustomWidget()); // Replace children for multiple child elements like col or row b.replaceUnderStructure("parent_sid", [Widget1(), Widget2()]); Widget compiledWidget = b.build(context); ---- Interacting with Elements from Code ===================================== Except for stateless SpWML, elements can be accessed and modified via their **sid** regardless of the component being used. .. code-block:: dart // Get element by sid BtnElement delBtn = builder.getElement("deleteButton") as BtnElement; // Modify parameters directly delBtn.setBGColor(Colors.red); delBtn.textParams.p.isSelectable = true; .. note:: Accessing **element.params** is not recommended as it is for internal use. Please use **spwmlParams**, **elParams**, or specific params like **textParams**. ---- State Management and Serialization ==================================== SpWML manages the state of UI elements (such as text field inputs or switch states) using the `simple_managers `_ package. With SpWMLView (Automatic Management) ---------------------------------------- In **SpWMLView**, state management is handled automatically. You don't need to manually create a **StateManager**. Use **onInit** to set initial values and **scope.sm** in **onSetup** to access the manager for serialization. .. code-block:: dart return SpWMLView( pathBuilder: (_) => "assets/layout.spwml", onInit: (sm) { // 1. Pre-set values before UI build sm.tfm.setText("user_name", "Taro Yamada"); }, onSetup: (context, builder, scope) { // 2. Access the manager via scope.sm for serialization final manager = scope.sm; final Map json = manager.toDict(); // Save all states to JSON // 3. Set callbacks for buttons final btn = builder.getElement("saveBtn") as BtnElement; btn.setCallback(() => print("Saved!")); }, ); With SpWMLBuilder (Manual Management) ---------------------------------------- If you are using **SpWMLBuilder** directly, you must provide a **StateManager** instance yourself and manage its lifecycle. .. code-block:: dart // In your State Class final manager = StateManager(); @override void dispose() { manager.dispose(); // Important: Manually dispose the manager super.dispose(); } @override Widget build(BuildContext context) { SpWMLBuilder b = SpWMLBuilder(layout); b.setStateManager(manager); // Link the manager to the builder return b.build(context); }