### Basic CMakeLists.txt Setup Source: https://github.com/tensegritics/clojuredart/blob/main/samples/ffi/hello_library/CMakeLists.txt Initializes CMake, defines the project, and adds libraries and executables. This is a foundational setup for C/C++ projects managed by CMake. ```cmake cmake_minimum_required(VERSION 3.7 FATAL_ERROR) project(hello_library VERSION 1.0.0 LANGUAGES C) add_library(hello_library SHARED hello.c hello.def) add_executable(hello_test hello.c) ``` -------------------------------- ### ClojureDart Project Setup (deps.edn) Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Configure your project's dependencies and ClojureDart options in deps.edn. Ensure Clojure and Flutter are installed and on your PATH. ```shell mkdir hello cd hello cat << EOF > deps.edn {:paths ["src"] ; where your cljd files are :deps {tensegritics/clojuredart {:git/url "https://github.com/tensegritics/ClojureDart.git" :sha "81b5c03a55cf52b21dc0be8ccfa4827b9889f488"}} :aliases {:cljd {:main-opts ["-m" "cljd.build"]}} :cljd/opts {:kind :flutter :main acme.main}} EOF ``` -------------------------------- ### Run FFI Example Source: https://github.com/tensegritics/clojuredart/blob/main/samples/ffi/README.md Execute the FFI (Foreign Function Interface) example using Dart. This is expected to return 'Hello World'. ```shell dart run bin/ffi.dart ``` -------------------------------- ### Navigate to Sample Project Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Change the directory to the desired sample project, for example, the 'fab' sample. ```shell cd ClojureDart/samples/fab ``` -------------------------------- ### Complete Counter App Example Source: https://context7.com/tensegritics/clojuredart/llms.txt A full ClojureDart application demonstrating state management with atoms and Flutter integration. This example shows how to build a basic UI with a counter that increments on button press. ```clojure (ns sample.counter (:require ["package:flutter/material.dart" :as m] [cljd.flutter :as f])) (defn main [] (let [counter (atom 0)] (f/run (m/MaterialApp .title "Cljd Demo" .theme (m/ThemeData .primarySwatch m/Colors.blue)) .home (m/Scaffold .appBar (m/AppBar .title (m/Text "ClojureDart Home Page")) .floatingActionButton (f/widget (m/FloatingActionButton .onPressed #(swap! counter inc) .tooltip "Increment") (m/Icon m/Icons.add))) .body m/Center (m/Column .mainAxisAlignment m/MainAxisAlignment.center) .children [(m/Text "You have pushed the button this many times:") (f/widget :get {{{:flds [displayLarge]} .-textTheme} m/Theme} :watch [N counter] (m/Text (str N) .style displayLarge))])))) ``` -------------------------------- ### cljd.flutter: :let Directive Example Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Example of using the :let directive within f/widget to introduce local bindings. ```clojure (f/widget :let [some bindings] …) ``` -------------------------------- ### Install Missing Command-line Tools Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-quick-start.md Command to install missing Android SDK command-line tools. This is typically required after running `flutter doctor` and receiving a warning about missing components. ```shell path/to/sdkmanager --install "cmdline-tools;latest" ``` -------------------------------- ### Connect to ClojureDart REPL Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Connect to the ClojureDart socket REPL using netcat, after the watcher has started. ```shell nc localhost 59268 ``` -------------------------------- ### Compile and Run ClojureDart Example Source: https://github.com/tensegritics/clojuredart/blob/main/samples/fficjson/README.md Compile the ClojureDart code using the clj command and then run the Dart application. ```bash clj -M:cljd compile dart run ``` -------------------------------- ### Open iOS Simulator Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-quick-start.md Opens the iOS simulator application from the command line. Ensure Xcode is installed and has been run at least once to accept licenses. ```shell open -a Simulator ``` -------------------------------- ### ClojureDart Resource Management with `:with`, `:let`, and `:dispose` Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-helpers.md This example demonstrates advanced resource management using `:with`, including intermediate values defined with `:let` and a custom dispose method. ```clojure :with [res1 init1 :dispose .cancel :let [v expr] res2 (init2 v)] ``` -------------------------------- ### ClojureDart Named Arguments Example Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Example of how to use named arguments in ClojureDart, mirroring Dart's syntax. ```clojure (m/Text "Hello world" .maxLines 2 .softWrap true .overflow m/TextOverflow.fade) ``` -------------------------------- ### Dart Flutter Widget Example Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-helpers.md This is a standard Dart example demonstrating nested widgets using the ':child' property. ```dart IgnorePointer( ignoring: _open, child: AnimatedContainer( transformAlignment: Alignment.center, transform: Matrix4.diagonal3Values( _open ? 0.7 : 1.0, _open ? 0.7 : 1.0, 1.0, ), duration: const Duration(milliseconds: 250), curve: const Interval(0.0, 0.5, curve: Curves.easeOut), child: AnimatedOpacity( opacity: _open ? 0.0 : 1.0, curve: const Interval(0.25, 1.0, curve: Curves.easeInOut), duration: const Duration(milliseconds: 250), child: FloatingActionButton( onPressed: _toggle, child: const Icon(Icons.create), ), ), ), ); ``` -------------------------------- ### f/widget - Basic Widget Creation Source: https://context7.com/tensegritics/clojuredart/llms.txt The `f/widget` macro simplifies widget creation by automatically handling `.child` threading. This example shows a basic widget with a single child. ```clojure ;; Basic widget with child-threading (f/widget m/Center (m/Text "hello")) ;; Expands to: (m/Center .child (m/Text "hello")) ``` -------------------------------- ### f/widget - Widget with Chained Threading Source: https://context7.com/tensegritics/clojuredart/llms.txt This example demonstrates `f/widget`'s ability to thread widgets through different named parameters like `.home`, `.body`, or `.child`. ```clojure ;; Threading through different named params (f/widget m/MaterialApp .home m/Scaffold .body m/Center (m/ColoredBox .color m/Colors.pink.shade500) (m/Text "Don't stop it now!")) ;; Each widget is threaded through .home, .body, or .child as specified ``` -------------------------------- ### Run Clojure Flutter Application Source: https://github.com/tensegritics/clojuredart/blob/main/samples/first_flutter_app_codelabs/README.md Execute this command after installing dependencies to run the ClojureDart Flutter application. ```bash clj -M:cljd flutter ``` -------------------------------- ### Calling Super Implementation Source: https://github.com/tensegritics/clojuredart/blob/main/doc/differences.md Provides an example of how to call the `super` implementation in ClojureDart by adding metadata to the 'this' argument at the call site. ```clojure (initState [self] (.initState ^super self) ... nil) ``` -------------------------------- ### cljd.flutter: Expanded Child Threading Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Shows the expanded form of the child-threading example, illustrating the macro expansion. ```clojure (m/MaterialApp .home (m/Scaffold .body (m/Center .child (m/ColoredBox .color m/Colors.pink.shade500 .child (m/Text "Don't stop it now!”))))) ``` -------------------------------- ### Get ScaffoldMessenger for snackbars Source: https://context7.com/tensegritics/clojuredart/llms.txt Use the :get directive to access the ScaffoldMessenger service for displaying snackbars. ```clojure ;; Get ScaffoldMessenger for snackbars (f/widget :get [m/ScaffoldMessenger] (m/ElevatedButton .onPressed (fn [] (.showSnackBar scaffold-messenger (m/SnackBar .content (m/Text "Hello!"))) nil)) (m/Text "Show Snackbar")) ``` -------------------------------- ### Initialize and Run ClojureDart Flutter Project Source: https://github.com/tensegritics/clojuredart/blob/main/samples/README.md Use these commands to initialize a new ClojureDart project and run a Flutter application. Ensure you have the necessary Clojure CLI tools installed. ```sh clj -M:cljd init ``` ```sh clj -M:cljd flutter ``` -------------------------------- ### cljd.flutter: Basic Widget Structure Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md A simple example of defining a widget using f/widget with a Center and Text child. ```clojure (f/widget m/Center (m/Text "hello")) ``` -------------------------------- ### cljd.flutter: Child Threading Example Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Demonstrates explicit child-threading using dotted symbols within f/widget. ```clojure (f/widget m/MaterialApp .home m/Scaffold .body m/Center (m/ColoredBox .color m/Colors.pink.shade500) (m/Text "Don't stop it now!”)) ``` -------------------------------- ### Record Creation in ClojureDart Source: https://github.com/tensegritics/clojuredart/blob/main/doc/differences.md Record creation in ClojureDart requires three additional arguments: meta, extmap, and hash. Example: `(R. "arg" nil {} -1)`. ```clojure (defrecord R [a]) (R. "arg" nil {} -1) (new R "arg" nil {} -1) ``` -------------------------------- ### Pure Dart Project Configuration (deps.edn) Source: https://context7.com/tensegritics/clojuredart/llms.txt Example deps.edn configuration for a pure Dart (CLI) ClojureDart project, including Clojure and ClojureDart dependencies. ```clojure ;; Pure Dart (CLI) project deps.edn {:paths ["src"] :deps {org.clojure/clojure {:mvn/version "1.10.1"} tensegritics/clojuredart {:git/url "git@github.com:tensegritics/ClojureDart.git" :sha "81b5c03a55cf52b21dc0be8ccfa4827b9889f488"}} :aliases {:cljd {:main-opts ["-m" "cljd.build"]}} :cljd/opts {:kind :dart :main quickstart.helloworld}} ``` -------------------------------- ### Start Flutter on Specific Device Source: https://context7.com/tensegritics/clojuredart/llms.txt Launches the Flutter application on a specified device. Use `flutter devices` to find available device IDs. ```shell clj -M:cljd flutter -d chrome ``` ```shell clj -M:cljd flutter -d macos ``` ```shell clj -M:cljd flutter -d D6707352-78D2-46BB-AB95-87355283FC82 ``` -------------------------------- ### f/widget - Widget with Multiple Directives Source: https://context7.com/tensegritics/clojuredart/llms.txt Shows how to use multiple directives like `:let`, `:get`, and `:watch` within a single `f/widget` call to manage local state, access services, and react to atom changes. ```clojure ;; Widget with multiple directives (f/widget :let [title "My App"] :get [m/Navigator] :watch [data some-atom] m/Center (m/Text (str title ": " data))) ``` -------------------------------- ### Flutter Project Configuration (deps.edn) Source: https://context7.com/tensegritics/clojuredart/llms.txt Example deps.edn configuration for a ClojureDart Flutter project, specifying source paths, dependencies, and build options. ```clojure ;; Flutter project deps.edn {:paths ["src"] :deps {tensegritics/clojuredart {:git/url "https://github.com/tensegritics/ClojureDart.git" :sha "81b5c03a55cf52b21dc0be8ccfa4827b9889f488"}} :aliases {:cljd {:main-opts ["-m" "cljd.build"]}} :cljd/opts {:kind :flutter :main acme.main}} ``` -------------------------------- ### ClojureDart Flattened Widget with `nest` Macro Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-helpers.md This example demonstrates how the `nest` macro in ClojureDart can flatten deeply nested widgets, reducing boilerplate. ```clojure (f/nest (m/IgnorePointer. :ignoring (boolean @open)) (m/AnimatedContainer. :transformAlignment m.Alignment/center :transform (m.Matrix4/diagonal3Values (if @open 0.7 1.0) (if @open 0.7 1.0) 1.0) :duration ^:const (m/Duration. :milliseconds 250) :curve ^:const (m/Interval. 0.0 0.5 :curve m.Curves/easeOut)) (m/AnimatedOpacity. :opacity (if @open 0.0 1.0) :curve ^:const (m/Interval. 0.25 1.0 :curve m.Curves/easeInOut) :duration ^:const (m/Duration. :milliseconds 250)) (m/FloatingActionButton. :onPressed toggle) (m/Icon. m.Icons/create)) ``` -------------------------------- ### Animated Widgets in ClojureDart Source: https://context7.com/tensegritics/clojuredart/llms.txt Demonstrates creating animated widgets in Flutter using ClojureDart. This example uses AnimatedContainer and manages its state with an atom for dynamic updates. ```clojure (defn random-color [] (m/Color.fromRGBO (rand-int 256) (rand-int 256) (rand-int 256) 1)) ``` ```clojure (def animated-container (let [config (atom {:width 50.0 :height 50.0 :color m/Colors.green :border-radius (m/BorderRadius.circular 8.0)})] (m/Scaffold .appBar (m/AppBar .title (m/Text "AnimatedContainer Demo")) .body (m/Center .child (f/widget :watch [{:keys [width height color border-radius]} config] (m/AnimatedContainer .width width .height height .decoration (m/BoxDecoration .color color .borderRadius border-radius) .duration (Duration .seconds 1) .curve m/Curves.fastOutSlowIn))) .floatingActionButton (m/FloatingActionButton .onPressed #(swap! config assoc :width (rand-int 300) :height (rand-int 300) :color (random-color) :border-radius (m/BorderRadius.circular (rand-int 100))) .child (m/Icon. m/Icons.play_arrow))))) ``` ```clojure (defn main [] (f/run m/MaterialApp .home animated-container)) ``` -------------------------------- ### REPL Usage Examples Source: https://context7.com/tensegritics/clojuredart/llms.txt Interact with the ClojureDart REPL to access previous results, exceptions, inspect and replace widgets, and switch namespaces. The default namespace is `cljd.user`. ```clojure ;; In the REPL (cljd.user namespace by default) ;; Access REPL variables *1 ; last result *2 ; second-to-last result *3 ; third-to-last result *e ; last exception ``` ```clojure ;; Pick a widget to inspect (use UI picker) (pick!) ``` ```clojure ;; After picking, access lexical bindings (keys *env) ; see available bindings ``` ```clojure ;; Replace the selected widget (mount! (m/Text "Replaced!")) ``` ```clojure ;; Switch namespaces (ns myapp.core) ``` -------------------------------- ### Optional `new` and `.` for Constructors Source: https://github.com/tensegritics/clojuredart/blob/main/doc/differences.md In ClojureDart, the `new` keyword and the trailing `.` for constructors can be omitted for brevity. For example, `(List)` is equivalent to `(new List)` or `(List.)`. ```clojure (List) ``` -------------------------------- ### Watch for Changes During Development Source: https://github.com/tensegritics/clojuredart/blob/main/doc/quick-start.md Starts the ClojureDart watcher, which recompiles the project automatically upon detecting code changes. Recommended for active development. ```shell clj -M:cljd watch ``` -------------------------------- ### Dart Covariance Example Source: https://github.com/tensegritics/clojuredart/blob/main/doc/GENERICS.md Demonstrates the covariant nature of Dart generics and the potential runtime errors when a covariant list is treated as a supertype. ```dart List strings = []; List objects = strings; // I must be able to add any object to objects since it's a list of Object, right? objects.add(Object()); // right? // ka💥boom! because objects points to strings which accepts only strings as items. ``` -------------------------------- ### ClojureDart REPL - Get Widget Environment Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Access the lexical bindings and build context for the selected widget in the ClojureDart REPL using the `*env` var after calling `cljd.flutter.repl/pick!`. ```clojure (keys *env) ``` -------------------------------- ### ClojureDart Flutter App Source Code Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Example of a basic Flutter app written in ClojureDart, demonstrating UI elements and Flutter integration. Requires Flutter and Dart SDKs. ```clojurescript (ns acme.main (:require ["package:flutter/material.dart" :as m] [cljd.flutter :as f])) (defn main [] (f/run (m/MaterialApp .title "Welcome to Flutter" .theme (m/ThemeData .primarySwatch m.Colors/pink)) .home (m/Scaffold .appBar (m/AppBar .title (m/Text "Welcome to ClojureDart"))) .body m/Center (m/Text "Let's get coding!" .style (m/TextStyle .color m.Colors/red .fontSize 32.0)))) ``` -------------------------------- ### Navigate to Project Directory Source: https://github.com/tensegritics/clojuredart/blob/main/samples/ffi/README.md Change the current directory to the 'hello_library' folder to begin the build process. ```shell cd hello_library ``` -------------------------------- ### Build Project with Make Source: https://github.com/tensegritics/clojuredart/blob/main/samples/ffi/README.md Execute the 'make' command to compile the project after configuration. ```shell make ``` -------------------------------- ### Initialize and Compile ClojureDart Project Source: https://github.com/tensegritics/clojuredart/blob/main/samples/ffi/README.md Navigate back to the parent directory, then initialize and compile the ClojureDart project using the provided commands. ```shell cd .. clj -M:cljd init clj -M:cljd compile ``` -------------------------------- ### Get Navigator from context Source: https://context7.com/tensegritics/clojuredart/llms.txt Use the :get directive to retrieve the Navigator widget from the Flutter BuildContext. It automatically kebab-cases the name to 'navigator'. ```clojure ;; Get Navigator from context (auto kebab-cases to navigator) (f/widget :get [m/Navigator] (m/ElevatedButton .onPressed #(.pop navigator)) (m/Text "Go back!")) ``` -------------------------------- ### Get Theme data with nested destructuring Source: https://context7.com/tensegritics/clojuredart/llms.txt Retrieve nested properties from the Theme data using the :get directive with advanced destructuring syntax. ```clojure ;; Get Theme data with nested destructuring (f/widget :get {{{:flds [displayLarge]} .-textTheme} m/Theme} (m/Text "Styled" .style displayLarge)) ``` -------------------------------- ### f/run - Flutter Application Entry Point Source: https://context7.com/tensegritics/clojuredart/llms.txt The `f/run` macro serves as the entry point for Flutter applications, setting up the widget tree and enabling hot reload. It takes widget definitions as arguments. ```clojure (ns acme.main (:require ["package:flutter/material.dart" :as m] [cljd.flutter :as f])) (defn main [] (f/run (m/MaterialApp .title "Welcome to Flutter" .theme (m/ThemeData .primarySwatch m.Colors/pink)) .home (m/Scaffold .appBar (m/AppBar .title (m/Text "Welcome to ClojureDart"))) .body m/Center (m/Text "Let's get coding!" .style (m/TextStyle .color m.Colors/red .fontSize 32.0)))) ``` -------------------------------- ### Retrieve Bound Values with :get Directive Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Use the :get directive to retrieve values bound via :bind and make them available in the lexical scope. It can also retrieve Flutter objects like Navigator. ```clojure :get [:k1 :k2] ``` ```clojure :get [m/Navigator] ``` -------------------------------- ### Upgrade ClojureDart Version Source: https://context7.com/tensegritics/clojuredart/llms.txt Upgrades the ClojureDart installation to the latest available version. ```shell clj -M:cljd upgrade ``` -------------------------------- ### Initialize ClojureDart Project Source: https://github.com/tensegritics/clojuredart/blob/main/doc/quick-start.md Initializes the project as a Dart project using the Clojure CLI tools. ```shell clj -M:cljd init ``` -------------------------------- ### Configure Project with CMake Source: https://github.com/tensegritics/clojuredart/blob/main/samples/ffi/README.md Use CMake to configure the build environment for the project. ```shell cmake . ``` -------------------------------- ### List Connected Devices Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Run this command to see a list of available devices for Flutter development. ```shell flutter devices ``` -------------------------------- ### Get custom bound values Source: https://context7.com/tensegritics/clojuredart/llms.txt Retrieve custom values that have been bound using the :bind directive in ancestor widgets. ```clojure ;; Get custom bound values (f/widget :get [:app-state :user-settings] (m/Text (str "User: " (:name app-state)))) ``` -------------------------------- ### Add Material and Video Player Packages Source: https://github.com/tensegritics/clojuredart/blob/main/samples/video_player/README.md Add the material and video_player packages to your Flutter project. ```bash flutter pub add material flutter pub add video_player ``` -------------------------------- ### Access BuildContext for navigation Source: https://context7.com/tensegritics/clojuredart/llms.txt The :context directive provides direct access to the Flutter BuildContext, which can then be used with other directives like :get for navigation. ```clojure (f/widget :context ctx :get [m/Navigator] (m/ElevatedButton .onPressed (fn [] (.push navigator (#/(m/MaterialPageRoute Object) .builder (f/build second-screen))) nil)) (m/Text "Navigate")) ``` -------------------------------- ### Create ClojureDart Project Configuration (deps.edn) Source: https://github.com/tensegritics/clojuredart/blob/main/doc/quick-start.md Defines project paths, dependencies (Clojure and ClojureDart), and build aliases. Ensure the ClojureDart git URL and SHA are up-to-date. ```shell mkdir helloworld cd helloworld cat << EOF > deps.edn {:paths ["src"] ; where your cljd files will live :deps {org.clojure/clojure {:mvn/version "1.10.1"} tensegritics/clojuredart {:git/url "git@github.com:tensegritics/ClojureDart.git" ; or "https://github.com/tensegritics/ClojureDart.git" :sha "81b5c03a55cf52b21dc0be8ccfa4827b9889f488"}} :aliases {:cljd {:main-opts ["-m" "cljd.build"]}} :cljd/opts {:kind :dart :main quickstart.helloworld}} EOF ``` -------------------------------- ### Retrieve bindings in a child widget Source: https://context7.com/tensegritics/clojuredart/llms.txt A child widget can retrieve bindings established by an ancestor using the :get directive and watch them for changes. ```clojure ;; Child widget retrieves bindings (def my-home-page (f/widget :get [:app-state :api-client] :watch [{:keys [user theme]} app-state] (m/Scaffold .body (m/Text (str "Welcome, " user))))) ``` -------------------------------- ### Correct ClojureDart Project Initialization Source: https://github.com/tensegritics/clojuredart/blob/main/TROUBLESHOOTING.md Use the correct command to initialize a ClojureDart project. An incorrect command can lead to issues like EOF errors when reading library information. ```bash clj -M -m cljd.build init --dart folder.example ``` ```bash clj -M -m cljd.build init folder.example ``` -------------------------------- ### Build cJson Dynamic Library Source: https://github.com/tensegritics/clojuredart/blob/main/samples/fficjson/README.md Navigate to the cjson_library directory and use CMake and make to build the dynamic library. Ensure you are in the root of the repository before running these commands. ```bash cd third_party/cjson_library cmake . make cd ../../ ``` -------------------------------- ### ClojureDart Direct Translation of Flutter Widget Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-helpers.md This ClojureDart code directly translates the Dart example, showing the verbose ':child' chaining. ```clojure (m/IgnorePointer. :ignoring (boolean @open) :child (m/AnimatedContainer. :transformAlignment m.Alignment/center :transform (m.Matrix4/diagonal3Values (if @open 0.7 1.0) (if @open 0.7 1.0) 1.0) :duration ^:const (m/Duration. :milliseconds 250) :curve ^:const (m/Interval. 0.0 0.5 :curve m.Curves/easeOut) :child (m/AnimatedOpacity. :opacity (if @open 0.0 1.0) :curve ^:const (m/Interval. 0.25 1.0 :curve m.Curves/easeInOut) :duration ^:const (m/Duration. :milliseconds 250) :child (m/FloatingActionButton. :onPressed toggle :child (m/Icon. m.Icons/create))))) ``` -------------------------------- ### Generate cJson Dart Bindings Source: https://github.com/tensegritics/clojuredart/blob/main/samples/fficjson/README.md From the example/c_json directory, initialize ClojureDart, fetch Dart dependencies, add ffi, path, and ffigen, and then run ffigen to generate the bindings. The generated bindings will be located in lib/cjson_generated_bindings.dart. ```bash clj -M:cljd init dart pub get dart pub add ffi dart pub add path dart pub add ffigen --dev dart run ffigen --config config.yaml ``` -------------------------------- ### Using :let Directive in f/widget Source: https://github.com/tensegritics/clojuredart/blob/main/doc/BOOK.md Demonstrates the usage of the :let directive within an f/widget to introduce local bindings. This avoids the need to wrap the entire expression in a separate let form. ```clojure (f/widget (m/DefaultTextStyle.merge .style (m/TextStyle .fontSize 36)) (m/DecoratedBox .decoration (m/BoxDecoration .color m/Colors.pink)) (m/Center) :let [msg "Hello ?"] (m/Text msg)) ``` -------------------------------- ### Launch Android Emulator Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-quick-start.md Launches a specific Android virtual device emulator. This command requires that emulators have been previously created and configured via Android Studio. ```shell flutter emulators --launch Pixel_5_API_33 ``` -------------------------------- ### Set Multiple Object Properties with doto Source: https://github.com/tensegritics/clojuredart/blob/main/doc/BOOK.md Use `doto` with `.-` mutation sugar for concisely setting multiple properties on an object, common for initializing UI elements. ```clojure (doto (m/Paint) (.-color! m/Colors.green) (.-style! m/PaintingStyle.stroke)) ``` -------------------------------- ### Bind BuildContext with :context Directive Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md The :context directive binds a BuildContext instance to a variable, which is useful when a Flutter function requires a BuildContext that cannot be obtained via :get. ```clojure :context ctx ``` -------------------------------- ### Configure cjson_library CMake Project Source: https://github.com/tensegritics/clojuredart/blob/main/samples/fficjson/third_party/cjson_library/CMakeLists.txt Sets up the CMake project, defines the shared library, and configures its properties including versioning and output name. Ensure XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY is updated with your specific signing ID if building for Apple platforms. ```cmake cmake_minimum_required(VERSION 3.7 FATAL_ERROR) project(cjson_library VERSION 1.0.0 LANGUAGES C) add_library(cjson_library SHARED cJSON.c) set_target_properties(cjson_library PROPERTIES PUBLIC_HEADER cJSON.h VERSION ${PROJECT_VERSION} SOVERSION 1 OUTPUT_NAME "cjson" XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Hex_Identity_ID_Goes_Here" ) ``` -------------------------------- ### Calling Default Constructors Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Illustrates how to call default constructors in ClojureDart, similar to function calls. ```clojure (StringBuffer "hello") ``` -------------------------------- ### Managing TextEditingController with :managed Source: https://github.com/tensegritics/clojuredart/blob/main/doc/BOOK.md Initializes a TextEditingController with an initial text value and specifies a callback function to be executed when the user submits the text. The :dispose option is set to nil, meaning no explicit cleanup is performed by default. ```clojure (defn text-input [init update!] (f/widget :managed [ctrl (m/TextEditingController .text init)] (m/TextField .controller ctrl .onSubmitted (fn [s] (update! s) nil)))) ``` -------------------------------- ### ClojureDart Resource Management with `:with` and `:dispose` Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-helpers.md This snippet shows how to manage resources like files within a widget using the `:with` option, specifying a custom dispose method. ```clojure :with [file (.openSync (io/File "log")) :dispose .closeSync] ``` -------------------------------- ### Create ClojureDart Main Entry-Point Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-quick-start.md Defines the main entry-point for a ClojureDart Flutter application. This code sets up a basic Flutter `MaterialApp` with a scaffold and text, requiring `clojuredart` and Flutter's material.dart package. ```clojure (ns acme.main (:require ["package:flutter/material.dart" :as m] [cljd.flutter :as f])) (defn main [] (f/run (m/MaterialApp .title "Welcome to Flutter" .theme (m/ThemeData .primarySwatch m.Colors/pink)) .home (m/Scaffold .appBar (m/AppBar .title (m/Text "Welcome to ClojureDart"))) .body m/Center (m/Text "Let\'s get coding!" .style (m/TextStyle .color m.Colors/red .fontSize 32.0)))) ``` -------------------------------- ### ClojureDart CLI Commands Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Common commands for initializing, compiling, cleaning, upgrading, and testing ClojureDart projects. ```sh clj -M:cljd init clj -M:cljd flutter # automatically compile and hot reload; press RETURN to force restart clj -M:cljd compile # AOT compilation (eg for deploying) clj -M:cljd clean # to exit the twilight zone clj -M:cljd upgrade # stay current w/ CLJD clj -M:cljd test ``` -------------------------------- ### :watch Deduplication Example Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Demonstrates how :watch triggers rebuilds only when bound values change according to equality. Binding to a map's key prevents rebuilds if other keys in the map change. ```clojure (f/widget :watch [x big-atom] ...) ``` ```clojure (f/widget :watch [{:keys [some-prop]} big-atom] ...) ``` ```clojure (f/widget :watch [{:keys [some-prop] :as unused-big-value} big-atom] ...) ``` -------------------------------- ### Shorthand for :managed and :watch Source: https://github.com/tensegritics/clojuredart/blob/main/doc/BOOK.md Demonstrates the shorthand syntax for :managed and :watch directives, where :managed is used for resource lifecycle management and :watch for observing changes. ```clojure (f/widget :watch [n (atom 0) :as counter] ...) ``` ```clojure (f/widget :managed [counter (atom 0) :dispose nil] :watch [n counter] ...) ``` -------------------------------- ### Run ClojureDart Tests Source: https://context7.com/tensegritics/clojuredart/llms.txt Execute tests using the `clj` command-line tool with the appropriate ClojureDart alias. You can run all tests, specific namespaces, or filter by tags. ```shell # Run all tests clj -M:cljd test ``` ```shell # Run specific namespaces clj -M:cljd test myapp.core-test ``` ```shell # Run tests with specific tags clj -M:cljd test -- -t widget ``` -------------------------------- ### Dart Member Access with String Names Source: https://github.com/tensegritics/clojuredart/blob/main/doc/differences.md When Dart member names are not valid Clojure symbols (e.g., operators like `[]=` ), use strings to represent them for member access. Example: `(. a "[]=" i v)`. ```clojure (. a "[]=" i v) ``` -------------------------------- ### Extending a Super Class with reify Source: https://github.com/tensegritics/clojuredart/blob/main/doc/differences.md Shows how to use `:extends` metadata with `reify` to derive from a super class, requiring a no-arg constructor. ```clojure (reify :extends material/StatelesWidget (build [_ ctx] ...)) ``` -------------------------------- ### Flutter Navigation with ClojureDart Source: https://context7.com/tensegritics/clojuredart/llms.txt Implements basic screen navigation in Flutter using ClojureDart, demonstrating how to define routes and push/pop them using the Navigator. ```clojure (def second-route (m/Scaffold .appBar (m/AppBar .title (m/Text "Second Route")) .body (f/widget :get [m/Navigator] m/Center (m/ElevatedButton .onPressed #(.pop navigator)) (m/Text "Go back!")))) ``` ```clojure (def first-route (m/Scaffold .appBar (m/AppBar .title (m/Text "First Route")) .body (f/widget :get [m/Navigator] m/Center (m/ElevatedButton .onPressed #(do (.push navigator (#/(m/MaterialPageRoute Object) .builder (f/build second-route))) nil)) (m/Text "Open route")))) ``` ```clojure (defn main [] (m/runApp (m/MaterialApp .title "Navigation Basics" .home first-route))) ``` -------------------------------- ### Call Static Methods in ClojureDart Source: https://github.com/tensegritics/clojuredart/blob/main/doc/BOOK.md Demonstrates the two syntaxes for calling static methods: the legacy slash form `(ClassName/methodName ...)` and the modern dot form `(ClassName.methodName ...)`. The dot form is recommended for compatibility with aliases. ```clojure (ClassName/methodName ...) ``` ```clojure (ClassName.methodName ...) ``` ```clojure (alias/ClassName.methodName ...) ``` -------------------------------- ### ClojureDart Property Access Syntax Source: https://github.com/tensegritics/clojuredart/blob/main/NEWS.md Demonstrates the preferred syntax for property access in ClojureDart, using `(.-prop x)` to avoid syntactic ambiguity. The compiler will issue warnings to encourage the consistent use of the dash prefix for properties. ```clojure (.-prop x) ``` -------------------------------- ### Calling Named Constructors Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Demonstrates calling named constructors in ClojureDart, using a similar syntax to static method calls. ```clojure (List/empty .growable true) ``` -------------------------------- ### Clone ClojureDart Repository Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Use this command to clone the main ClojureDart repository from GitHub. ```shell git clone https://github.com/Tensegritics/ClojureDart.git ``` -------------------------------- ### cljd.flutter: f/run Macro Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md The entry point for a Flutter application in ClojureDart, used within main. ```clojure (f/run [& widget-body]) ``` -------------------------------- ### Control recomputation with :refresh-on Source: https://context7.com/tensegritics/clojuredart/llms.txt The :refresh-on option in :watch allows you to specify which watchables, when changed, should trigger a recomputation of the widget's dependencies. ```clojure ;; Watch with :refresh-on to control recomputation (f/widget :watch [ntop (atom 0) :as top-counter nbottom (atom ntop) :as bottom-counter :refresh-on nil] m/Column .children [(f/widget (m/TextButton .onPressed (fn [] (swap! top-counter + 10) nil)) (m/Text (str "Top: " (quot ntop 10)))) (f/widget (m/TextButton .onPressed (fn [] (swap! bottom-counter inc) nil)) (m/Text (str "Bottom: " nbottom)))]) ``` -------------------------------- ### Connect to ClojureDart REPL Source: https://context7.com/tensegritics/clojuredart/llms.txt Connect to the ClojureDart socket REPL for interactive development, especially useful during Flutter hot reload. This allows for real-time code changes and inspection. ```shell # After running clj -M:cljd flutter, connect to the socket REPL nc localhost 59268 ``` ```shell # Or in Emacs with inferior-lisp # C-U M-x inferior-lisp, then: nc localhost 59268 ``` -------------------------------- ### f/widget - Widget with State Watching Source: https://context7.com/tensegritics/clojuredart/llms.txt Utilizes the `:watch` directive within `f/widget` to create a reactive widget that updates when a specified atom changes. ```clojure ;; Widget with state watching (f/widget :watch [count counter-atom] (m/Text (str "Count: " count))) ``` -------------------------------- ### Using ::f/with-notifier for external state changes Source: https://github.com/tensegritics/clojuredart/blob/main/doc/BOOK.md Binds a ValueNotifier named 'progress-notifier' to an initial value of 0. It watches 'app-state' for changes in 'progress' and updates the notifier with interpolated (animated) values. This allows for repainting a CustomPainter without rebuilding the entire widget tree. ```clojure ::f/with-notifier ([progress-notifier 0] :watch [{:keys [progress]} app-state] :animate [progress progress] progress) ``` -------------------------------- ### Create Android JRE Symlink Source: https://github.com/tensegritics/clojuredart/blob/main/doc/flutter-quick-start.md Creates a symbolic link for the Android Studio JRE directory on macOS. This is a workaround for an incompatibility between newer Android Studio versions (Eels) and Flutter, where the JRE directory was renamed from `jre` to `jbr`. ```shell ln -s jbr jre ``` -------------------------------- ### Add Flutter Package Dependency Source: https://github.com/tensegritics/clojuredart/blob/main/samples/first_flutter_app_codelabs/README.md Use this command to add the 'english_words' package as a dependency for your Flutter project. ```bash flutter pub add english_words ``` -------------------------------- ### Name a watched atom using :as Source: https://context7.com/tensegritics/clojuredart/llms.txt Use the :as keyword within :watch to assign a specific name to the watched atom, making it accessible by that name in the widget's scope. ```clojure ;; Watch with :as to name the watchable (f/widget :watch [n (atom 0) :as counter] (m/TextButton .onPressed (fn [] (swap! counter inc) nil)) (m/Text (str "Clicked " n " time(s)"))) ``` -------------------------------- ### Dart Function Signature: writeAll Source: https://github.com/tensegritics/clojuredart/blob/main/doc/README.md Demonstrates a Dart function with one positional and one optional named parameter. ```dart writeAll(Iterable objects, [String separator = ""]) ``` -------------------------------- ### ClojureDart Named Parameter Syntax Source: https://github.com/tensegritics/clojuredart/blob/main/NEWS.md Illustrates the new syntax for named parameters in ClojureDart interop, using dotted symbols instead of keywords to avoid ambiguity. This change requires explicit type-hinting for non-hinted code to function correctly. ```clojure (w/Center .child x) ``` -------------------------------- ### ClojureDart REPL - Namespace Switching Source: https://github.com/tensegritics/clojuredart/blob/main/README.md Switch namespaces in the ClojureDart REPL. If the namespace exists, requires are ignored, and only the namespace switch occurs. ```clojure (ns my.new.namespace) ``` -------------------------------- ### Define Main Namespace in ClojureDart Source: https://github.com/tensegritics/clojuredart/blob/main/doc/quick-start.md Creates the main namespace and defines the entry point function for the Dart CLI application. ```shell mkdir -p src/quickstart cat << EOF > src/quickstart/helloworld.cljd (ns quickstart.helloworld) (defn main [] (print "hello, world\n")) EOF ``` -------------------------------- ### Bind app state for descendants Source: https://context7.com/tensegritics/clojuredart/llms.txt Use the :bind directive to establish inherited bindings for application state and other services, making them available to descendant widgets. ```clojure ;; Bind app state for descendants (f/widget :bind {:app-state (atom {:user "Guest" :theme :dark}) :api-client api-instance} m/MaterialApp .home my-home-page) ``` -------------------------------- ### Run Tests Source: https://context7.com/tensegritics/clojuredart/llms.txt Executes project tests. Can specify specific namespaces or pass arguments to the Dart test runner. ```shell clj -M:cljd test ``` ```shell clj -M:cljd test ns.to.test1 ns.to.test2 ``` ```shell clj -M:cljd test -- -t widget ```