fui_examples 0.18.0

Examples for FUI UI Framework
#![windows_subsystem = "windows"]

use anyhow::{Error, Result};
use fui_app::*;
use fui_controls::*;
use fui_core::*;
use fui_macros::ui;
use windowing_qt::*;

use std::cell::RefCell;
use std::rc::Rc;

use std::fs::File;
use std::io::Read;
use std::path::Path;
use tokio::task::LocalSet;
use typed_builder::TypedBuilder;
use typemap::TypeMap;

struct MainViewModel {
    pub counter: Property<i32>,
    pub counter2: Property<i32>,
}

impl MainViewModel {
    pub fn new() -> Rc<Self> {
        Rc::new(MainViewModel {
            counter: Property::new(10),
            counter2: Property::new(0),
        })
    }

    pub fn increase(self: &Rc<Self>) {
        self.counter.change(|c| c + 1);
    }

    pub fn decrease(self: &Rc<Self>) {
        self.counter.change(|c| c - 1);
    }
}

#[derive(TypedBuilder)]
pub struct ButtonText {
    #[builder(default = Property::new("".to_string()))]
    pub text: Property<String>,
    #[builder(default = Callback::empty())]
    pub clicked: Callback<()>,
}

impl ButtonText {
    pub fn to_view(
        self,
        _style: Option<Box<dyn Style<Self>>>,
        _context: ViewContext,
    ) -> Rc<RefCell<dyn ControlObject>> {
        ui! {
            Button {
                clicked: self.clicked,
                Text { text: self.text }
            }
        }
    }
}

impl ViewModel for MainViewModel {
    fn create_view(self: &Rc<Self>) -> Rc<RefCell<dyn ControlObject>> {
        self.counter2.bind(&self.counter);
        self.counter.bind(&self.counter2);

        ui!(
            Horizontal {
                Margin: Thickness::sides(0.0f32, 5.0f32),
                Text {
                    Margin: Thickness::all(5.0f32),
                    text: (&self.counter, |counter| format!("Counter {}", counter))
                },
                Button {
                    clicked: cb!(self, decrease),
                    Text { text: "Decrease" }
                },
                ButtonText {
                    clicked: cb!(self, increase),
                    text: "Increase"
                },
                Text {
                    Margin: Thickness::all(5.0f32),
                    text: (&self.counter2, |counter| format!("Counter2 {}", counter))
                },
            }
        )
    }
}

#[tokio::main(flavor = "current_thread")]
//#[tokio::main]
async fn main() -> Result<()> {
    LocalSet::new()
        .run_until(async {
            // TODO: tray must be still ported to async
            let app = fui_app::Application::new("Example: tray").await?;

            let menu_items = vec![
                windowing_qt::MenuItem::folder(
                    "File",
                    vec![
                        windowing_qt::MenuItem::simple("Open...", || {}),
                        windowing_qt::MenuItem::simple("Save...", || {}),
                        windowing_qt::MenuItem::folder(
                            "Export",
                            vec![
                                windowing_qt::MenuItem::simple("PDF...", || {}),
                                windowing_qt::MenuItem::simple("PNG...", || {}),
                                windowing_qt::MenuItem::simple("HTML...", || {}),
                            ],
                        ),
                        windowing_qt::MenuItem::Separator,
                        windowing_qt::MenuItem::simple("Exit", || fui_app::Application::exit()),
                    ],
                ),
                windowing_qt::MenuItem::folder(
                    "Help",
                    vec![
                        windowing_qt::MenuItem::simple("Help", || {}),
                        windowing_qt::MenuItem::Separator,
                        windowing_qt::MenuItem::simple("About", || {}),
                    ],
                ),
            ];

            let icon_path = Path::new("assets")
                .join("icon.png")
                .into_os_string()
                .into_string()
                .unwrap();
            let mut file = File::open(icon_path).unwrap();
            let mut icon_data = Vec::new();
            file.read_to_end(&mut icon_data)?;
            let icon = Icon::from_data(&icon_data).unwrap();

            let mut tray = TrayIcon::new().unwrap();
            tray.set_menu(menu_items).unwrap();
            tray.set_icon(&icon).unwrap();
            tray.set_tool_tip("Mądrej Głowie dość po słowie!\nLinia 2\nLinia 3\nLinia 4")
                .unwrap();
            tray.set_visible(true).unwrap();

            tray.show_message("Title", "Hello world", TrayIconType::Custom(&icon), 5000)
                .unwrap();

            let mut window = fui_app::Window::create(
                WindowOptions::new()
                    .with_title("Example: tray")
                    .with_size(800, 600),
            )
            .await?;

            window.set_vm(MainViewModel::new());

            app.run().await?;

            Ok::<(), Error>(())
        })
        .await
}