### Define Installation Directories Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Sets the destination directories for data and libraries within the installation bundle. This organizes the installed application files. ```cmake set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") ``` -------------------------------- ### Configure Installation Prefix and Bundle Directory Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Sets up the installation directory and the build bundle directory. It ensures that the installation prefix is correctly set for creating a relocatable bundle. ```cmake # === Installation === # By default, "installing" just makes a relocatable bundle in the build # directory. set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/verygoodopensource/formz/blob/main/CONTRIBUTING.md Installs all project dependencies, including dev dependencies, recursively for all packages. ```sh very_good packages get -r ``` -------------------------------- ### Install Bundled Plugin Libraries Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Installs any bundled plugin libraries. This ensures that plugins are correctly included and available at runtime. ```cmake if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Install Executable and Data Files Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Installs the main executable, ICU data, and the Flutter library to their respective destinations within the bundle. This makes the application runnable. ```cmake install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Install Very Good CLI Source: https://github.com/verygoodopensource/formz/blob/main/CONTRIBUTING.md Installs the Very Good CLI globally. This tool is essential for managing project dependencies and running commands. ```sh dart pub global activate very_good_cli ``` -------------------------------- ### Install Flutter Assets Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Installs the Flutter assets directory. It first removes any existing assets and then copies the current build's assets to ensure they are up-to-date. ```cmake # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Clean Build Bundle Directory on Install Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Removes the build bundle directory before installation to ensure a clean state. This prevents stale files from previous builds. ```cmake # Start with a clean build bundle directory every time. install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) ``` -------------------------------- ### Set Minimum CMake Version and Project Name Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Specifies the minimum required CMake version and names the project. This is a standard starting point for any CMake project. ```cmake cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) ``` -------------------------------- ### Install AOT Library for Non-Debug Builds Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Installs the Ahead-Of-Time (AOT) compiled library on non-Debug builds. This is used for performance optimization in release and profile modes. ```cmake # Install the AOT library on non-Debug builds only. if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Configure Flutter Library and Headers Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/flutter/CMakeLists.txt Defines the path to the Flutter Linux shared library and its associated header files. These variables are set to be available in the parent scope for use in other parts of the build process, including installation steps. ```cmake set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) ``` -------------------------------- ### Configure Cross-Building with Sysroot Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Sets up the sysroot and search paths for cross-compilation. This is essential when building for a different architecture or environment. ```cmake if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() ``` -------------------------------- ### Find and Check PkgConfig Modules Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Finds and checks for required system-level dependencies using PkgConfig, specifically GTK. This ensures necessary libraries are available. ```cmake # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") ``` -------------------------------- ### Find and Check PkgConfig Modules for GTK Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/flutter/CMakeLists.txt This section finds and checks for the presence of GTK, GLIB, and GIO libraries using PkgConfig. It ensures that the necessary system-level dependencies for the Flutter Linux embedder are available. The results are stored in imported targets for easy linking. ```cmake find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) ``` -------------------------------- ### Define Application Binary and ID Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Sets the name of the executable binary and the application ID. These are used for naming the output and for system integration. ```cmake set(BINARY_NAME "example") set(APPLICATION_ID "com.example.example") ``` -------------------------------- ### Run Project Tests Source: https://github.com/verygoodopensource/formz/blob/main/CONTRIBUTING.md Executes all tests within the project. Ensure all tests pass before submitting changes. ```sh very_good test ``` -------------------------------- ### Set CMake Policy and RPATH Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Configures CMake policies and the runtime search path for libraries. CMP0063 NEW ensures modern behavior, and RPATH is set for library loading. ```cmake cmake_policy(SET CMP0063 NEW) set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") ``` -------------------------------- ### Apply Standard Compilation Settings Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt A function to apply common compilation settings like C++ standard, warning flags, optimization levels, and debug definitions to a target. ```cmake function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") endfunction() ``` -------------------------------- ### Interact with FormzInput States Source: https://github.com/verygoodopensource/formz/blob/main/README.md Demonstrates how to create and inspect the state of a FormzInput. `pure` represents an initial, unmodified input, while `dirty` represents a modified input. Access `value`, `isValid`, `error`, and `displayError` to check the input's status. ```dart const name = NameInput.pure(); print(name.value); // '' print(name.isValid); // false print(name.error); // NameInputError.empty print(name.displayError); // null const joe = NameInput.dirty(value: 'joe'); print(joe.value); // 'joe' print(joe.isValid); // true print(joe.error); // null print(name.displayError); // null ``` -------------------------------- ### Custom Command to Assemble Flutter Library Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/flutter/CMakeLists.txt This custom command invokes the Flutter tool backend script to build the Flutter library and headers. It uses a phony target `_phony_` to ensure the command runs on every build, as direct input/output tracking for the Flutter tool is not yet supported. ```cmake add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ``` -------------------------------- ### Set Runtime Output Directory for Executable Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Configures the executable's runtime output directory to a subdirectory. This is done to prevent users from running the unbundled executable directly. ```cmake # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of # the default top-level location. set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### Format Code Source: https://github.com/verygoodopensource/formz/blob/main/CONTRIBUTING.md Formats Dart code in the `lib` and `test` directories according to standard Dart formatting. ```sh dart format lib test ``` -------------------------------- ### Include Flutter Managed Directory Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Includes the Flutter managed directory, which contains Flutter's build rules and libraries. This is crucial for integrating Flutter into the native build. ```cmake set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") # Flutter library and tool build rules. add_subdirectory(${FLUTTER_MANAGED_DIR}) ``` -------------------------------- ### Configure Runner Executable Source: https://github.com/verygoodopensource/formz/blob/main/example/windows/runner/CMakeLists.txt Defines the main executable target for the runner application, listing all necessary source files and resources. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) apply_standard_settings(${BINARY_NAME}) target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Flutter Login Form with Formz State Management Source: https://context7.com/verygoodopensource/formz/llms.txt This snippet defines the complete Flutter login form, including input definitions, form state management with `FormzMixin`, and the UI widget. It handles email and password validation, submission status, and user feedback. Ensure `formz` package is added to your `pubspec.yaml`. ```dart import 'package:flutter/material.dart'; import 'package:formz/formz.dart'; // --- Input definitions --- enum EmailValidationError { empty, invalid } class Email extends FormzInput with FormzInputErrorCacheMixin { Email.pure([super.value = '']) : super.pure(); Email.dirty([super.value = '']) : super.dirty(); static final _emailRegExp = RegExp( r'^[a-zA-Z\d.!#$%&*+/=?^_`{|}~-]+@[a-zA-Z\d-]+(?:\.[a-zA-Z\d-]+)*$', ); @override EmailValidationError? validator(String value) { if (value.isEmpty) return EmailValidationError.empty; if (!_emailRegExp.hasMatch(value)) return EmailValidationError.invalid; return null; } } enum PasswordValidationError { empty, tooShort } class Password extends FormzInput { const Password.pure([super.value = '']) : super.pure(); const Password.dirty([super.value = '']) : super.dirty(); @override PasswordValidationError? validator(String value) { if (value.isEmpty) return PasswordValidationError.empty; if (value.length < 8) return PasswordValidationError.tooShort; return null; } } // --- Form state using FormzMixin --- class LoginFormState with FormzMixin { LoginFormState({ Email? email, this.password = const Password.pure(), this.status = FormzSubmissionStatus.initial, }) : email = email ?? Email.pure(); final Email email; final Password password; final FormzSubmissionStatus status; @override List> get inputs => [email, password]; LoginFormState copyWith({ Email? email, Password? password, FormzSubmissionStatus? status, }) =>LoginFormState( email: email ?? this.email, password: password ?? this.password, status: status ?? this.status, ); } // --- Widget --- class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State createState() => _LoginPageState(); } class _LoginPageState extends State { late LoginFormState _state; final _emailController = TextEditingController(); final _passwordController = TextEditingController(); @override void initState() { super.initState(); _state = LoginFormState(); _emailController.addListener(() => setState(() { _state = _state.copyWith(email: Email.dirty(_emailController.text)); })); _passwordController.addListener(() => setState(() { _state = _state.copyWith(password: Password.dirty(_passwordController.text)); })); } Future _onSubmit() async { if (!_state.isValid) return; setState(() => _state = _state.copyWith(status: FormzSubmissionStatus.inProgress)); try { await Future.delayed(const Duration(seconds: 1)); // Simulate API call setState(() => _state = _state.copyWith(status: FormzSubmissionStatus.success)); } catch (_) { setState(() => _state = _state.copyWith(status: FormzSubmissionStatus.failure)); } } @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column(children: [ TextField( controller: _emailController, decoration: InputDecoration( labelText: 'Email', // displayError suppresses errors until field is dirty errorText: _state.email.displayError?.name, ), ), TextField( controller: _passwordController, obscureText: true, decoration: InputDecoration( labelText: 'Password', errorText: _state.password.displayError?.name, ), ), if (_state.status.isInProgress) const CircularProgressIndicator() else ElevatedButton( // Disable button if form is invalid or already submitted onPressed: _state.isValid && !_state.status.isInProgressOrSuccess ? _onSubmit : null, child: const Text('Login'), ), if (_state.status.isSuccess) const Text('Login successful!', style: TextStyle(color: Colors.green)), if (_state.status.isFailure) const Text('Login failed. Try again.', style: TextStyle(color: Colors.red)), ]); } } ``` -------------------------------- ### Automatic Form Validation with FormzMixin Source: https://github.com/verygoodopensource/formz/blob/main/README.md Implement `FormzMixin` in a form class to automatically manage and validate a list of `FormzInput`s. The `inputs` getter should return all form fields that need validation. ```dart class LoginForm with FormzMixin { LoginForm({ this.username = const Username.pure(), this.password = const Password.pure(), }); final Username username; final Password password; @override List get inputs => [username, password]; } void main() { print(LoginForm().isValid); // false } ``` -------------------------------- ### Define Executable Target Source: https://github.com/verygoodopensource/formz/blob/main/example/linux/CMakeLists.txt Defines the main executable target, listing its source files and applying standard settings. It also links necessary libraries. ```cmake # Application build add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) apply_standard_settings(${BINARY_NAME}) target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Load Main Dart JS with Service Worker Logic Source: https://github.com/verygoodopensource/formz/blob/main/example/web/index.html This script manages service worker registration and loads the main application script. It includes logic to handle service worker updates and fallbacks to a plain script tag if the service worker fails to load. ```javascript var serviceWorkerVersion = null; var scriptLoaded = false; function loadMainDartJs() { if (scriptLoaded) { return; } scriptLoaded = true; var scriptTag = document.createElement('script'); scriptTag.src = 'main.dart.js'; scriptTag.type = 'application/javascript'; document.body.append(scriptTag); } if ('serviceWorker' in navigator) { // Service workers are supported. Use them. window.addEventListener('load', function () { // Wait for registration to finish before dropping the