use iced::widget::{button, center, column, container, stack, text};
use iced::{Element, Length, Task, color};
use std::fmt::Debug;
use activity_manager::{Activity, ActivityHost, ActivityManager, LaunchMode, Route};
pub struct GlobalContext {
pub user_name: String,
}
#[derive(Debug, Clone, PartialEq)]
pub enum AppRoute {
Home,
Detail(String), Dialog, }
impl Route for AppRoute {
fn launch_mode(&self) -> LaunchMode {
match self {
AppRoute::Home => LaunchMode::SingleTask, _ => LaunchMode::Standard,
}
}
fn is_translucent(&self) -> bool {
matches!(self, AppRoute::Dialog) }
}
#[derive(Debug, Clone)]
pub enum AppMessage {
NavigateTo(AppRoute),
Back,
IncrementCounter,
}
pub struct IcedHost;
impl ActivityHost for IcedHost {
type Message = AppMessage;
type Context = GlobalContext;
type Route = AppRoute;
type View<'a> = Element<'a, AppMessage>;
type Task = Task<AppMessage>;
fn empty_task() -> Self::Task {
Task::none()
}
fn batch_tasks(tasks: Vec<Self::Task>) -> Self::Task {
Task::batch(tasks)
}
}
pub struct HomeActivity {
counter: i32,
welcome_text: String,
}
impl Activity<IcedHost> for HomeActivity {
fn route(&self) -> AppRoute {
AppRoute::Home
}
fn on_create(&mut self, _ctx: &mut GlobalContext) -> Task<AppMessage> {
log::info!("HomeActivity created.");
Task::none()
}
fn on_resume(&mut self, _ctx: &mut GlobalContext) -> Task<AppMessage> {
log::debug!("HomeActivity resumed.");
Task::none()
}
fn on_pause(&mut self, _ctx: &mut GlobalContext) -> Task<AppMessage> {
log::debug!("HomeActivity paused.");
Task::none()
}
fn update(&mut self, _ctx: &mut GlobalContext, msg: AppMessage) -> Task<AppMessage> {
if let AppMessage::IncrementCounter = msg {
log::debug!("Incrementing counter in HomeActivity.");
self.counter += 1;
}
Task::none()
}
fn view<'a>(&'a self, ctx: &'a GlobalContext) -> Element<'a, AppMessage> {
let content = column![
text(&self.welcome_text).size(40),
text(format!("当前用户: {}", ctx.user_name)).size(20),
text(format!("页面内计数器: {}", self.counter)).size(50),
button("计数 + 1").on_press(AppMessage::IncrementCounter),
button("跳转到详情页 (Standard)").on_press(AppMessage::NavigateTo(AppRoute::Detail(
"订单 #1024".into()
))),
button("打开弹窗 (Translucent)").on_press(AppMessage::NavigateTo(AppRoute::Dialog)),
]
.spacing(20)
.padding(20);
center(content).into()
}
}
pub struct DetailActivity {
param_id: String,
}
impl Activity<IcedHost> for DetailActivity {
fn route(&self) -> AppRoute {
AppRoute::Detail(self.param_id.clone())
}
fn on_create(&mut self, _ctx: &mut GlobalContext) -> Task<AppMessage> {
log::info!("DetailActivity created with ID: {}", self.param_id);
Task::none()
}
fn on_destroy(&mut self, _ctx: &mut GlobalContext) -> Task<AppMessage> {
log::info!("DetailActivity destroyed (ID: {}).", self.param_id);
Task::none()
}
fn view<'a>(&'a self, _ctx: &'a GlobalContext) -> Element<'a, AppMessage> {
let content = column![
text("详情页面").size(40),
text(format!("接收到的参数: {}", self.param_id)).size(20),
button("返回 (Back)").on_press(AppMessage::Back),
button("回到首页 (SingleTask)").on_press(AppMessage::NavigateTo(AppRoute::Home)),
]
.spacing(20);
container(content)
.center_x(Length::Fill)
.center_y(Length::Fill)
.style(|_theme| container::Style::default().background(color!(0x111111)))
.into()
}
}
pub struct DialogActivity;
impl Activity<IcedHost> for DialogActivity {
fn route(&self) -> AppRoute {
AppRoute::Dialog
}
fn on_create(&mut self, _ctx: &mut GlobalContext) -> Task<AppMessage> {
log::info!("DialogActivity (Translucent) opened.");
Task::none()
}
fn view<'a>(&'a self, _ctx: &'a GlobalContext) -> Element<'a, AppMessage> {
let dialog_box = container(
column![
text("这是一个半透明叠加弹窗!").size(24),
button("关闭弹窗").on_press(AppMessage::Back)
]
.spacing(20),
)
.padding(30)
.style(|_theme| {
container::Style::default()
.background(color!(0x333333))
.border(iced::Border {
radius: 10.0.into(),
..Default::default()
})
});
container(center(dialog_box))
.width(Length::Fill)
.height(Length::Fill)
.style(|_theme| {
container::Style::default().background(iced::Color::from_rgba(0.0, 0.0, 0.0, 0.7))
})
.into()
}
}
fn activity_factory(route: &AppRoute) -> Box<dyn Activity<IcedHost>> {
match route {
AppRoute::Home => Box::new(HomeActivity {
counter: 0,
welcome_text: "欢迎来到 Iced 0.14 路由引擎".into(),
}),
AppRoute::Detail(id) => Box::new(DetailActivity {
param_id: id.clone(),
}),
AppRoute::Dialog => Box::new(DialogActivity),
}
}
struct IcedApp {
manager: ActivityManager<IcedHost>,
context: GlobalContext,
}
impl IcedApp {
fn new() -> (Self, Task<AppMessage>) {
log::info!("Initializing IcedApp and routing to Home.");
let mut manager = ActivityManager::new(activity_factory);
let mut context = GlobalContext {
user_name: "Rust开发者".into(),
};
let task = manager.start_activity(&mut context, AppRoute::Home);
(Self { manager, context }, task)
}
fn update(&mut self, message: AppMessage) -> Task<AppMessage> {
match message {
AppMessage::NavigateTo(route) => {
log::debug!("Global navigation requested: {:?}", route);
self.manager.start_activity(&mut self.context, route)
}
AppMessage::Back => {
log::debug!("Global back navigation requested.");
self.manager.back(&mut self.context).1
}
_ => {
self.manager.update(&mut self.context, message)
}
}
}
fn view(&self) -> Element<'_, AppMessage> {
let views = self.manager.views(&self.context);
stack(views).width(Length::Fill).height(Length::Fill).into()
}
}
pub fn main() -> iced::Result {
env_logger::init();
log::info!("Starting the Iced application...");
iced::application(IcedApp::new, IcedApp::update, IcedApp::view)
.title("Activity Manager Iced Demo")
.run()
}