fission-shell-desktop 0.2.0

Desktop shell wrapper for Fission applications
Documentation
#![cfg(feature = "tray")]

use fission_core::ui::{Button, Column, Text};
use fission_core::{reduce_with, AppState, BuildCtx, View, Widget};
use fission_shell_desktop::{
    DesktopApp, TrayActivateBehavior, TrayConfig, TrayHostAction, TrayIconSource, TrayMenu,
    TrayMenuAction, TrayMenuWidget, WindowCloseBehavior,
};

#[derive(Default, Debug, Clone, PartialEq, Eq)]
struct TrayApiState {
    refreshed: bool,
}

impl AppState for TrayApiState {}

#[fission_macros::fission_reducer(RefreshTray)]
fn on_refresh_tray(state: &mut TrayApiState) {
    state.refreshed = true;
}

struct TrayMenuModel;

impl TrayMenuWidget<TrayApiState> for TrayMenuModel {
    fn build(&self, ctx: &mut BuildCtx<TrayApiState>, _view: &View<TrayApiState>) -> TrayMenu {
        let refresh = ctx.bind(RefreshTray, reduce_with!(on_refresh_tray));
        TrayMenu::new()
            .item("Show", TrayMenuAction::host(TrayHostAction::ShowMainWindow))
            .item("Refresh", TrayMenuAction::app(refresh))
            .item("Quit", TrayMenuAction::host(TrayHostAction::QuitApp))
    }
}

struct TrayApp;

impl Widget<TrayApiState> for TrayApp {
    fn build(
        &self,
        _ctx: &mut BuildCtx<TrayApiState>,
        view: &View<TrayApiState>,
    ) -> fission_core::Node {
        Column {
            children: vec![
                Text::new(if view.state.refreshed {
                    "Refreshed"
                } else {
                    "Ready"
                })
                .into_node(),
                Button {
                    child: Some(Box::new(Text::new("Keep running").into_node())),
                    ..Default::default()
                }
                .into_node(),
            ],
            ..Default::default()
        }
        .into_node()
    }
}

#[test]
fn desktop_app_accepts_tray_config_with_menu_widget() {
    let tray =
        TrayConfig::<TrayApiState>::new(TrayIconSource::rgba(vec![255, 255, 255, 255], 1, 1))
            .tooltip("Tray API smoke")
            .close_behavior(WindowCloseBehavior::HideToTray)
            .activate_behavior(TrayActivateBehavior::ToggleMainWindow)
            .menu(TrayMenuModel);

    let _app = DesktopApp::new(TrayApp).with_tray(tray);
}