feat: first cut on M0 - base structure of project
This commit is contained in:
48
crates/bds-ui/src/app.rs
Normal file
48
crates/bds-ui/src/app.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use iced::widget::{column, container, text};
|
||||
use iced::{Element, Length, Subscription, Task};
|
||||
|
||||
use crate::platform::menu;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
MenuEvent(muda::MenuId),
|
||||
Noop,
|
||||
}
|
||||
|
||||
pub struct BdsApp {
|
||||
_menu_bar: muda::Menu,
|
||||
}
|
||||
|
||||
impl BdsApp {
|
||||
pub fn new() -> (Self, Task<Message>) {
|
||||
let menu_bar = menu::build_menu_bar();
|
||||
(Self { _menu_bar: menu_bar }, Task::none())
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::MenuEvent(_id) => {
|
||||
// Menu routing will be expanded in M2
|
||||
Task::none()
|
||||
}
|
||||
Message::Noop => Task::none(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view(&self) -> Element<'_, Message> {
|
||||
let content = column![text("bDS — Blogging Desktop Server").size(24),]
|
||||
.padding(20)
|
||||
.spacing(10);
|
||||
|
||||
container(content)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.center_x(Length::Fill)
|
||||
.center_y(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn subscription(&self) -> Subscription<Message> {
|
||||
menu::menu_subscription()
|
||||
}
|
||||
}
|
||||
4
crates/bds-ui/src/lib.rs
Normal file
4
crates/bds-ui/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
mod app;
|
||||
mod platform;
|
||||
|
||||
pub use app::BdsApp;
|
||||
7
crates/bds-ui/src/main.rs
Normal file
7
crates/bds-ui/src/main.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use bds_ui::BdsApp;
|
||||
|
||||
fn main() -> iced::Result {
|
||||
iced::application("bDS", BdsApp::update, BdsApp::view)
|
||||
.subscription(BdsApp::subscription)
|
||||
.run_with(BdsApp::new)
|
||||
}
|
||||
10
crates/bds-ui/src/platform/macos.rs
Normal file
10
crates/bds-ui/src/platform/macos.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
// macOS lifecycle shim — objc2 hooks for NSApplicationDelegate.
|
||||
//
|
||||
// Handles:
|
||||
// - application:openFile: (Finder open)
|
||||
// - application:openURLs: (URL scheme handling)
|
||||
//
|
||||
// These will be forwarded as Message variants into the Iced event loop
|
||||
// via a channel-based subscription.
|
||||
//
|
||||
// Implementation deferred to M2 when the full message routing is in place.
|
||||
79
crates/bds-ui/src/platform/menu.rs
Normal file
79
crates/bds-ui/src/platform/menu.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
use iced::Subscription;
|
||||
use muda::{Menu, MenuEvent, MenuItem, PredefinedMenuItem, Submenu};
|
||||
|
||||
use crate::app::Message;
|
||||
|
||||
/// Build the native menu bar with standard application menus.
|
||||
pub fn build_menu_bar() -> Menu {
|
||||
let menu = Menu::new();
|
||||
|
||||
// App menu (macOS only shows this as the app name)
|
||||
let app_menu = Submenu::new("bDS", true);
|
||||
let _ = app_menu.append(&PredefinedMenuItem::about(None, None));
|
||||
let _ = app_menu.append(&PredefinedMenuItem::separator());
|
||||
let _ = app_menu.append(&PredefinedMenuItem::services(None));
|
||||
let _ = app_menu.append(&PredefinedMenuItem::separator());
|
||||
let _ = app_menu.append(&PredefinedMenuItem::hide(None));
|
||||
let _ = app_menu.append(&PredefinedMenuItem::hide_others(None));
|
||||
let _ = app_menu.append(&PredefinedMenuItem::show_all(None));
|
||||
let _ = app_menu.append(&PredefinedMenuItem::separator());
|
||||
let _ = app_menu.append(&PredefinedMenuItem::quit(None));
|
||||
|
||||
// File menu
|
||||
let file_menu = Submenu::new("File", true);
|
||||
let _ = file_menu.append(&MenuItem::new("Open Project...", true, None));
|
||||
let _ = file_menu.append(&PredefinedMenuItem::separator());
|
||||
let _ = file_menu.append(&MenuItem::new("Save", true, None));
|
||||
let _ = file_menu.append(&PredefinedMenuItem::close_window(None));
|
||||
|
||||
// Edit menu
|
||||
let edit_menu = Submenu::new("Edit", true);
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::undo(None));
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::redo(None));
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::separator());
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::cut(None));
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::copy(None));
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::paste(None));
|
||||
let _ = edit_menu.append(&PredefinedMenuItem::select_all(None));
|
||||
|
||||
// View menu
|
||||
let view_menu = Submenu::new("View", true);
|
||||
let _ = view_menu.append(&MenuItem::new("Toggle Sidebar", true, None));
|
||||
let _ = view_menu.append(&PredefinedMenuItem::fullscreen(None));
|
||||
|
||||
// Window menu
|
||||
let window_menu = Submenu::new("Window", true);
|
||||
let _ = window_menu.append(&PredefinedMenuItem::minimize(None));
|
||||
let _ = window_menu.append(&PredefinedMenuItem::maximize(None));
|
||||
|
||||
// Help menu
|
||||
let help_menu = Submenu::new("Help", true);
|
||||
let _ = help_menu.append(&MenuItem::new("bDS Help", true, None));
|
||||
|
||||
let _ = menu.append(&app_menu);
|
||||
let _ = menu.append(&file_menu);
|
||||
let _ = menu.append(&edit_menu);
|
||||
let _ = menu.append(&view_menu);
|
||||
let _ = menu.append(&window_menu);
|
||||
let _ = menu.append(&help_menu);
|
||||
|
||||
// Initialize the menu on macOS
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let _ = menu.init_for_nsapp();
|
||||
}
|
||||
|
||||
menu
|
||||
}
|
||||
|
||||
/// Iced subscription that polls muda menu events.
|
||||
pub fn menu_subscription() -> Subscription<Message> {
|
||||
iced::event::listen_with(|_event, _status, _id| {
|
||||
// Check for pending menu events
|
||||
if let Ok(event) = MenuEvent::receiver().try_recv() {
|
||||
Some(Message::MenuEvent(event.id))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
4
crates/bds-ui/src/platform/mod.rs
Normal file
4
crates/bds-ui/src/platform/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod menu;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod macos;
|
||||
Reference in New Issue
Block a user