radarmp/mp/src/app.rs
2024-11-26 12:02:44 +08:00

360 lines
11 KiB
Rust

use crate::file::*;
use crate::menu::{handle_menu, spawn_background};
use crate::widgets::area::TAreaWidgetRefExt;
use crate::widgets::selector::{
ItemKey, ItemValue, SelectorListWidgetRefExt, SelectorWidgetRefExt,
};
use crate::windows_manager::WM;
use crate::{render_task::RenderTasks, PLUGIN_MANAGER, RUNTIME};
use ::log::info;
use element_bridge::TextureBridge;
use makepad_widgets::makepad_micro_serde::*;
use makepad_widgets::*;
use mp_elements::app::DrawList as DW;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Mutex;
live_design! {
import makepad_widgets::base::*;
import makepad_widgets::theme_desktop_dark::*;
import crate::app_ui::MainView;
HELLO = "Hello, World!";
App = {{App}} {
ui: <Root> {
<Window> {
window: {inner_size: vec2(2000, 1024)},
caption_bar = {visible: false, caption_label = {label = {text: "SDXL Surf"}}},
hide_caption_on_fullscreen: true,
draw_bg: {
fn pixel(self) -> vec4 {
return mix(#7,#4,self.pos.y);
}
},
body = {
flow: Overlay
padding: 0.
spacing: 0.
modal = <Modal> {
content: {
height: 100,
width: 150,
show_bg: true,
draw_bg: {
color: #3c3c3c
}
align: {
x: 0.5,
y: 0.5
}
<Label> {
text: "Content in the modal"
}
}
}
notification = <PopupNotification> {
content: {
height: Fit,
width: Fit,
padding: 10,
<RoundedView> {
height: Fit,
width: 240,
padding: 30,
show_bg: true,
draw_bg: {
color: #3c3c3c
radius: 3.0
}
notifacion_title = <Label> {
text: "Notification"
}
notification_message = <Label> {
width: 170
}
close_popup_button = <Button> {
width: Fit,
height: Fit,
margin: {top: -20 },
icon_walk: {width: 10, height: 10}
}
}
}
}
<MainView>{}
}
window_menu = {
main = Main {items: [app, file, window, help]}
app = Sub {name: "MP", items: [about, line, settings, line, quit]}
about = Item {name: "About Makepad Studio", enabled: false}
settings = Item {name: "Settings", enabled: false}
quit = Item {name: "Quit Makepad Studio", key: KeyQ}
file = Sub {name: "File", items: [open_file, open_window]}
open_file = Item {name: "Open File", enabled: true, shift: true, key: KeyO}
open_window = Item {name: "Open Folder", enabled: false, shift: true, key: KeyN}
window = Sub {name: "Window", items: [minimize, zoom, line, all_to_front]}
minimize = Item {name: "Minimize", enabled: false}
zoom = Item {name: "Zoom", enabled: false}
all_to_front = Item {name: "Bring All to Front", enabled: false}
help = Sub {name: "Help", items: [about]}
line = Line,
}
}
}
}
}
#[derive(Default, Clone, Debug)]
pub enum AppAction {
OpenFile,
OpenFolder,
Quit,
Task(TaskAction),
File(FileAction),
Notification {
message: String,
duration: f64,
},
#[default]
None,
}
impl AppAction {
pub fn register_task(id: usize, bridge: Arc<TextureBridge>, draw_list: DW) -> AppAction {
AppAction::Task(TaskAction::Register(id, bridge, draw_list))
}
}
#[derive(Debug, Clone)]
pub enum TaskAction {
Register(usize, Arc<TextureBridge>, DW),
Unregister(),
}
#[derive(Debug, Clone)]
pub enum FileAction {
OpenFile(PathBuf),
OpenFolder(PathBuf),
}
#[derive(Live, LiveHook)]
pub struct App {
#[live]
ui: WidgetRef,
#[rust]
pub render_tasks: Arc<Mutex<RenderTasks>>,
#[rust]
windows_manager: WM,
#[rust]
tex_reciver: ToUIReceiver<Vec<u8>>,
#[rust]
file_manager: FileManager,
#[rust]
timer: Timer,
}
impl LiveRegister for App {
fn live_register(_cx: &mut Cx) {
crate::makepad_widgets::live_design(_cx);
crate::app_ui::live_design(_cx);
crate::widgets::area::live_design(_cx);
crate::widgets::renderer::live_design(_cx);
crate::widgets::background_text::live_design(_cx);
crate::widgets::selector::live_design(_cx);
}
}
#[derive(SerRon, DeRon)]
struct AppStateRon {
slide: usize,
}
impl MatchEvent for App {
// Start UP
fn handle_startup(&mut self, cx: &mut Cx) {
info!("Starting up......");
let ui = self.ui.clone();
let area = ui.tarea(id!(quad));
area.set_windows(self.windows_manager.clone());
// Listening to the render tasks
let render_tasks = self.render_tasks.clone();
RUNTIME.spawn(async move {
let render_task = render_tasks.lock().await;
render_task.render().await;
});
let items = vec![
(
ItemKey {
path: "path".to_string(),
category: "category".to_string(),
description: "description_1".to_string(),
},
vec![
ItemValue {
name: "Item 1".to_string(),
},
ItemValue {
name: "Item 2".to_string(),
},
],
),
(
ItemKey {
path: "path".to_string(),
category: "category".to_string(),
description: "description_1".to_string(),
},
vec![
ItemValue {
name: "Item 1".to_string(),
},
ItemValue {
name: "Item 2".to_string(),
},
],
),
(
ItemKey {
path: "path".to_string(),
category: "category".to_string(),
description: "description_2".to_string(),
},
vec![
ItemValue {
name: "Item 1".to_string(),
},
ItemValue {
name: "Item 2".to_string(),
},
],
),
(
ItemKey {
path: "path".to_string(),
category: "category".to_string(),
description: "description_1".to_string(),
},
vec![
ItemValue {
name: "Item 1".to_string(),
},
ItemValue {
name: "Item 3".to_string(),
},
],
),
];
ui.selector(id!(a)).set_items(cx, items);
}
fn handle_signal(&mut self, cx: &mut Cx) {
self.file_manager.try_deal_file(cx);
}
fn handle_action(&mut self, _cx: &mut Cx, e: &Action) {
let ui = self.ui.clone();
match e.cast() {
AppAction::OpenFile => {
use native_dialog::FileDialog;
info!("Open File Dialog");
let supported_extensions = PLUGIN_MANAGER.supported_extensions();
let file = FileDialog::new()
.add_filter("Supported files", &supported_extensions)
.show_open_single_file()
.unwrap();
if let Some(file) = file {
_cx.action(AppAction::File(FileAction::OpenFile(file)));
}
}
AppAction::OpenFolder => {
info!("Open Folder");
}
AppAction::Quit => {
info!("Quit");
}
AppAction::Task(task) => match task {
TaskAction::Register(bridge_id, bridge, draw_list) => {
info!(
"Register Task for {:?}, draw_list: {:?}",
bridge_id, draw_list
);
let bridge = bridge.render_window();
let sender = self.tex_reciver.sender();
RUNTIME.block_on(async {
let mut render_tasks = self.render_tasks.lock().await;
render_tasks.register_task(sender, bridge_id, bridge, draw_list);
});
}
TaskAction::Unregister() => {
info!("Unregister Task");
}
},
AppAction::File(file) => match file {
FileAction::OpenFile(file) => {
info!("Open File: {:?}", file);
self.file_manager.load_data(&file);
}
FileAction::OpenFolder(folder) => {
info!("Open Folder: {:?}", folder);
}
},
AppAction::Notification { message, duration } => {
let notifacion: PopupNotificationRef = ui.popup_notification(id!(notification));
let timer = _cx.start_timeout(duration);
self.timer = timer;
ui.label(id!(notification_message)).set_text(&message);
notifacion.open(_cx);
}
_ => {}
}
}
}
impl AppMain for App {
fn handle_event(&mut self, cx: &mut Cx, event: &Event) {
self.match_event(cx, event);
self.ui.handle_event(cx, event, &mut Scope::empty());
spawn_background(self, event);
handle_menu(cx, event);
self.timer.is_event(event).map(|_| {
let notifacion: PopupNotificationRef = self.ui.popup_notification(id!(notification));
notifacion.close(cx);
});
}
}
impl App {}
app_main!(App);