Skip to content

Reusable Widget Library

Joseph Chacko edited this page Jul 22, 2026 · 2 revisions

Reusable Widget Library (CustomComp.slint)

Relevant source files

The following files were used as context for generating this wiki page:

The CustomComp.slint file serves as the primary UI component library for the Aurora Music Player. It defines the visual language and interactive behavior of all reusable elements, from low-level sliders to high-level responsive grids. These components are designed to be theme-aware, utilizing the global Theme singleton to maintain visual consistency.

Core Layout & Navigation Components

ScrollView

The ScrollView component provides a clipped container for vertical content. It implements manual viewport calculation to handle overflow logic without relying on standard OS scrollbars, ensuring a consistent look across platforms.

  • Implementation: It uses a TouchArea to capture scroll-event data, updating a viewport-y property constrained between 0px and the negative of the content's overflow height [app/ui/CustomComp.slint:22-25]().
  • Auto-Reset: When the content-height changes (e.g., filtering a list), the viewport-y is reset to 0 [app/ui/CustomComp.slint:13-15]().

Responsive Grid (PlList)

The PlList component implements a responsive grid for displaying PlaylistCard elements. It dynamically calculates the number of columns based on the available width.

  • Logic: It calculates column_count by dividing the total width by a target card width (170px) and then determines the necessary row_count [app/ui/CustomComp.slint:397-402]().
  • Data Mapping: It uses a nested for loop structure to map a flat [PlaylistMinimal] model into a grid layout [app/ui/CustomComp.slint:406-421]().
Component Purpose Key Properties
ScrollView Custom vertical scrolling direction, viewport-y
PlList Responsive playlist grid playlists, column_count
SongCardRow Horizontal scrollable row songs, title

Sources: [app/ui/CustomComp.slint:4-36](), [app/ui/CustomComp.slint:391-425](), [app/ui/CustomComp.slint:427-464]()


Interactive Controls

CustomSlider (Seek & Volume)

The CustomSlider is a sophisticated input component used for the track seek bar and volume control. It features "pressed-state decoupling" to prevent the UI from flickering while the backend updates the playback position.

  • Decoupling Logic: When a user drags the slider, root.pressed is set to true. This prevents the incoming value property (synced from the daemon) from overwriting the displayValue currently being manipulated by the user [app/ui/CustomComp.slint:56-60]().
  • Hover States: It supports a secondary "hover" fill (normalizedDisplayHoverValue) that shows where the value would jump if clicked [app/ui/CustomComp.slint:71-82]().
  • Event Flow: On PointerEventKind.up, the component sets pressed = false and fires the released(float) callback to notify the Rust backend of the final value [app/ui/CustomComp.slint:115-118]().

ComboBox

A custom dropdown implementation for selection lists (e.g., Search Type). It manages its own expanded state and uses a clip: true rectangle with an animated height for the dropdown transition [app/ui/CustomComp.slint:166-177]().

Sources: [app/ui/CustomComp.slint:38-123](), [app/ui/CustomComp.slint:125-214]()


Data Display Components

SongList & SongCard

These components represent individual tracks or collections of tracks.

  • SongList: A dense, vertical list of songs. It supports:
    • Multi-selection: Tracks selected_songs via an array of UUID strings [app/ui/CustomComp.slint:273]().
    • Liked Toggle: A dedicated heart icon that triggers the toggle-liked callback [app/ui/CustomComp.slint:365-373]().
    • Selection Logic: Clicking a song updates the selection model; holding Shift (handled in interface.rs) allows for range selection [app/ui/CustomComp.slint:323-332]().
  • SongCard: A graphical tile for songs, featuring the album art (or a placeholder) and metadata. It highlights if current is true (currently playing) [app/ui/CustomComp.slint:216-267]().

PlaylistCard

A square tile representing a playlist. It includes a play button overlay that appears on hover, allowing users to immediately play a playlist without entering its detail view [app/ui/CustomComp.slint:489-498]().

Sources: [app/ui/CustomComp.slint:216-267](), [app/ui/CustomComp.slint:271-389](), [app/ui/CustomComp.slint:466-515]()


Context Menus & Overlays

Aurora implements custom context menus to handle right-click actions on songs and playlists. These are managed via global coordinates to ensure they appear above all other UI elements.

Context Menu Logic

The ContextMenu component (and its variants PlContextMenu, QueueContextMenu) uses an absolute positioning strategy.

  1. Trigger: A TouchArea in SongList detects a right-click via pointer-event [app/ui/CustomComp.slint:333-342]().
  2. Positioning: The open_context_menu callback is fired with the mouse coordinates.
  3. Overflow Protection: The menu calculates its own width/height to ensure it doesn't render outside the window boundaries.

Menu Variants

Menu Type Context Actions
ContextMenu Library / Search Play, Enqueue, Add to Playlist, Like
PlContextMenu Playlist View Play, Enqueue, Remove from Playlist
QueueContextMenu Now Playing / Queue Play now, Remove from Queue, Clear Queue

Sources: [app/ui/CustomComp.slint:517-640](), [app/ui/CustomComp.slint:642-736](), [app/ui/CustomComp.slint:738-812]()


Component Architecture Diagram

The following diagram illustrates how the Slint properties and callbacks bridge the UI state to the Rust backend logic defined in interface.rs.

UI Data Flow and Interaction Bridge

graph TD
    subgraph "Slint UI Space (CustomComp.slint)"
        SC["SongList Component"]
        CS["CustomSlider"]
        CM["ContextMenu"]
    end

    subgraph "Rust Backend Space (interface.rs)"
        IC["interface() loop"]
        US["unix_sender (mpsc)"]
        SS["StateStruct (Slint)"]
    end

    SC -- "callback play_song(Song)" --> IC
    SC -- "callback toggle_liked(string)" --> IC
    CS -- "callback released(float)" --> IC
    CM -- "callback menu_action(string, string)" --> IC

    IC -- "Request::Enqueue / Request::Seek" --> US
    US -- "JSON IPC" --> Daemon["aurora-daemon"]
    
    Daemon -- "Response::Status" --> IC
    IC -- "SS.set_status_..." --> SS
    SS -- "Property Binding" --> CS
    SS -- "Property Binding" --> SC
Loading

Sources: [app/ui/CustomComp.slint:271-285](), [app/ui/CustomComp.slint:49-54](), [app/src/interface.rs:240-300]()


Visual Entity Mapping

This diagram maps the visual components defined in CustomComp.slint to the data structures they consume from Types.slint and the protocol.

Component to Data Type Mapping

classDiagram
    class Song {
        +string uuid
        +string title
        +string artist
        +string album
    }
    class PlaylistMinimal {
        +string name
        +int song_count
    }
    class Theme {
        +color bgd0
        +color acct
        +color txt1
    }

    class SongCard {
        <<Component>>
        +Song song
        +bool current
        +clicked()
    }
    class SongList {
        <<Component>>
        +[Song] songs
        +[string] selected_songs
        +play_song(Song)
    }
    class PlaylistCard {
        <<Component>>
        +PlaylistMinimal playlist
        +play_playlist(string)
    }

    SongCard --> Song : consumes
    SongList --> Song : consumes
    PlaylistCard --> PlaylistMinimal : consumes
    SongCard ..> Theme : styled by
    SongList ..> Theme : styled by
Loading

Sources: [app/ui/CustomComp.slint:216-218](), [app/ui/CustomComp.slint:271-274](), [app/ui/CustomComp.slint:466-467](), [app/ui/Types.slint:13-25]()

Clone this wiki locally