### Installation Rules Configuration Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/CMakeLists.txt Configures the installation process for the application and its associated files. This includes setting the installation prefix, copying runtime files, libraries, and assets, and handling plugin libraries. ```cmake set(BUILD_BUNDLE_DIR "$") set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 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) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() 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) install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### Riverpod Provider Setup and Mocking in Dart Source: https://github.com/tappeddev/tapped_toolkit/blob/main/README.md Demonstrates setting up a service provider and a ChangeNotifierProvider using Riverpod. It also shows how to override a provider with a mock implementation in a test scenario. ```dart // Here we have a simple service that is wrapped in a provider. final provMyService = Provider((ref) => MyServiceImpl()); final provHomeChangeNotifier = ChangeNotifierProvider((ref) { // Accessing dependencies is done like this. // Based on your use case you might use ref.watch(). return HomeChangeNotifier(myService: ref.read(myService)); }); ``` ```dart void main() { test("example test", () { final container = ProviderContainer( overrides: [ provMyService.overrideWithValue(MyServiceMock()), ], ); final homeChangeNotifier = container.read(provHomeChangeNotifier); }); } ``` -------------------------------- ### Install FVM (Flutter Version Manager) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/README.md Commands to install and verify the Flutter Version Manager (FVM). FVM helps manage different Flutter SDK versions across projects. ```bash dart pub global activate fvm fvm version fvm install fvm flutter doctor ``` -------------------------------- ### Project Setup and Configuration Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/CMakeLists.txt Initializes the CMake project, sets the minimum required version, defines the project name and languages, and configures the binary name. It also enforces modern CMake behaviors. ```cmake cmake_minimum_required(VERSION 3.14) project(example LANGUAGES CXX) set(BINARY_NAME "example") cmake_policy(SET CMP0063 NEW) ``` -------------------------------- ### Flutter CustomDropDown Example with Country Selection Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt Demonstrates how to implement a customizable dropdown for country selection using the CustomDropDown widget. It includes form validation, custom item building with flags and names, and dynamic button styling based on selection and validation status. This example utilizes Flutter's State management and integrates with the tapped_toolkit package. ```dart import 'package:flutter/material.dart'; import 'package:tapped_toolkit/tapped_toolkit.dart'; class CountrySelector extends StatefulWidget { const CountrySelector({Key? key}) : super(key: key); @override State createState() => _CountrySelectorState(); } class _CountrySelectorState extends State { String? _selectedCountry; final _dropDownKey = GlobalKey>(); final List> _countries = [ {'code': 'US', 'name': 'United States', 'flag': 'πŸ‡ΊπŸ‡Έ'}, {'code': 'UK', 'name': 'United Kingdom', 'flag': 'πŸ‡¬πŸ‡§'}, {'code': 'DE', 'name': 'Germany', 'flag': 'πŸ‡©πŸ‡ͺ'}, {'code': 'FR', 'name': 'France', 'flag': 'πŸ‡«πŸ‡·'}, {'code': 'JP', 'name': 'Japan', 'flag': 'πŸ‡―πŸ‡΅'}, ]; String? _validateCountry(String? value) { if (value == null) { return 'Please select a country'; } return null; } List> _buildDropDownItems() { return _countries.map((country) { return CustomDropDownItem( value: country['code'], backgroundColor: Colors.white, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ Text(country['flag']!, style: const TextStyle(fontSize: 24)), const SizedBox(width: 12), Expanded( child: Text( country['name']!, style: const TextStyle(fontSize: 16), ), ), if (_selectedCountry == country['code']) const Icon(Icons.check, color: Colors.green), ], ), ), ); }).toList(); } @override Widget build(BuildContext context) { final selectedCountryData = _countries.firstWhere( (c) => c['code'] == _selectedCountry, orElse: () => {'code': '', 'name': 'Select a country', 'flag': '🌍'}, ); return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( 'Country Selection', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), CustomDropDown( key: _dropDownKey, value: _selectedCountry, items: _buildDropDownItems(), validator: _validateCountry, autoValidate: true, borderColor: Colors.grey.shade400, cornerRadius: 12, itemHeight: 56, textStyle: const TextStyle( fontSize: 16, color: Colors.black87, ), errorStyle: const TextStyle( fontSize: 12, color: Colors.red, ), buildButton: (context, animation, formField) { return CustomDropDownItem( value: _selectedCountry, backgroundColor: formField.hasError ? Colors.red.shade50 : Colors.grey.shade100, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ Text( selectedCountryData['flag']!, style: const TextStyle(fontSize: 24), ), const SizedBox(width: 12), Expanded( child: Text( selectedCountryData['name']!, style: TextStyle( fontSize: 16, color: _selectedCountry == null ? Colors.grey : Colors.black87, ), ), ), // Animated chevron icon RotationTransition( turns: Tween(begin: 0.0, end: 0.5).animate(animation), child: const Icon(Icons.keyboard_arrow_down), ), ], ), ), ); }, onChanged: (value) { setState(() { _selectedCountry = value; }); }, ), ], ), ); } } ``` -------------------------------- ### Add Tapped Toolkit Dependency using Git in pubspec.yaml Source: https://github.com/tappeddev/tapped_toolkit/blob/main/README.md Example of how to add the tapped_toolkit package as a dependency in your project's pubspec.yaml file using a git repository URL. This is used when packages are not yet published to pub.dev. ```yaml dependencies: tapped_toolkit: git: url: git@github.com:tappeddev/tapped_toolkit.git ref: stable ``` -------------------------------- ### Add Tapped Toolkit Dependency via Git Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt This YAML snippet shows how to add the tapped_toolkit package to your Flutter project's `pubspec.yaml` file using a Git dependency. Ensure you have Git installed and configured for SSH access to the repository. ```yaml # pubspec.yaml dependencies: tapped_toolkit: git: url: git@github.com:tappeddev/tapped_toolkit.git ref: stable ``` -------------------------------- ### Implement BaseTextField for User Input and Validation in Flutter Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt This Dart code demonstrates how to integrate the BaseTextField widget into a Flutter form for user profile input. It showcases handling text changes, validation logic, autofill hints, and visual feedback based on validation status. The example includes two BaseTextField instances for email and password, along with buttons to prefill data and submit the form. ```dart import 'package:flutter/material.dart'; import 'package:tapped_toolkit/tapped_toolkit.dart'; class UserProfileForm extends StatefulWidget { const UserProfileForm({Key? key}) : super(key: key); @override State createState() => _UserProfileFormState(); } class _UserProfileFormState extends State { String _email = ''; String _password = ''; bool _isEmailValid = true; bool _isPasswordValid = true; String? _validateEmail(String? value) { if (value == null || value.isEmpty) { return 'Email is required'; } if (!value.contains('@')) { return 'Please enter a valid email'; } return null; } String? _validatePassword(String? value) { if (value == null || value.isEmpty) { return 'Password is required'; } if (value.length < 8) { return 'Password must be at least 8 characters'; } return null; } void _prefillTestData() { // External update - cursor will be positioned correctly setState(() { _email = 'test@example.com'; _password = 'securepassword123'; }); } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ BaseTextField( text: _email, onChanged: (value, source) { setState(() => _email = value); // Distinguish between user typing and programmatic updates if (source == TextFieldSource.inside) { print('User typed: $value'); } else { print('External update: $value'); } }, validator: _validateEmail, autoValidate: true, autofillHints: const [AutofillHints.email], textInputType: TextInputType.emailAddress, textInputAction: TextInputAction.next, onValidationChanged: (isValid) { setState(() => _isEmailValid = isValid); }, onFocusChanged: (hasFocus) { print('Email field focus: $hasFocus'); }, decoration: InputDecoration( labelText: 'Email', prefixIcon: const Icon(Icons.email), suffixIcon: _isEmailValid ? const Icon(Icons.check, color: Colors.green) : null, border: const OutlineInputBorder(), ), textStyle: const TextStyle(fontSize: 16), ), const SizedBox(height: 16), BaseTextField( text: _password, onChanged: (value, source) { setState(() => _password = value); }, validator: _validatePassword, autoValidate: true, obscureText: true, autofillHints: const [AutofillHints.password], textInputAction: TextInputAction.done, onValidationChanged: (isValid) { setState(() => _isPasswordValid = isValid); }, onFieldSubmitted: (value) { if (_isEmailValid && _isPasswordValid) { print('Form submitted with email: $_email'); } }, onLeave: () { print('Password field lost focus'); }, decoration: InputDecoration( labelText: 'Password', prefixIcon: const Icon(Icons.lock), suffixIcon: _isPasswordValid ? const Icon(Icons.check, color: Colors.green) : null, border: const OutlineInputBorder(), ), textStyle: const TextStyle(fontSize: 16), ), const SizedBox(height: 24), ElevatedButton( onPressed: _prefillTestData, child: const Text('Prefill Test Data'), ), const SizedBox(height: 8), ElevatedButton( onPressed: (_isEmailValid && _isPasswordValid) ? () => print('Submitting: $_email') : null, child: const Text('Submit'), ), ], ), ); } } ``` -------------------------------- ### CI/CD Pipeline Commands for Flutter Projects Source: https://github.com/tappeddev/tapped_toolkit/blob/main/README.md Commands for common CI/CD pipeline stages in Flutter projects, including linting, formatting, and testing. These commands ensure code quality and consistency. ```bash fvm flutter analyze fvm flutter format --set-exit-if-changed find . -name "*.dart" ! -name "*.g.dart" ! -name "*.freezed.dart" ! -path '*/generated/*' ! -path '*/gen/*' | xargs fvm flutter format -n --set-exit-if-changed fvm flutter test ``` -------------------------------- ### Apply Standard Build Settings (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/runner/CMakeLists.txt Applies a predefined set of standard build settings to the specified target. This simplifies configuration for common build requirements. This can be customized or removed if the application needs unique build settings. ```cmake # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Link Libraries and Include Directories (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/runner/CMakeLists.txt Specifies the libraries to link against and the directories to search for header files. It links the application target with 'flutter' and 'flutter_wrapper_app' libraries and adds the source directory to include paths. Application-specific dependencies should be added here. ```cmake # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Execute Code After First Widget Build with AfterFirstBuildMixin Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt Demonstrates using `AfterFirstBuildMixin` in a Flutter `StatefulWidget` to execute code, such as requesting focus or measuring widget size, only after the widget has been rendered for the first time. This mixin ensures that operations requiring layout information are performed safely. ```dart import 'package:flutter/material.dart'; import 'package:tapped_toolkit/tapped_toolkit.dart'; class MyWidget extends StatefulWidget { const MyWidget({Key? key}) : super(key: key); @override State createState() => _MyWidgetState(); } class _MyWidgetState extends State with AfterFirstBuildMixin { final _focusNode = FocusNode(); Size? _widgetSize; @override void afterFirstBuild() { // This runs after the first frame is rendered _focusNode.requestFocus(); // Safe to measure widget size here final renderBox = context.findRenderObject() as RenderBox; setState(() { _widgetSize = renderBox.size; }); print('Widget size: $_widgetSize'); } @override Widget build(BuildContext context) { return TextField( focusNode: _focusNode, decoration: InputDecoration( hintText: _widgetSize != null ? 'Width: ${_widgetSize!.width}' : 'Loading...', ), ); } @override void dispose() { _focusNode.dispose(); super.dispose(); } } ``` -------------------------------- ### Execute Flutter Tool Backend Command (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/flutter/CMakeLists.txt Defines a custom command to execute the Flutter tool backend script. This command is designed to run on every build by using a phony output file. It sets up environment variables and passes build configuration arguments to the tool. The output of this command includes the Flutter library, headers, and wrapper source files. ```cmake # === Flutter tool backend === # _phony_ is a non-existent file to force this command to run every time, # since currently there's no way to get a full input/output list from the # flutter tool. set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ${PHONY_OUTPUT} COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" windows-x64 $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ) ``` -------------------------------- ### Configure Flutter Library and Headers (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/flutter/CMakeLists.txt Sets up the Flutter library and its associated header files. It includes generated configuration, defines library paths, and configures include directories and link libraries for the 'flutter' interface library. Dependencies are managed via 'flutter_assemble'. ```cmake cmake_minimum_required(VERSION 3.14) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") # Configuration provided via flutter tool. include(${EPHEMERAL_DIR}/generated_config.cmake) # TODO: Move the rest of this into files in ephemeral. See # https://github.com/flutter/flutter/issues/57146. set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") # === Flutter Library === set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") # 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/windows/app.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "flutter_export.h" "flutter_windows.h" "flutter_messenger.h" "flutter_plugin_registrar.h" "flutter_texture_registrar.h" ) list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Define Executable Target and Source Files (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/runner/CMakeLists.txt Defines the main executable target for the application and lists all the source files required for compilation. This includes C++ source files, generated Flutter files, and resource files. The executable name is controlled by BINARY_NAME. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. 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" ) ``` -------------------------------- ### Build C++ Wrapper Libraries (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/flutter/CMakeLists.txt Defines static C++ wrapper libraries for Flutter plugins and applications. It compiles core implementation files along with plugin-specific or application-specific source files. These libraries are linked against the Flutter library and configured with specific include paths and visibility settings. ```cmake # === Wrapper === list(APPEND CPP_WRAPPER_SOURCES_CORE "core_implementations.cc" "standard_codec.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_PLUGIN "plugin_registrar.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") list(APPEND CPP_WRAPPER_SOURCES_APP "flutter_engine.cc" "flutter_view_controller.cc" ) list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") # Wrapper sources needed for a plugin. add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) # Wrapper sources needed for the runner. add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP} ) apply_standard_settings(flutter_wrapper_app) target_link_libraries(flutter_wrapper_app PUBLIC flutter) target_include_directories(flutter_wrapper_app PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_app flutter_assemble) ``` -------------------------------- ### Standard Compilation Settings Function Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/CMakeLists.txt Defines a reusable function `APPLY_STANDARD_SETTINGS` to apply common compilation features, options, and definitions to CMake targets. This promotes consistency across different build targets. ```cmake function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_17) target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") target_compile_options(${TARGET} PRIVATE /EHsc) target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") endfunction() ``` -------------------------------- ### Add Version Preprocessor Definitions (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/runner/CMakeLists.txt Adds preprocessor definitions to the build target, embedding Flutter version information directly into the compiled code. This allows the application to access version details at runtime. It defines major, minor, patch, and build numbers. ```cmake # Add preprocessor definitions for the build version. target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") ``` -------------------------------- ### Flutter and Runner Integration Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/CMakeLists.txt Includes subdirectories for Flutter managed code and the application runner. It also includes generated CMake files for plugins, integrating them into the build process. ```cmake set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) add_subdirectory("runner") include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Build Configuration Management Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/CMakeLists.txt Manages build configurations (Debug, Profile, Release) based on whether the generator supports multi-configuration builds. It sets default build types and defines settings specific to the Profile build mode. ```cmake get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(IS_MULTICONFIG) set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" CACHE STRING "" FORCE) else() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() endif() set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") ``` -------------------------------- ### Schedule Callbacks on Next Frame with onNextFrame Extension Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt Illustrates the use of the `onNextFrame` extension on `State` in Flutter to safely schedule callbacks that execute on the next frame. This method includes automatic checks for widget mounting and handles errors, making it suitable for animations or state updates that depend on frame rendering. ```dart import 'dart:async'; import 'package:flutter/material.dart'; import 'package:tapped_toolkit/tapped_toolkit.dart'; class AnimatedCounter extends StatefulWidget { const AnimatedCounter({Key? key}) : super(key: key); @override State createState() => _AnimatedCounterState(); } class _AnimatedCounterState extends State { int _counter = 0; final _scrollController = ScrollController(); Future _incrementAndScroll() async { setState(() { _counter++; }); // Schedule scroll after the rebuild completes await onNextFrame(() { // This only runs if widget is still mounted _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 300), curve: Curves.easeOut, ); }); print('Scroll animation completed'); } Future _batchUpdate() async { // Chain multiple frame callbacks for (int i = 0; i < 5; i++) { await onNextFrame(() { setState(() => _counter++); }); } print('Batch update completed, counter: $_counter'); } @override Widget build(BuildContext context) { return Column( children: [ Expanded( child: ListView.builder( controller: _scrollController, itemCount: _counter, itemBuilder: (context, index) => ListTile( title: Text('Item $index'), ), ), ), ElevatedButton( onPressed: _incrementAndScroll, child: Text('Add Item (Count: $_counter)'), ), ], ); } @override void dispose() { _scrollController.dispose(); super.dispose(); } } ``` -------------------------------- ### Custom Dropdown Item Configuration Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt Defines data classes for configuring items within a CustomDropDown. Each item can hold a value, a child widget, and styling properties like background color. It supports basic text, complex widgets like ListTile, and even custom layouts with images and text. ```dart import 'package:flutter/material.dart'; import 'package:tapped_toolkit/tapped_toolkit.dart'; // Creating dropdown items with different configurations final items = [ // Basic item CustomDropDownItem( value: 1, child: const Text('Option 1'), backgroundColor: Colors.white, ), // Item with custom key for widget testing CustomDropDownItem( key: const ValueKey('option-2'), value: 2, child: const ListTile( leading: Icon(Icons.star), title: Text('Premium Option'), subtitle: Text('Best value'), ), backgroundColor: Colors.amber.shade50, ), // Complex item with multiple widgets CustomDropDownItem( value: 3, child: Row( children: [ const CircleAvatar( backgroundImage: NetworkImage('https://example.com/avatar.png'), ), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: const [ Text('User Profile', style: TextStyle(fontWeight: FontWeight.bold)), Text('john@example.com', style: TextStyle(fontSize: 12)), ], ), ], ), backgroundColor: Colors.blue.shade50, ), ]; ``` -------------------------------- ### Disable Conflicting Windows Macros (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/runner/CMakeLists.txt Disables specific Windows preprocessor macros (NOMINMAX) that can conflict with standard C++ library functions, particularly `min` and `max`. This prevents potential compilation errors and ensures standard library functions work as expected. ```cmake # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") ``` -------------------------------- ### Add Flutter Build Dependency (CMake) Source: https://github.com/tappeddev/tapped_toolkit/blob/main/example/windows/runner/CMakeLists.txt Ensures that the Flutter build artifacts are generated before the application target is built. This is a crucial step for Flutter desktop applications, guaranteeing that the necessary Flutter assets and code are available during the compilation process. ```cmake # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Custom Dropdown Form Interaction Source: https://context7.com/tappeddev/tapped_toolkit/llms.txt Demonstrates how to integrate a CustomDropDown into a Flutter form, including programmatic validation and resetting the selection. It uses a GlobalKey to access the dropdown's state for validation and updates a state variable to track the selected country. ```dart print('Selected country: $value'); }, ), const SizedBox(height: 24), ElevatedButton( onPressed: () { // Programmatically validate final isValid = _dropDownKey.currentState?.validate() ?? false; if (isValid) { print('Form is valid, selected: $_selectedCountry'); } }, child: const Text('Validate & Submit'), ), const SizedBox(height: 8), OutlinedButton( onPressed: () { setState(() => _selectedCountry = null); }, child: const Text('Reset Selection'), ), ], ), ); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.