libcosmic

repository·master·Indexed 21 days ago

https://github.com/pop-os/libcosmic

A platform toolkit built on top of the iced framework for creating applications and applets for the COSMIC™ desktop environment. It provides a suite of widgets (calendar, context-menu, image-button, menu, nav-context, text-input), multi-window management, and a comprehensive configuration system via cosmic-config for managing persistent settings, state, and data using RON format.

Tokens
25.1K
Snippets
92
Records
111
Agent score
74%

What's inside libcosmic

  1. Run libcosmic examples using `just`

    master

    The libcosmic repository includes several example projects that demonstrate specific widgets and API usage. You can run these examples using the just command-line tool. Each example is invoked with just run <example-name>.

    # Example: Run the application template
    just run application
    
    # Example: Run the calendar widget demo
    just run calendar
  2. Install system dependencies for libcosmic

    master

    To compile a typical COSMIC project on Pop!_OS, you must install several shared system library headers. Use the following command to install the necessary dependencies:

    sudo apt install cargo cmake just libexpat1-dev libfontconfig-dev libfreetype-dev libxkbcommon-dev pkgconf
  3. Run libcosmic examples

    master

    To run the included examples, clone the repository with submodules and use just to execute them.

    git clone --recurse-submodules https://github.com/pop-os/libcosmic
    cd libcosmic
    just run <project_name>

    If you have an existing clone, sync it first:

    git fetch origin
    git checkout master
    git reset --hard origin/master
    git clone --recurse-submodules https://github.com/pop-os/libcosmic
    cd libcosmic
    just run application
  4. Identify COSMIC Applications and Applets in Flatpak metainfo

    master

    To ensure your project is correctly identified by the COSMIC desktop, you must add specific IDs to the <provides> section of your project's metainfo file.

    For COSMIC Applications

    Use com.system76.CosmicApplication.

    For COSMIC Applets

    Use com.system76.CosmicApplet.

    <!-- For Applications -->
    <provides>
      <id>com.system76.CosmicApplication</id>
    </provides>
    
    <!-- For Applets -->
    <provides>
      <id>com.system76.CosmicApplet</id>
    </provides>
  5. Use the cosmic-theme library modules

    master

    The cosmic-theme library provides utilities for creating custom themes through several modules:

    • model: Contains the core data models for theme definitions.
    • palette: Provides tools for managing color palettes.
    • composite: Utilities for working with composite colors in sRGB.
    • steps: Utilities for calculating color steps.

    Note: If the export feature is enabled, the output module is also available for exporting theme data.

  6. Associate custom data with Segmented Button items

    master

    There are three ways to attach data to items in a Model using the BuilderEntity:

    1. Internal Data: Use .data(data) to attach a component directly to the item. The model stores this internally, but you can only have one component per Rust type.
    2. Secondary Map: Use .secondary(map, data) to associate data using a slotmap::SecondaryMap. This is efficient for data that is commonly associated with items and uses a Vec internally.
    3. Sparse Secondary Map: Use .secondary_sparse(map, data) to associate data using a slotmap::SparseSecondaryMap. This is more efficient for data that is only associated with a small subset of items, as it uses a HashMap internally.
    // Using internal data
    builder.insert(|b| b.text("Home").data(ViewItem::Home));
    
    // Using an external secondary map
    let mut my_map = SecondaryMap::new();
    builder.insert(|b| b.text("Profile").secondary(&mut my_map, ProfileData::User));
  7. How Segmented Button Model manages items and selection

    master

    A Model in libcosmic acts as a central registry for segmented button items. It manages several distinct aspects of an item's lifecycle:

    1. Identity: Each item is identified by a unique Entity ID. These IDs are stable until the item is explicitly removed.
    2. Visual State: The model stores visual properties like text, icons, indents, and divider_aboves in separate internal maps, keyed by the Entity ID.
    3. Selection Mode: The model is generic over a SelectionMode. This determines how items are selected (e.g., SingleSelect or MultiSelect).
    4. Ordering: Items are stored in a VecDeque<Entity> to maintain a specific display order, independent of their storage in internal maps.
    5. Lifecycle: When an item is removed via remove(id), the model cleans up its visual properties, its position in the order, and any custom data associated with it in the Storage map.
  8. How to use the COSMIC Core

    master

    Every application model requires a cosmic::Core (found in cosmic::core::Core). The Core contains state managed by the libcosmic runtime, including:

    • Context drawer
    • Navigation bar
    • Headerbar

    Developers use the Core to subscribe to configuration changes and to emit events to the parts of the application's state and view that are managed by the libcosmic runtime.

  9. How COSMIC applications and applets work (MVU Pattern)

    master

    COSMIC applications and applets are built using the Model-View-Update (MVU) pattern, based on the iced framework. To build an application, you must implement the Application trait, which consists of three main parts:

    1. Model: A struct that holds the persistent application state.
    2. View (Application::view): A function that borrows data from the model to construct a user interface using stateless widgets.
    3. Update (Application::update): A function that receives messages (from widgets, tasks, or subscriptions) and updates the model or spawns background tasks.

    Tasks and Subscriptions

    • Tasks: Returned by the update function, tasks run concurrently on a background thread (using tokio by default). They can be futures or streams that emit messages back to the application.
    • Subscriptions: Defined via Application::subscription, these allow the app to listen to external asynchronous event streams. Subscriptions can be started, stopped, or restarted dynamically based on changes in the application model.
  10. How to compose custom widgets

    master

    Widgets in libcosmic are composable and configurable via chainable builder methods. You can create complex interfaces by composing existing widgets.

    Custom Composed Widgets: If you create a custom type to manage a group of widgets, it is a common pattern to implement its own view and update functions. To make your custom widget compatible with the libcosmic API (allowing it to be treated like a native widget), implement From<YourCustomWidget> for the Element type.

    Advanced Custom Widgets: If a specific widget does not exist, you can implement the iced::advanced::Widget trait to create an advanced custom widget, which can then be composed into higher-level widgets.

  11. Build a Segmented Button Model using ModelBuilder

    master

    To create a Model for a segmented button, use the ModelBuilder pattern. You start with a ModelBuilder, use the insert method to define individual items via a closure that provides a BuilderEntity, and finally call build() to consume the builder and return the completed Model.

    Each BuilderEntity allows you to configure properties for a specific item, such as its text, icon, position, or associated data, before it is finalized in the model.

    // Example of building a segmented button model
    let model = segmented_button::Model::builder()
        .insert(|b| b.text("Item A").icon("custom-icon"))
        .insert(|b| b.text("Item B").activate())
        .build();