### Install App UI Unity Package Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/setup.md Steps to add the App UI Unity Package to your project using the Unity Package Manager by providing a Git URL. ```Unity Windows > Package Manager + button > Add package from git URL... com.unity.dt.app-ui Add button ``` -------------------------------- ### Implement Navigation Component Setup in NavigationScreen Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/navigation.md This example illustrates an alternative pattern where navigation component setup methods like SetupAppBar are overridden directly within a custom NavigationScreen implementation. This approach allows for screen-specific control over navigation UI elements. ```cs class MyAppHomeScreen : NavigationScreen { public override void SetupAppBar(AppBar appBar, NavController navController) { appBar.title = "Home"; } } ``` -------------------------------- ### App UI Project Settings Configuration Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/setup.md Details on configuring the App UI package settings within the Unity Editor. This includes options for UI scaling, editor-only mode, update frequency, Android manifest overrides, and shader inclusion. ```APIDOC App UI Settings: Generate Settings File: - Description: Generates the default App UI settings file in the Assets folder. - Location: Edit > Project Settings > App UI Auto correct the UI scale: - Description: Enables or disables automatic UI scaling to match OS pixel density. Designed for 96 DPI screens. - Type: Boolean - Default: Enabled (implied) Editor-only mode: - Description: Injects a scripting definition symbol to prevent App UI assemblies from being included in builds. Useful for editor-only features. - Type: Boolean - Default: Disabled Editor Update Frequency: - Description: Configures how often App UI updates in the editor. Affects internal message queue. Standalone builds use MonoBehaviour.Update(). - Type: Integer - Default: 60 (updates per second) - Example: Set to 1 to simulate slower devices. Override Android Main Manifest: - Description: Allows overriding the Android main manifest file for custom permissions (e.g., VIBRATE for haptic feedback). Affects only Android builds. - Type: Boolean - Default: Enabled Include App UI Shaders In Player Build: - Description: Includes App UI shaders in the player build to render UI elements. Disable to reduce build size if shaders are not used. - Type: Boolean - Default: Enabled ``` -------------------------------- ### Refactor SplitView Component in XML Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Demonstrates the new structure of the SplitView component, which now supports multiple Pane children and has a refactored implementation for greater flexibility. The example shows how to define panes with specific widths and stretch behavior. ```xml ``` -------------------------------- ### Redux Store Creation with Slices Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Shows the refactored Redux API for creating stores and slices in Unity App UI. Slices must be provided during store creation, and cannot be added afterward. ```csharp var store = new Store(); store.AddSlice("sliceName", new MySliceState(), builder => { /* ... */ }); store.AddSlice("slice2Name", /* ... */ ); ``` ```csharp var store = StoreFactory.CreateStore(new [] { StoreFactory.CreateSlice("sliceName", new MySliceState(), builder => { /* ... */ }), StoreFactory.CreateSlice("slice2Name", /* ... */ ) // ... }); ``` -------------------------------- ### Custom Theme File Reference Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/theming.md Example of a theme file that imports a stylesheet and is referenced in `PanelSettings` for applying custom themes to a `UIDocument` component. ```css @import url("darkBlue.uss"); VisualElement {} ``` -------------------------------- ### Implement INavVisualController in C# Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Shows the addition of the `SetupNavigationRail` method to the `INavVisualController` interface. This method must be implemented to configure the navigation rail, similar to existing methods for bottom navigation bars, app bars, and drawers. ```csharp public class MyNavController : INavVisualController { public void SetupBottomNavBar(BottomNavBar bottomNavBar, NavDestination destination, NavController navController) { if (destination.showBottombar) { /* ... */ } } public void SetupAppBar(AppBar appBar, NavDestination destination, NavController navController) { if (destination.showAppBar) { /* ... */ } } public void SetupDrawer(Drawer drawer, NavDestination destination, NavController navController) { if (destination.showDrawer) { /* ... */ } } } ``` ```csharp public class MyNavController : INavVisualController { public void SetupBottomNavBar(BottomNavBar bottomNavBar, NavDestination destination, NavController navController) { if (destination.showBottombar) { /* ... */ } } public void SetupAppBar(AppBar appBar, NavDestination destination, NavController navController) { if (destination.showAppBar) { /* ... */ } } public void SetupDrawer(Drawer drawer, NavDestination destination, NavController navController) { if (destination.showDrawer) { /* ... */ } } public void SetupNavigationRail(NavigationRail navigationRail, NavDestination destination, NavController navController) { if (destination.showNavigationRail) { /* ... */ } } } ``` -------------------------------- ### MVVM App Creation: InitializeComponent Override Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Illustrates the change in MVVM app creation within Unity App UI. Developers can now override the InitializeComponent method to set up the visual tree, offering more flexibility. ```csharp public class MyApp : App { public MyApp(MainPage mainPage) { var panel = new Panel(); panel.Add(mainPage); this.mainPage = panel; } } ``` ```csharp public class MyApp : App { public new static MyApp current => (MyApp)App.current; public override void InitializeComponent() { base.InitializeComponent(); rootVisualElement.Add(services.GetRequiredService()); } } ``` -------------------------------- ### Implement IPartionableState Interface Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/state-management.md Illustrates the implementation of the `IPartionableState` interface for managing state slices. The `Get` and `Set` methods are crucial for retrieving and updating specific parts of the state immutably. ```csharp using Unity.AppUI.Redux; class MyState : IPartionableState { public TSliceState Get(string sliceName) { // Implement the method to return the slice state. } public MyState Set(string sliceName, TSliceState sliceState) { // Implement the method to set the slice state. // Remember that the state object is immutable, so the returned object should be a new instance. } } ``` -------------------------------- ### Custom Theme Stylesheet Variables Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/theming.md Example of a stylesheet file defining USS variables for a custom theme. Requires the `appui--` prefix for theme names to be recognized by the App UI context provider. ```css .appui--darkBlue { --appui-primary-100: #E3F2FD; ... } ``` -------------------------------- ### App UI Support for New Input System Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/faq.md Confirms that App UI components are compatible with Unity's New Input System. It also provides instructions on how to install the Input System package and configure input actions for newer Unity versions. ```text Install the "Input System" package via the Package Manager. For Unity 2023.2+, configure UI input actions in Project Settings > Input System Package > Input Actions. ``` -------------------------------- ### Implement INavVisualController for Navigation Components Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/navigation.md This example demonstrates implementing the INavVisualController interface to control the visual state of navigation components such as AppBar, BottomNavBar, Drawer, and NavigationRail. It requires the Unity.AppUI.Navigation and Unity.AppUI.UI namespaces and allows for custom logic based on navigation destinations. ```cs class MyVisualController : INavVisualController { public void SetupBottomNavBar(BottomNavBar bottomNavBar, NavDestination destination, NavController navController) { if (!destination.showBottomNavBar) return; var homeButton = new BottomNavBarItem("info", "Home", () => navController.Navigate(Actions.navigateToHome)) { isSelected = destination.name == Screens.home }; bottomNavBar.Add(homeButton); // etc ... } public void SetupAppBar(AppBar appBar, NavDestination destination, NavController navController) { if (!destination.showAppBar) return; appBar.title = destination.label; } public void SetupDrawer(Drawer drawer, NavDestination destination, NavController navController) { if (!destination.showDrawer) return; drawer.Add(new DrawerHeader()); drawer.Add(new Divider { vertical = false }); var homeButton = new MenuItem {icon = "info", label = "Home", selectable = true}; homeButton.SetValueWithoutNotify(destination.name == Screens.home); homeButton.clickable.clicked += () => navController.Navigate(Actions.navigateToHome); drawer.Add(homeButton); // etc ... } public void SetupNavigationRail(NavigationRail navigationRail, NavDestination destination, NavController navController) { navigationRail.anchor = NavigationRailAnchor.End; navigationRail.labelType = LabelType.Selected; navigationRail.groupAlignment = GroupAlignment.Center; var homeButton = new NavigationRailItem { icon = "info", label = "Home", selected = destination.name == Destinations.home }; homeButton.clickable.clicked += () => navController.Navigate(Actions.navigateToHome); navigationRail.mainContainer.Add(homeButton); // etc ... } } ``` -------------------------------- ### Declare Action Creators in C# Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Demonstrates how to declare action creators using `ActionCreator` or `ActionCreator` classes directly. It shows the transition from using `Store.CreateAction` to simpler assignments, including implicit string conversion and `nameof` for payload types. ```csharp static readonly ActionCreator actionType0 = Store.CreateAction("actionType0"); static readonly ActionCreator actionType1 = Store.CreateAction("actionType1"); ``` ```csharp static readonly ActionCreator actionType0 = "actionType0"; // no payload static readonly ActionCreator actionType1 = nameof(actionType1); // with int payload ``` -------------------------------- ### Migrate Dropzone Logic to DropzoneController Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Explains the refactoring of the Dropzone component, where most logic is moved to a new `DropzoneController`. The `Dropzone` class now focuses on visuals, while the controller handles drop logic via an `acceptDrag` delegate and the `dropped` event. The `dragStarted` event has been removed. ```csharp // Before: var dropzone = new Dropzone(); dropzone.tryGetDroppableFromPath = TryGetDroppableFromPath; dropzone.tryGetDroppablesFromUnityObjects = TryGetDroppableFromUnityObjects; dropzone.dropped += OnDropped; dropzone.dragStarted += OnEditorDragStarted; dropzone.dragEnded += OnDragEndedOrCanceled; // After: var dropzone = new Dropzone(); var dropzoneController = dropzone.controller; dropzoneController.acceptDrag = ShouldAcceptDrag; dropzoneController.dropped += OnDropped; dropzoneController.dragEnded += OnDragEndedOrCanceled; ``` -------------------------------- ### Manage Store Subscriptions in C# Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Details the updated method for subscribing to store changes. Instead of returning a function for unsubscription, the `store.Subscribe` method now returns an `IDisposableSubscription` instance, which provides `Dispose()` and `IsValid()` methods for managing the subscription lifecycle. ```csharp Unsubscriber unsub; // Subscribe to store changes unsub = store.Subscribe("sliceName", state => { /* ... */ }); // Unsubscribe unsub(); ``` ```csharp IDisposableSubscription subscription; // Subscribe to store changes subscription = store.Subscribe("sliceName", state => { /* ... */ }); // Unsubscribe subscription.Dispose(); // Check if subscription is valid Assert.IsFalse(subscription.IsValid()); ``` -------------------------------- ### Replace Platform Theme Properties with DarkMode Boolean Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Describes the update to native platform theme handling, simplifying it to differentiate only between light and dark themes. The `Platform.systemThemeChanged` event and `Platform.systemTheme` string property are replaced by `Platform.darkModeChanged` event and `Platform.darkMode` boolean property. ```csharp // Before: Platform.systemThemeChanged += theme => Debug.Log($"Theme changed to {theme}"); if (Platform.systemTheme == "dark") { /* ... */ } // After: Platform.darkModeChanged += darkMode => Debug.Log($"Dark mode changed to {darkMode}"); if (Platform.darkMode) { /* ... */ } ``` -------------------------------- ### Redux Slice Reducer Builder: AddCase Method Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Details the change in Redux slice creation for defining reducers. The AddCase method replaces the Add method for primary reducers, while AddDefault and AddMatcher remain for extra reducers. ```csharp store.AddSlice("sliceName", new MySliceState(), builder => { builder.Add("actionType", (state, action) => { /* ... */ }); }); ``` ```csharp StoreFactory.CreateSlice("sliceName", new MySliceState(), builder => { builder.AddCase("actionType", (state, action) => { /* ... */ }); }); ``` -------------------------------- ### Update Reducer Signatures in C# Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Explains the change in reducer method signatures. Reducers now accept an `IAction` interface type as the second parameter instead of the older `Action` or `Action` types, improving type safety and consistency for payload handling. ```csharp // with no payload static MyAppState MyReducer1(MyAppState state, Action action) { /* ... */ } // with int payload static MyAppState MyReducer2(MyAppState state, Action action) { /* ... */ } ``` ```csharp // with no payload static MyAppState MyReducer1(MyAppState state, IAction action) { /* ... */ } // with int payload static MyAppState MyReducer2(MyAppState state, IAction action) { /* ... */ } ``` -------------------------------- ### Clipboard Text and PNG Operations Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/native-integration.md Provides examples for interacting with the system clipboard using Unity App UI. It demonstrates how to retrieve and set text content (UTF-8 encoded) and PNG image data from the clipboard. The code includes necessary encoding/decoding for text and handling byte arrays for image data, along with checks for data availability. ```csharp using UnityEngine; using Unity.AppUI.Core; using System.Text; public class ClipboardManager : MonoBehaviour { void InteractWithClipboard() { // --- Text Operations --- // Get text content from the clipboard byte[] clipboardTextBytes = Platform.GetPasteboardData(PasteboardType.Text); if (clipboardTextBytes != null && clipboardTextBytes.Length > 0) { string clipboardText = Encoding.UTF8.GetString(clipboardTextBytes); Debug.Log($"Clipboard text content: {clipboardText}"); } else { Debug.Log("Clipboard is empty or does not contain text."); } // Set text content to the clipboard string textToCopy = "Hello from Unity App UI!"; Platform.SetPasteboardData(PasteboardType.Text, Encoding.UTF8.GetBytes(textToCopy)); Debug.Log($"Set clipboard text to: {textToCopy}"); // --- PNG Image Operations --- // Get PNG image content from the clipboard byte[] clipboardImageBytes = Platform.GetPasteboardData(PasteboardType.PNG); if (clipboardImageBytes != null && clipboardImageBytes.Length > 0) { Texture2D texture = new Texture2D(2, 2); // Create a dummy texture if (texture.LoadImage(clipboardImageBytes)) { Debug.Log($"Clipboard image loaded: {texture.width}x{texture.height}"); // You can now use this texture, e.g., assign it to a UI Image component } else { Debug.LogError("Failed to load image from clipboard data."); } } else { Debug.Log("Clipboard is empty or does not contain PNG data."); } // Set PNG image content to the clipboard // Example: Create a simple 1x1 red texture Texture2D textureToCopy = new Texture2D(1, 1); textureToCopy.SetPixel(0, 0, Color.red); textureToCopy.Apply(); byte[] imageBytesToCopy = textureToCopy.EncodeToPNG(); Platform.SetPasteboardData(PasteboardType.PNG, imageBytesToCopy); Debug.Log("Set clipboard PNG data."); // --- Check for data --- bool hasText = Platform.HasPasteboardData(PasteboardType.Text); Debug.Log($"Clipboard has text data: {hasText}"); bool hasPng = Platform.HasPasteboardData(PasteboardType.PNG); Debug.Log($"Clipboard has PNG data: {hasPng}"); } } ``` -------------------------------- ### Build and Configure Modal Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/overlays.md Illustrates the creation and configuration of a Modal dialog using a fluent API. This includes setting full-screen mode and other potential configurations for modal dialogs. ```APIDOC Modal.Build(content) .SetFullScreenMode(ModalFullScreenMode.None) // ... other configurations // Methods: // Build(content): Creates a new Modal builder instance. // - content: The UI content to display within the modal. // SetFullScreenMode(mode): Sets the modal to occupy the full screen or a specific mode. // - mode: An enum value from ModalFullScreenMode (e.g., None, Auto, Always). // Additional methods for configuration would follow a similar pattern to Popover. ``` -------------------------------- ### MyApp Entry Point Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/mvvm-sample.md Shows the MyApp class, an implementation of App, serving as the entry point for the application. It defines the main UI by adding the MainPage to the rootVisualElement and utilizes Dependency Injection for service resolution. ```C# public class MyApp : App { public new static MyApp current => (MyApp)App.current; public override void InitializeComponent() { base.InitializeComponent(); rootVisualElement.Add(services.GetRequiredService()); } public override void Shutdown() { // Called when the app is shutting down } } ``` -------------------------------- ### Get Localized String with LangContext (C#) Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/localization.md Demonstrates how to retrieve a localized string using the `LangContext`. It registers a callback for context changes and shows how to get the current localized string asynchronously. Requires the `Unity.AppUI.UI` namespace and `Unity.AppUI.Core.LangContext`. ```C# using Unity.AppUI.UI; public class MyComponent : BaseVisualElement { public MyComponent() { this.RegisterContextChangedCallback(OnLangContextChanged); } // This method will be called when the LangContext changes async void OnLangContextChanged(ContextChangedEvent evt) { var ctx = evt.context; if (ctx != null) { var translatedString = await ctx.GetLocalizedStringAsync("@myTable:myEntry"); } } // This method will check for the currently provided locale // without using any listener public void TranslateNow() { var ctx = this.GetContext(); if (ctx != null) { var translatedString = ctx.GetLocalizedStringAsync("@myTable:myEntry"); } } } ``` -------------------------------- ### Build and Configure Menu Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/overlays.md Shows how to construct a context menu or navigation menu using a fluent API. It supports adding actions, pushing sub-menus, and displaying them relative to a target element. ```APIDOC MenuBuilder.Build(anchor) .AddAction(123, "An Item", "info", evt => Debug.Log("Item clicked")) .PushSubMenu(456, "My Sub Menu", "help") .AddAction(789, "Sub Menu Item", "info", evt => Debug.Log("Sub Item clicked")) .PushSubMenu(3455, "Another Sub Menu", "help") .AddAction(7823129, "Another Sub Menu Item", "info", evt => Debug.Log("Other Item clicked")) .Pop() .Pop() .Show(); // Methods: // Build(anchor): Initializes the MenuBuilder with a target anchor element. // - anchor: The UI element the menu will be displayed next to. // AddAction(id, text, icon, onClick): Adds a clickable menu item. // - id: Unique identifier for the action. // - text: The display text for the menu item. // - icon: Optional icon identifier or path. // - onClick: Event handler for when the item is clicked. // PushSubMenu(id, text, icon): Creates and pushes a new sub-menu onto the stack. // - id: Unique identifier for the sub-menu. // - text: The display text for the sub-menu trigger. // - icon: Optional icon identifier or path. // Pop(): Removes the current sub-menu from the stack, returning to the parent menu. // Show(): Displays the constructed menu. ``` -------------------------------- ### ActionGroup Component Usage Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/actions.md Provides an example of how to group multiple ActionButton components using the ActionGroup component, allowing for toggling between different actions. ```xml ``` -------------------------------- ### Build and Configure Popover Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/overlays.md Demonstrates how to build and configure a Popover component using a fluent API. This includes setting placement, flip behavior, offsets, arrow visibility, padding, dismissal behavior, and modal backdrop. ```APIDOC Popover.Build(target, content) .SetPlacement(placement) .SetShouldFlip(shouldFlip) .SetOffset(offset) .SetCrossOffset(crossOffset) .SetArrowVisible(showArrow) .SetContainerPadding(containerPadding) .SetOutsideClickDismiss(outsideClickDismissEnabled) .SetModalBackdrop(modalBackdrop) .SetKeyboardDismiss(keyboardDismissEnabled); // Methods: // Build(target, content): Creates a new Popover builder instance. // - target: The UI element the popover is anchored to. // - content: The UI content to display within the popover. // SetPlacement(placement): Sets the preferred placement of the popover relative to the target. // - placement: An enum value indicating the desired position (e.g., Top, Bottom, Left, Right). // SetShouldFlip(shouldFlip): Enables or disables automatic flipping of placement if the popover overflows the screen. // - shouldFlip: Boolean, true to enable flipping, false otherwise. // SetOffset(offset): Sets the distance between the popover and the target element. // - offset: Float value for the offset. // SetCrossOffset(crossOffset): Sets the offset along the cross axis relative to the target. // - crossOffset: Float value for the cross offset. // SetArrowVisible(showArrow): Controls the visibility of the arrow pointing to the target. // - showArrow: Boolean, true to show the arrow, false to hide it. // SetContainerPadding(containerPadding): Sets padding around the popover content. // - containerPadding: Float value for padding. // SetOutsideClickDismiss(outsideClickDismissEnabled): Configures whether clicking outside the popover dismisses it. // - outsideClickDismissEnabled: Boolean, true to enable dismissal, false otherwise. // SetModalBackdrop(modalBackdrop): Configures the modal backdrop behavior. // - modalBackdrop: Boolean, true to show a modal backdrop, false otherwise. // SetKeyboardDismiss(keyboardDismissEnabled): Configures whether pressing the Escape key dismisses the popover. // - keyboardDismissEnabled: Boolean, true to enable dismissal, false otherwise. // Show(): Displays the configured popover. ``` -------------------------------- ### Gesture Handling: Magnification and Pan Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Demonstrates the refactoring of gesture handling in Unity App UI. MagnificationGestureEvent is replaced by PinchGestureEvent, and PanGestureEvent is replaced by WheelEvent for pan-like behavior on non-touch devices. ```csharp public class MyComponent : VisualElement { public MyComponent() { this.AddManipulator(new MagnificationManipulator()); this.RegisterCallback(OnMagnification); this.RegisterCallback(OnPan); } private void OnMagnification(MagnificationGestureEvent evt) { /* ... */ } private void OnPan(PanGestureEvent evt) { /* ... */ } } ``` ```csharp public class MyComponent : VisualElement { public MyComponent() { this.AddManipulator(new PinchManipulator()); this.RegisterCallback(OnPinch); this.RegisterCallback(OnPan); } private void OnPinch(PinchGestureEvent evt) { /* ... */ } private void OnPan(WheelEvent evt) { /* ... */ } } ``` -------------------------------- ### Generic StoryBookEnumProperty in C# Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Illustrates the change of `StoryBookEnumProperty` to a generic class. This update allows it to handle any enum type directly, simplifying usage and preventing casting errors compared to the previous non-generic implementation. ```csharp var enumProperty = new StoryBookEnumProperty( nameof(Button.variant), (btn) => ((Button)btn).variant, (btn, val) => ((Button)btn).variant = (ButtonVariant)val); ``` ```csharp var enumProperty = new StoryBookEnumProperty( nameof(Button.variant), (btn) => ((Button)btn).variant, (btn, val) => ((Button)btn).variant = val); ``` -------------------------------- ### Create Redux Store with Simple State Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/state-management.md Demonstrates how to create a Redux store using the generic `Store.CreateStore` method. It takes the state type, a reducer function, and an initial state object as parameters. ```csharp using Unity.AppUI.Redux; record MyState {} var store = Store.CreateStore((state, action) => state, new MyState()); ``` -------------------------------- ### MyAppBuilder Implementation Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/mvvm-sample.md Demonstrates the MyAppBuilder class, an implementation of UIToolkitAppBuilder, used to define runtime app configuration and hook into the app lifecycle events. It allows specifying the App implementation and handling initialization and shutdown. ```C# public class MyAppBuilder : UIToolkitAppBuilder { protected override void OnAppInitialized(MyApp app) { base.OnAppInitialized(app); // Called after the app is initialized } protected override void OnConfiguringApp(AppBuilder builder) { base.OnConfiguringApp(builder); // Called during app configuration } protected override void OnAppShuttingDown(MyApp app) { base.OnAppShuttingDown(app); // Called before the app is shut down } } ``` -------------------------------- ### Register Dependencies in AppBuilder Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/mvvm-di.md Provides an example of how to register custom dependencies within the App UI framework. It shows accessing the IServiceCollection via the AppBuilder during the OnConfiguringApp event to add services. ```csharp public class MyAppBuilder : UIToolkitAppBuilder { protected override void OnConfiguringApp(AppBuilder appBuilder) { base.OnConfiguringApp(appBuilder); // Register dependencies here // ex: appBuilder.services.AddSingleton(); } } ``` -------------------------------- ### Unity App UI Core Platform API Reference Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/native-integration.md This section provides an overview of key properties and methods available in the `Unity.AppUI.Core.Platform` class for interacting with the underlying operating system and device features. It covers accessing system-level information and triggering platform-specific actions. ```APIDOC Unity.AppUI.Core.Platform: // Properties textScaleFactor: float // Description: Gets the current text scaling factor applied by the system. // Use case: Adjust font sizes or UI element dimensions based on user's text scaling preference. layoutDirection: LayoutDirection // Description: Gets the current layout direction of the system (e.g., Left-to-Right or Right-to-Left). // Use case: Adapt UI layout for different language directions, e.g., using flexbox properties. darkMode: bool // Description: Gets a boolean indicating whether the system theme is currently set to dark mode. // Use case: Dynamically change the application's theme (light/dark) to match the system setting. // Events systemThemeChanged: event Action // Description: Event that is invoked when the system's dark mode setting changes. // Parameters: // darkMode: bool - True if the new system theme is dark, false otherwise. // Use case: Subscribe to this event to update the application's theme in real-time. // Methods RunHapticFeedback(): void // Description: Triggers haptic feedback on supported platforms (e.g., iOS, Android). // Limitations: Currently, no App UI components use this directly; it's for custom implementation. // Use case: Provide tactile feedback for user interactions. GetPasteboardData(pasteboardType: PasteboardType): byte[] // Description: Retrieves data from the system clipboard for a specified pasteboard type. // Parameters: // pasteboardType: PasteboardType - The type of data to retrieve (e.g., Text, PNG). // Returns: byte[] - The data from the clipboard, or null/empty if no data of that type is available. // Supported Types: // PasteboardType.Text: UTF-8 encoded string. // PasteboardType.PNG: PNG image data. // Notes: // On Windows, Text content is automatically converted between UTF-8 (C#) and UTF-16LE (OS). // Use case: Copying text or images from other applications into your app. SetPasteboardData(pasteboardType: PasteboardType, data: byte[]): void // Description: Sets data to the system clipboard for a specified pasteboard type. // Parameters: // pasteboardType: PasteboardType - The type of data to set (e.g., Text, PNG). // data: byte[] - The byte array containing the data to be placed on the clipboard. // Supported Types: // PasteboardType.Text: UTF-8 encoded string. // PasteboardType.PNG: PNG image data. // Notes: // On Windows, Text content is automatically converted between UTF-8 (C#) and UTF-16LE (OS). // Use case: Copying text or images from your app to the system clipboard. HasPasteboardData(pasteboardType: PasteboardType): bool // Description: Checks if the system clipboard currently contains data of the specified type. // Parameters: // pasteboardType: PasteboardType - The type of data to check for (e.g., Text, PNG). // Returns: bool - True if data of the specified type is available, false otherwise. // Use case: Pre-checking clipboard content before attempting to retrieve it. // Enum Unity.AppUI.Core.PasteboardType: Text PNG ``` -------------------------------- ### Create Redux Store with Slices Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/state-management.md Shows how to create a Redux store using `StoreFactory.CreateStore` with multiple slices. Each slice is defined with a name, initial state, and a builder function for configuration, enabling modular state management. ```csharp using Unity.AppUI.Redux; record MyState {} var store = StoreFactory.CreateStore(new [] { StoreFactory.CreateSlice( "mySlice", new MyState(), builder => { /* ... */ }, ) }); ``` -------------------------------- ### React to Layout Direction Changes with ContextChangedEvent Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/accessibility.md Provides an example of registering a callback for `ContextChangedEvent` to programmatically react to changes in the layout direction context. This allows for dynamic UI logic adjustments based on LTR or RTL settings. ```csharp using Unity.AppUI.Core; using Unity.AppUI.UI; var myElement = new VisualElement(); myElement.RegisterContextChangedCallback(OnDirContextChanged); void OnDirContextChanged(ContextChangedEvent evt) { var dir = evt.context?.dir ?? Dir.Ltr; UpdateMyLogic(dir); } ``` -------------------------------- ### Resolve Scoped Service in ViewModel Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/mvvm-di.md Shows how to resolve a scoped service within a ViewModel. This example demonstrates obtaining a scoped service instance by creating a new service scope and then retrieving the dependency from that scope. ```csharp using Unity.AppUI.MVVM; public class MyViewModel : ObservableObject { public MyViewModel(IServiceProvider serviceProvider) { using (var scope = serviceProvider.CreateScope()) { var scopedService = scope.ServiceProvider.GetRequiredService(); } } } ``` -------------------------------- ### Logger Middleware and Store Enhancement in C# Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/state-management.md Illustrates how to create a logger middleware that logs actions before they are dispatched and how to combine multiple middlewares using Store.ApplyMiddleware to create a store enhancer. This enhancer is then used to create a store with the logging functionality. ```cs using Unity.AppUI.Redux; using UnityEngine; public static class Application { public static Middleware LoggerMiddleware() where TStore : Store { return (store) => (nextMiddleware) => (action) => { Debug.Log($"Action: {action.type}"); return nextMiddleware(action); }; } public static StoreEnhancer EnhanceStoreWithLogger() where TStore : Store { return Store.ApplyMiddleware(LoggerMiddleware()); } static void Main() { // At this point you can use your Enhancer to create a new store with the logger middleware. var store = Store.CreateStore(new [] { Store.CreateSlice( "mySlice", new MyState(), // Assuming MyState is defined elsewhere builder => { /* ... */ }), }, EnhanceStoreWithLogger()); } } ``` -------------------------------- ### Redux Slice Reducer Builder: Action Creator Usage Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/migrate.md Explains how to use ActionCreator instances or string representations with the Redux slice builder's AddCase method. Explicit casting is required when passing string action types. ```csharp store.AddSlice("sliceName", new MySliceState(), builder => { builder.Add("actionType", (state, action) => { /* ... */ }); }); ``` ```csharp static readonly ActionCreator actionType0 = "actionType0"; // no payload static readonly ActionCreator actionType1 = nameof(actionType1); // with int payload StoreFactory.CreateSlice("sliceName", new MySliceState(), builder => { builder.AddCase((ActionCreator)"actionType2", (state, action) => { /* ... */ }); // cast to ActionCreator }); ``` -------------------------------- ### Use App UI Components in EditorWindow Source: https://github.com/thephuongcqt/unity-app-ui-docs/blob/main/faq.md Demonstrates how to integrate App UI components within Unity's EditorWindow class. It covers loading the necessary theme stylesheet either programmatically via C# or directly within the UXML file. ```cs class MyWindow : EditorWindow { void CreateGUI() { const string defaultTheme = "Packages/com.unity.dt.app-ui/PackageResources/Styles/Themes/App UI.tss"; rootVisualElement.styleSheets.Add(AssetDatabase.LoadAssetAtPath(defaultTheme)); rootVisualElement.AddToClassList("unity-editor"); // Enable Editor related styles } } ``` ```xml