tray-controls

Crates.iotray-controls
lib.rstray-controls
version0.1.2
created_at2025-12-30 11:37:57.809591+00
updated_at2025-12-30 17:21:08.141044+00
descriptionAn enhanced menu management tool designed for the tray-icon library
homepagehttps://github.com/iKineticate/tray-controls
repositoryhttps://github.com/iKineticate/tray-controls
max_upload_size
id2012515
size107,237
(iKineticate)

documentation

https://docs.rs/tray-controls

README

tray-controls

Licence Crates.io version

English | 简体中文

An enhanced menu management utility designed for the tray-icon crate. It provides structured management for Radio, CheckBox, and other menu item types, and is especially suitable for applications that require single-selection menus or complex system tray menus.


Features

🎯 Core Advantages

  • Unified Menu Management Easily manage multiple menu item types, including:

    • Standard menu items
    • Icon menu items
    • Checkboxes
    • Radio buttons
  • Group Management Automatically manages Radio menu groups to ensure correct single-selection behavior.

  • Direct Access by ID Access and modify any menu item and its properties directly via its ID.


🔧 Problems This Crate Solves

When using the tray-icon crate, menu event handling only provides the menu ID, not the actual menu item object. As a result:

  • Direct access to the clicked menu item is difficult
  • Updating menu properties (e.g. text, checked state) is inconvenient
  • Synchronizing grouped menus (such as Radio buttons) requires manual bookkeeping

This crate solves these issues by introducing a centralized menu manager that maintains ownership and state of all menu items.


Usage

Add the dependency to your Cargo.toml:

[dependencies]
tray-control = "0.1.2"
tray-icon = "0.21.2"

Example

An example demonstrating usage with winit + tray-icon + tray-control:


Core Components

MenuControl<G>

Represents different types of menu items:

pub enum MenuControl<G> {
    MenuItem(tray_icon::MenuItem),      // Standard menu item
    IconMenu(tray_icon::IconMenuItem),  // Menu item with icon
    CheckMenu(CheckMenuKind<G>),        // Checkbox / Radio menu item
}

CheckMenuKind<G>

Defines the specific behavior of a checkable menu item:

pub enum CheckMenuKind<G> {
    CheckBox(Rc<CheckMenuItem>, G), 
    // Checkbox menu item with group identifier

    Radio(Rc<CheckMenuItem>, Option<Rc<DefaultMenuId>>, G), 
    // Radio menu item with option default selection and group identifier

    Separate(Rc<CheckMenuItem>), 
    // Independent checkbox menu item (not grouped)
}

MenuManager<G>

The core manager responsible for menu storage, grouping, and state synchronization:

pub struct MenuManager<G>
where
    G: Clone + Eq + Hash + PartialEq,
{ /* private fields */ }

Example Code

#[derive(Clone, Eq, Hash, PartialEq)]
enum MenuGroup {
    CheckBoxA,
    CheckBoxB,
    RadioA,
    RadioB,
}

let mut manager = MenuManager::<MenuGroup>::new();

manager.insert(MenuControl::CheckMenu(
    CheckMenuKind::CheckBox(
        Rc::new(checkbox_menu_item),
        MenuGroup::CheckBoxA,
    ),
));

manager.insert(MenuControl::CheckMenu(
    CheckMenuKind::Radio(
        Rc::new(radio_menu_item),
        Some(MenuId::new("default_radio_id")),
        MenuGroup::RadioA,
    ),
));

// Use together with tray-icon's MenuEvent::set_event_handler
manager.update(&menu_id, |menu| {
    if let Some(menu) = menu {
        println!("Clicked or toggled menu text: {}", menu.text());
    }
});

When to Use This Crate

This crate is particularly useful if:

  • You rely on tray-icon and need structured menu state management
  • Your tray menu includes Radio or grouped CheckBox items
  • You want to decouple menu logic from low-level event handling
Commit count: 0

cargo fmt