draw some ui
这个ui框架是真tm难用,但是界面也是真的挺好看,省去了后期美化的过程,就当吃屎了吧
This commit is contained in:
parent
117ae5df3c
commit
21353af9e4
22
Cargo.toml
22
Cargo.toml
@ -7,30 +7,10 @@ edition = "2024"
|
||||
iced = { git = "https://github.com/iced-rs/iced.git", features = [
|
||||
"debug",
|
||||
"advanced",
|
||||
"image",
|
||||
|
||||
] }
|
||||
tokio = { version = "1.45.1", features = ["full"] }
|
||||
iced_aw = { git = "https://github.com/iced-rs/iced_aw.git", features = [
|
||||
"badge",
|
||||
"card",
|
||||
"number_input",
|
||||
"date_picker",
|
||||
"color_picker",
|
||||
"grid",
|
||||
"tab_bar",
|
||||
"tabs",
|
||||
"time_picker",
|
||||
"slide_bar",
|
||||
"wrap",
|
||||
"selection_list",
|
||||
"quad",
|
||||
"context_menu",
|
||||
"spinner",
|
||||
"drop_down",
|
||||
"menu",
|
||||
"sidebar",
|
||||
"labeled_frame",
|
||||
] }
|
||||
reqwest = "0.12.20"
|
||||
tracing-subscriber = { version = "0.3.19", features = [
|
||||
"chrono",
|
||||
|
@ -1,6 +1,8 @@
|
||||
mod ui;
|
||||
mod utils;
|
||||
mod widgets;
|
||||
mod winsparkle;
|
||||
|
||||
fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
ui::main_window::main_window();
|
||||
|
@ -0,0 +1,35 @@
|
||||
use iced::{Length, alignment::Horizontal, widget::Column};
|
||||
|
||||
use crate::ui::main_window::{MainWindowMsg, TabContent};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DbBrowser {}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum DbBrowserMsg {
|
||||
Nothing,
|
||||
}
|
||||
|
||||
impl TabContent for DbBrowser {
|
||||
type TabMessage = DbBrowserMsg;
|
||||
|
||||
fn update(&self, msg: Self::TabMessage) {
|
||||
match msg {
|
||||
DbBrowserMsg::Nothing => {
|
||||
println!("This function not allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn content(&self) -> iced::Element<'_, MainWindowMsg> {
|
||||
let btn = iced::widget::button("DbBrowser")
|
||||
.on_press(MainWindowMsg::DbBrowser(DbBrowserMsg::Nothing));
|
||||
|
||||
Column::new()
|
||||
.align_x(Horizontal::Left)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.push(btn)
|
||||
.into()
|
||||
}
|
||||
}
|
@ -1,52 +1,36 @@
|
||||
use iced::{
|
||||
Alignment, Element,
|
||||
alignment::{Horizontal, Vertical},
|
||||
widget::{Column, Container},
|
||||
};
|
||||
use iced::{Length, alignment::Horizontal, widget::Column};
|
||||
|
||||
use crate::ui::main_window::{MainWindowMsg, TabFrame};
|
||||
#[allow(unused_imports)]
|
||||
use crate::ui::main_window::{MainWindowMsg, TabContent};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct HomePage {}
|
||||
|
||||
impl Default for HomePage {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
}
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub enum HomePageMsg {
|
||||
#[default]
|
||||
Nothing,
|
||||
}
|
||||
impl HomePage {
|
||||
pub fn update(&mut self, msg: HomePageMsg) {
|
||||
|
||||
impl TabContent for HomePage {
|
||||
fn content(&self) -> iced::Element<'_, MainWindowMsg> {
|
||||
let btn = iced::widget::button("HomePage")
|
||||
.on_press(MainWindowMsg::HomePage(HomePageMsg::Nothing));
|
||||
|
||||
Column::new()
|
||||
.align_x(Horizontal::Left)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.push(btn)
|
||||
.into()
|
||||
}
|
||||
|
||||
type TabMessage = HomePageMsg;
|
||||
|
||||
fn update(&self, msg: Self::TabMessage) {
|
||||
match msg {
|
||||
HomePageMsg::Nothing => {
|
||||
println!("HomePage::Message::Nothing");
|
||||
println!("This way ok.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum HomePageMsg {
|
||||
Nothing,
|
||||
}
|
||||
|
||||
impl TabFrame for HomePage {
|
||||
type Message = MainWindowMsg;
|
||||
|
||||
fn title(&self) -> String {
|
||||
"HomePage".to_owned()
|
||||
}
|
||||
|
||||
fn tab_label(&self) -> iced_aw::TabLabel {
|
||||
iced_aw::TabLabel::Text("HomePage".to_owned())
|
||||
}
|
||||
|
||||
fn container(&self) -> iced::Element<'_, Self::Message> {
|
||||
let content: Element<'_, HomePageMsg> = Container::new(
|
||||
Column::new()
|
||||
.align_x(Alignment::Center)
|
||||
.push(iced::widget::button("Homepage Button").on_press(HomePageMsg::Nothing)),
|
||||
)
|
||||
.align_x(Horizontal::Center)
|
||||
.align_y(Vertical::Center)
|
||||
.into();
|
||||
content.map(MainWindowMsg::HomePageMsg)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,34 @@
|
||||
use iced::{
|
||||
Alignment, Element,
|
||||
alignment::{Horizontal, Vertical},
|
||||
widget::{Column, Container},
|
||||
};
|
||||
use iced::{Length, alignment::Horizontal, widget::Column};
|
||||
|
||||
use crate::ui::main_window::{MainWindowMsg, TabFrame};
|
||||
use crate::ui::main_window::{MainWindowMsg, TabContent};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct JlcDownloader {}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum JlcDownloaderMsg {
|
||||
Nothing,
|
||||
}
|
||||
|
||||
impl TabContent for JlcDownloader {
|
||||
type TabMessage = JlcDownloaderMsg;
|
||||
|
||||
fn update(&self, msg: Self::TabMessage) {
|
||||
match msg {
|
||||
JlcDownloaderMsg::Nothing => {
|
||||
println!("JlcDownloaderMsg::Nothing");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn content(&self) -> iced::Element<'_, MainWindowMsg> {
|
||||
let btn = iced::widget::button("JlcDownloader")
|
||||
.on_press(MainWindowMsg::JlcDownloader(JlcDownloaderMsg::Nothing));
|
||||
|
||||
Column::new()
|
||||
.align_x(Horizontal::Left)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.push(btn)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,135 @@
|
||||
use crate::ui::db_browser::DbBrowserMsg;
|
||||
use crate::ui::home_page::HomePageMsg;
|
||||
use crate::ui::jlc_downloader::JlcDownloaderMsg;
|
||||
use crate::ui::part_viewer::PartViewerMsg;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use super::db_browser;
|
||||
#[allow(unused_imports)]
|
||||
use super::home_page;
|
||||
#[allow(unused_imports)]
|
||||
use super::jlc_downloader;
|
||||
#[allow(unused_imports)]
|
||||
use super::part_viewer;
|
||||
use iced::Theme;
|
||||
#[allow(unused_imports)]
|
||||
use iced::widget as w;
|
||||
use iced::widget::button;
|
||||
use iced::widget::button::Status;
|
||||
use iced::widget::button::Style;
|
||||
use iced::widget::row;
|
||||
#[allow(unused_imports)]
|
||||
use iced::{
|
||||
Element, Length,
|
||||
alignment::{Horizontal, Vertical},
|
||||
widget::{Column, Container, Text},
|
||||
widget::{Column, Container, Text, column},
|
||||
};
|
||||
use iced_aw::Tabs;
|
||||
use iced_aw::iced_fonts;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct MainWindow {
|
||||
title: String,
|
||||
theme: iced::Theme,
|
||||
curr_tab: TabId,
|
||||
tab_pos: iced_aw::tabs::TabBarPosition,
|
||||
home_page: home_page::HomePage,
|
||||
tabs: Vec<TabItem>,
|
||||
home_page: crate::ui::home_page::HomePage,
|
||||
jlc_downloader: crate::ui::jlc_downloader::JlcDownloader,
|
||||
db_browser: crate::ui::db_browser::DbBrowser,
|
||||
part_viewer: crate::ui::part_viewer::PartViewer,
|
||||
}
|
||||
impl Default for MainWindow {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
title: Default::default(),
|
||||
title: "HardwareToolkit".into(),
|
||||
theme: Default::default(),
|
||||
curr_tab: Default::default(),
|
||||
tab_pos: iced_aw::tabs::TabBarPosition::Top,
|
||||
home_page: Default::default(),
|
||||
jlc_downloader: Default::default(),
|
||||
tabs: Vec::new(),
|
||||
db_browser: Default::default(),
|
||||
part_viewer: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ICON_BYTES: &[u8] = include_bytes!("./../../fonts/icons.ttf");
|
||||
const ICON: iced::Font = iced::Font::with_name("icons");
|
||||
|
||||
pub fn main_window() {
|
||||
iced::application(MainWindow::default, MainWindow::update, MainWindow::view)
|
||||
let _ = iced::application(MainWindow::default, MainWindow::update, MainWindow::view)
|
||||
.default_font(iced::Font::with_name("微软雅黑"))
|
||||
.title(MainWindow::title)
|
||||
.font(iced_fonts::REQUIRED_FONT_BYTES)
|
||||
.font(ICON_BYTES)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MainWindowMsg {
|
||||
TabSelected(TabId),
|
||||
TabClosed(TabId),
|
||||
ThemeChanged(iced::Theme),
|
||||
TitleChanged(String),
|
||||
HomePageMsg(home_page::HomePageMsg),
|
||||
TabSelected(TabId),
|
||||
HomePage(HomePageMsg),
|
||||
JlcDownloader(JlcDownloaderMsg),
|
||||
DbBrowser(DbBrowserMsg),
|
||||
PartViewer(PartViewerMsg),
|
||||
Nothing,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
enum TabId {
|
||||
pub(crate) enum TabId {
|
||||
#[default]
|
||||
HomePage,
|
||||
JlcDownloader,
|
||||
DbBrowser,
|
||||
PartViewer,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct TabItem {
|
||||
pub id: TabId,
|
||||
content: Box<dyn Fn() -> Element<'static, MainWindowMsg>>,
|
||||
}
|
||||
impl Display for TabId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
TabId::HomePage => "主页",
|
||||
TabId::JlcDownloader => "3D模型下载",
|
||||
TabId::DbBrowser => "数据库浏览",
|
||||
TabId::PartViewer => "元件查看",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
fn btn_active_style(_theme: &Theme, _status: Status) -> Style {
|
||||
let mut s = Style::default();
|
||||
let bgcolor = iced::Color::from_rgba8(30, 200, 200, 1.0);
|
||||
s.background = Some(iced::Background::Color(bgcolor));
|
||||
s
|
||||
}
|
||||
fn btn_deactive_style(_theme: &Theme, _status: Status) -> Style {
|
||||
let mut s = Style::default();
|
||||
let bgcolor = iced::Color::from_rgba8(220, 200, 100, 1.0);
|
||||
s.background = Some(iced::Background::Color(bgcolor));
|
||||
s
|
||||
}
|
||||
impl MainWindow {
|
||||
fn title(&self) -> String {
|
||||
self.title.clone()
|
||||
}
|
||||
fn create_tab_btn(&self, tab: TabId) -> Element<'_, MainWindowMsg> {
|
||||
let bstyle = if self.curr_tab == tab {
|
||||
btn_active_style
|
||||
} else {
|
||||
btn_deactive_style
|
||||
};
|
||||
let txt = format!("{tab}");
|
||||
|
||||
let txt = iced::widget::text(txt);
|
||||
let btn = button(txt).style(bstyle);
|
||||
btn.on_press(MainWindowMsg::TabSelected(tab.clone())).into()
|
||||
}
|
||||
fn update(&mut self, msg: MainWindowMsg) {
|
||||
println!("Process the msg: {msg:?}");
|
||||
match msg {
|
||||
MainWindowMsg::ThemeChanged(theme) => {
|
||||
self.theme = theme;
|
||||
@ -76,44 +141,53 @@ impl MainWindow {
|
||||
println!("Nothing");
|
||||
iced::debug::time("Test".to_owned());
|
||||
}
|
||||
MainWindowMsg::HomePageMsg(message) => {
|
||||
self.home_page.update(message);
|
||||
MainWindowMsg::TabSelected(i) => {
|
||||
self.curr_tab = i;
|
||||
}
|
||||
MainWindowMsg::TabSelected(tab_id) => {
|
||||
self.curr_tab = tab_id;
|
||||
MainWindowMsg::HomePage(msg) => {
|
||||
println!("update HomePage");
|
||||
self.home_page.update(msg);
|
||||
}
|
||||
MainWindowMsg::JlcDownloader(msg) => {
|
||||
self.jlc_downloader.update(msg);
|
||||
}
|
||||
MainWindowMsg::DbBrowser(msg) => {
|
||||
self.db_browser.update(msg);
|
||||
}
|
||||
MainWindowMsg::PartViewer(part_viewer_msg) => {
|
||||
self.part_viewer.update(part_viewer_msg);
|
||||
}
|
||||
MainWindowMsg::TabClosed(tab_id) => todo!(),
|
||||
}
|
||||
}
|
||||
fn view(&self) -> Element<'_, MainWindowMsg> {
|
||||
let t = Tabs::new(MainWindowMsg::TabSelected)
|
||||
.tab_icon_position(iced_aw::tabs::Position::Left)
|
||||
.on_close(MainWindowMsg::TabClosed)
|
||||
.push(
|
||||
TabId::HomePage,
|
||||
self.home_page.tab_label(),
|
||||
self.home_page.view(),
|
||||
)
|
||||
.set_active_tab(&self.curr_tab)
|
||||
.icon_font(ICON)
|
||||
.tab_bar_style(Box::new(iced_aw::style::tab_bar::primary))
|
||||
.tab_bar_position(self.tab_pos.clone());
|
||||
w::button("ClickMe").on_press(MainWindowMsg::Nothing).into()
|
||||
let h = row![
|
||||
self.create_tab_btn(TabId::HomePage),
|
||||
self.create_tab_btn(TabId::JlcDownloader),
|
||||
self.create_tab_btn(TabId::DbBrowser),
|
||||
self.create_tab_btn(TabId::PartViewer)
|
||||
];
|
||||
let v = match self.curr_tab {
|
||||
TabId::HomePage => self.home_page.view(),
|
||||
TabId::JlcDownloader => self.jlc_downloader.view(),
|
||||
TabId::DbBrowser => self.db_browser.view(),
|
||||
TabId::PartViewer => self.part_viewer.view(),
|
||||
};
|
||||
// let content = iced::widget::Button::new("Click").on_press(MainWindowMsg::Nothing);
|
||||
column![h, v].into()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TabFrame {
|
||||
type Message;
|
||||
fn title(&self) -> String;
|
||||
fn tab_label(&self) -> iced_aw::TabLabel;
|
||||
fn container(&self) -> Element<'_, Self::Message>;
|
||||
fn view(&self) -> Element<'_, Self::Message> {
|
||||
w::Container::new(self.container())
|
||||
pub trait TabContent {
|
||||
type TabMessage;
|
||||
fn update(&self, msg: Self::TabMessage);
|
||||
fn view(&self) -> Element<'_, MainWindowMsg> {
|
||||
iced::widget::Container::new(self.content())
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.align_x(Horizontal::Left)
|
||||
.align_y(Vertical::Top)
|
||||
.padding(5)
|
||||
.padding(16.0)
|
||||
.into()
|
||||
}
|
||||
fn content(&self) -> Element<'_, MainWindowMsg>;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
use iced::{Length, alignment::Horizontal, widget::Column};
|
||||
|
||||
use crate::ui::main_window::{MainWindowMsg, TabContent};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PartViewer {}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PartViewerMsg {
|
||||
Nothing,
|
||||
}
|
||||
|
||||
impl TabContent for PartViewer {
|
||||
type TabMessage = PartViewerMsg;
|
||||
|
||||
fn update(&self, msg: Self::TabMessage) {
|
||||
match msg {
|
||||
PartViewerMsg::Nothing => {
|
||||
println!("This function not allowed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn content(&self) -> iced::Element<'_, MainWindowMsg> {
|
||||
let btn = iced::widget::button("PartViewer")
|
||||
.on_press(MainWindowMsg::PartViewer(PartViewerMsg::Nothing));
|
||||
|
||||
Column::new()
|
||||
.align_x(Horizontal::Left)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.push(btn)
|
||||
.into()
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
pub mod tab_header;
|
4
src/widgets/tab_header.rs
Normal file
4
src/widgets/tab_header.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[allow(unused_imports)]
|
||||
use iced::advanced::renderer;
|
||||
#[allow(unused_imports)]
|
||||
use iced::advanced::widget::{self, Widget};
|
Loading…
x
Reference in New Issue
Block a user