#![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")]
async fn main() -> Result<()> {
LocalSet::new()
.run_until(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
}