diff --git a/.gitignore b/.gitignore
index d01bd1a..0b58c0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,4 +18,7 @@ Cargo.lock
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
\ No newline at end of file
+#.idea/
+
+# Test binaries
+*.exe
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index c49c225..d3e5213 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,4 +9,6 @@ repository = "https://github.com/Administroot/FreeEta"
[dependencies]
iced = {version = "0.13.1", features = ["image", "svg", "tokio", "advanced"] }
-tokio = {version = "1.43.0", features = ["time", "full"]}
\ No newline at end of file
+tokio = {version = "1.43.0", features = ["time", "full"]}
+serde = "1.0"
+serde_yml = "0.0.11"
\ No newline at end of file
diff --git a/README.md b/README.md
index b9b7d61..5ae42d9 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# FreeEta
+#  FreeEta
[](https://crates.io/crates/FreeEta)
-[](https://github.com/Administroot/FreeEta/blob/main/LICENSE)
+
[](https://github.com/Administroot/FreeEta/releases/latest)
-[](https://github.com/administroot/FreeEta/actions)
+
[](https://github.com/iced-rs/iced)
A fast, elegant & free ETA analysis utility powered by ๐ฆ Rust, ๐ง iced.
@@ -14,7 +14,9 @@ A fast, elegant & free ETA analysis utility powered by ๐ฆ Rust, ๐ง iced.
-> โโโMain functions are not yet!
+> [!danger]+
+> Freeeta is on flight๐ซ
+>
## Installation
@@ -22,10 +24,13 @@ A fast, elegant & free ETA analysis utility powered by ๐ฆ Rust, ๐ง iced.
-Support windows / linux / MacOS! Or use `cargo` to try it out:
+Support windows / linux / MacOS!
+
+Or use `cargo` to try it out:
```bash
cargo install --git https://github.com/administroot/FreeEta.git
+```
## Why "FreeEta"?
diff --git a/config.yml b/config.yml
new file mode 100644
index 0000000..01e213f
--- /dev/null
+++ b/config.yml
@@ -0,0 +1,3 @@
+name: FreeEta
+lang: zh-cn
+theme: Light
diff --git a/src/freeeta_buttons.rs b/src/freeeta_buttons.rs
new file mode 100644
index 0000000..a67ea5d
--- /dev/null
+++ b/src/freeeta_buttons.rs
@@ -0,0 +1,67 @@
+use crate::freeeta_styles;
+use crate::main_menu::MainMenuMessage;
+use iced::widget::text::LineHeight;
+use iced::widget::tooltip::Position;
+use iced::widget::{button, Text, Tooltip};
+use iced::{Alignment, Color, Font, Pixels, Theme};
+
+#[allow(dead_code)]
+/// Button 'ร'
+pub fn button_hide<'a>(
+ message: MainMenuMessage,
+ font: Font,
+) -> Tooltip<'a, MainMenuMessage, Theme> {
+ Tooltip::new(
+ button(
+ Text::new("ร")
+ .font(font)
+ .align_y(Alignment::Center)
+ .align_x(Alignment::Center)
+ .size(15)
+ .line_height(LineHeight::Relative(1.0)),
+ )
+ .padding(2)
+ .height(20)
+ .width(20)
+ .on_press(message),
+ Text::new("Cancel").font(font),
+ Position::Right,
+ )
+ .gap(5)
+}
+
+/// Bookmark
+pub fn bookmark<'a>(
+ message: MainMenuMessage,
+ font: Font,
+ inner_text: &str,
+ color: Color,
+ is_actived: bool,
+) -> Tooltip<'a, MainMenuMessage, Theme> {
+ let mut button = button(
+ Text::new(inner_text.to_string())
+ .font(font)
+ .align_y(Alignment::Center)
+ .align_x(Alignment::Center)
+ .line_height(LineHeight::Relative(1.0)),
+ )
+ .style(move |theme, status| freeeta_styles::bookmark_style(theme, status, color, is_actived))
+ .height(40)
+ .on_press(message);
+
+ // Lengthen and hignlight the button when activated
+ button = match is_actived {
+ true => button.width(80),
+ false => button.width(60),
+ };
+
+ let bookmark = Tooltip::new(
+ button,
+ Text::new("Press to active / deactive")
+ .font(font)
+ .size(Pixels { 0: 15f32 }),
+ Position::Right,
+ )
+ .gap(5);
+ return bookmark;
+}
diff --git a/src/freeeta_picklists.rs b/src/freeeta_picklists.rs
new file mode 100644
index 0000000..796a2e9
--- /dev/null
+++ b/src/freeeta_picklists.rs
@@ -0,0 +1,28 @@
+use std::borrow::Borrow;
+
+use iced::widget::pick_list;
+use iced::{
+ widget::{text::Shaping, PickList},
+ Length,
+};
+
+/// Picklist to select functions.
+pub fn functional_picklist<'a, T, L, V, Message, Theme, Renderer>(
+ options: L,
+ selected: Option,
+ on_selected: impl Fn(T) -> Message + 'a,
+ placeholder: &str,
+) -> PickList<'a, T, L, V, Message, Theme, Renderer>
+where
+ T: ToString + PartialEq + Clone + 'a,
+ L: Borrow<[T]> + 'a,
+ V: Borrow + 'a,
+ Message: Clone,
+ Theme: iced::widget::pick_list::Catalog + iced::widget::overlay::menu::Catalog,
+ Renderer: iced::advanced::text::Renderer,
+{
+ pick_list::<'a, T, L, V, Message, Theme, Renderer>(options, selected, on_selected)
+ .width(Length::Shrink)
+ .placeholder(placeholder)
+ .text_shaping(Shaping::Advanced)
+}
diff --git a/src/freeeta_styles.rs b/src/freeeta_styles.rs
index 97cebdd..f4c9ee9 100644
--- a/src/freeeta_styles.rs
+++ b/src/freeeta_styles.rs
@@ -1,27 +1,11 @@
-use iced::{border::Radius, widget::pick_list, Background, Border, Color, Theme};
-
-// pub fn radio_selected(_theme: &Theme, _status: radio::Status) -> radio::Style {
-// radio::Style {
-// text_color: Some(Color::from_rgb(0., 0., 1.)),
-// background: Background::Color(Color::from_rgb(1., 1., 1.)),
-// dot_color: Color::from_rgb(0., 0., 1.),
-// border_width: 1.0,
-// border_color: Color::from_rgb(0., 0., 1.),
-// }
-// }
-
-// pub fn radio_unselected(_theme: &Theme, _status: radio::Status) -> radio::Style {
-// radio::Style {
-// text_color: Some(Color::from_rgb(0.5, 0.5, 0.5)),
-// background: Background::Color(Color::from_rgb(1., 1., 1.)),
-// dot_color: Color::from_rgb(0., 0., 1.),
-// border_width: 1.0,
-// border_color: Color::from_rgb(0., 0., 1.),
-// }
-// }
+use iced::{
+ border::Radius,
+ widget::{button, pick_list, text},
+ Background, Border, Color, Theme,
+};
// TODO: Read Theme from const in the future.
-pub fn pick_list_unselected(_theme: &Theme, _status: pick_list::Status) -> pick_list::Style {
+pub fn functional_picklist_style(_theme: &Theme, _status: pick_list::Status) -> pick_list::Style {
pick_list::Style {
text_color: Color::from_rgb(0.09, 0.02, 0.08),
placeholder_color: Color::from_rgb(0.09, 0.02, 0.08),
@@ -39,3 +23,75 @@ pub fn pick_list_unselected(_theme: &Theme, _status: pick_list::Status) -> pick_
},
}
}
+
+pub fn bottomline_text_unselected(_theme: &Theme) -> text::Style {
+ text::Style {
+ color: Some(Color::from_rgb(0.35, 0.35, 0.34)),
+ }
+}
+
+/// Returns the average of two colors; color intensity is fixed to 100%
+fn mix_colors(color_1: Color, color_2: Color) -> Color {
+ Color {
+ r: (color_1.r + color_2.r) / 2.0,
+ g: (color_1.g + color_2.g) / 2.0,
+ b: (color_1.b + color_2.b) / 2.0,
+ a: 1.0,
+ }
+}
+
+/// Half transparency of the given color.
+fn half_transparency(color: Color) -> Color {
+ Color {
+ r: color.r,
+ g: color.g,
+ b: color.b,
+ a: color.a / 2.0,
+ }
+}
+
+pub fn bookmark_style(
+ _theme: &Theme,
+ status: button::Status,
+ color: Color,
+ is_actived: bool,
+) -> button::Style {
+ let text_color = Color::BLACK;
+ let border = Border {
+ color,
+ width: 2.,
+ radius: Radius {
+ top_left: 0.,
+ top_right: 5.,
+ bottom_right: 5.,
+ bottom_left: 0.,
+ },
+ };
+
+ match (status, is_actived) {
+ (button::Status::Active, true) => button::Style {
+ background: Some(Background::Color(color)),
+ text_color,
+ border,
+ ..Default::default()
+ },
+ (button::Status::Hovered, _) => button::Style {
+ background: Some(Background::Color(mix_colors(Color::WHITE, color))),
+ text_color,
+ border,
+ ..Default::default()
+ },
+ (button::Status::Pressed, _) => button::Style {
+ background: Some(Background::Color(color)),
+ text_color,
+ border,
+ ..Default::default()
+ },
+ (_, _) => button::Style {
+ background: Some(Background::Color(half_transparency(color))),
+ text_color,
+ border,
+ ..Default::default()
+ },
+ }
+}
\ No newline at end of file
diff --git a/src/freeeta_yml.rs b/src/freeeta_yml.rs
new file mode 100644
index 0000000..65fc34e
--- /dev/null
+++ b/src/freeeta_yml.rs
@@ -0,0 +1,34 @@
+use serde::{Deserialize, Serialize};
+use std::fs::{self, File};
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+pub struct FreeEtaConfig {
+ /// Software name: typically "FreeEta"
+ name: String,
+ /// Language: ["zh-cn", "en-us"]
+ lang: String,
+ /// Theme: Default "Light"; Others see [iced::theme::Theme](https://docs.rs/iced/0.13.1/iced/theme/enum.Theme.html)
+ theme: String,
+}
+
+/// Read FreeEta config from ./
+pub fn read_freeeta_config() -> Result {
+ let path = "config.yml";
+ if !fs::exists(path).unwrap() {
+ // If config doesn't exist, create a default config.
+ File::create(path).unwrap();
+ let default_config = FreeEtaConfig {
+ name: "FreeEta".to_string(),
+ lang: "zh-cn".to_string(),
+ theme: "Light".to_string(),
+ };
+ let yaml = serde_yml::to_string(&default_config)?;
+ fs::write(path, yaml).expect("Cannot write config.yml");
+ return Ok(default_config);
+ } else {
+ // If config exists, read from it.
+ let contents = fs::read_to_string(path).expect("Cannot read config.yml");
+ let deserialized_config: FreeEtaConfig = serde_yml::from_str(&contents)?;
+ return Ok(deserialized_config);
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index f7af803..a88bc23 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,13 +1,22 @@
+mod freeeta_buttons;
+mod freeeta_picklists;
mod freeeta_styles;
+mod freeeta_yml;
mod main_menu;
+mod pages;
use iced;
fn main() -> iced::Result {
+ let freeeta_yml = freeeta_yml::read_freeeta_config().expect("[ERROR] CONFIG ERROR");
+ // TODO: Deal with the config struct.
+ println!("{:?}", freeeta_yml);
iced::application(
"FreeEta",
main_menu::FreeEta::update,
main_menu::FreeEta::view,
)
+ .theme(main_menu::FreeEta::theme)
+ .subscription(main_menu::FreeEta::subscription)
.run()
}
diff --git a/src/main_menu.rs b/src/main_menu.rs
index c47155e..183cf65 100644
--- a/src/main_menu.rs
+++ b/src/main_menu.rs
@@ -1,12 +1,27 @@
+use iced::widget::{svg, text};
use iced::{
- widget::{column, container, horizontal_space, pick_list, row, svg, svg::Handle},
- ContentFit, Element, Task,
+ alignment,
+ event::{self, Status},
+ mouse::Event::CursorMoved,
+ touch::Event::FingerMoved,
+ widget::{
+ column, container, horizontal_rule, horizontal_space, row, svg::Handle, vertical_space,
+ },
+ Color, ContentFit, Element, Event, Font, Point, Subscription, Task,
};
-use crate::freeeta_styles;
+use crate::{freeeta_buttons, freeeta_picklists::functional_picklist, freeeta_styles};
+use crate::pages::Pages;
pub struct FreeEta {
+ // TODO: Actually, I don't need this member.
file_picklist: Option,
+ mouse_point: Point,
+ view_bookmark_status: bool,
+ eta_bookmark_status: bool,
+ developer_bookmark_status: bool,
+ export_bookmark_status: bool,
+ page: Pages,
}
impl Default for FreeEta {
@@ -17,7 +32,16 @@ impl Default for FreeEta {
#[derive(Debug, Clone)]
pub enum MainMenuMessage {
- DoNothing,
+ FilePicklistMsg(String),
+ GraphicsPicklistMsg(String),
+ AnalysisPicklistMsg(String),
+ SettingsPicklistMsg(String),
+ HelpPicklistMsg(String),
+ PointUpdated(Point),
+ ViewBookmarkMsg,
+ EtaBookmarkMsg,
+ DeveloperBookmarkMsg,
+ ExportBookmarkMsg,
}
impl FreeEta {
@@ -25,72 +49,254 @@ impl FreeEta {
(
Self {
file_picklist: None,
+ mouse_point: Point::ORIGIN,
+ view_bookmark_status: false,
+ eta_bookmark_status: false,
+ developer_bookmark_status: false,
+ export_bookmark_status: false,
+ page: Pages::MainMenuPage,
},
Task::none(),
)
}
- pub fn update(&mut self, _message: MainMenuMessage) -> Task {
+ pub fn update(&mut self, message: MainMenuMessage) -> Task {
+ match message {
+ MainMenuMessage::FilePicklistMsg(s) => {
+ // TODO: Divide different sections
+ self.file_picklist = Some(s);
+ }
+ MainMenuMessage::PointUpdated(p) => {
+ self.mouse_point = p;
+ }
+ MainMenuMessage::GraphicsPicklistMsg(s) => {
+ // TODO: Divide different sections
+ self.file_picklist = Some(s);
+ }
+ MainMenuMessage::AnalysisPicklistMsg(s) => {
+ // TODO: Divide different sections
+ self.file_picklist = Some(s);
+ }
+ MainMenuMessage::SettingsPicklistMsg(s) => {
+ // TODO: Divide different sections
+ self.file_picklist = Some(s);
+ }
+ MainMenuMessage::HelpPicklistMsg(s) => {
+ // TODO: Divide different sections
+ self.file_picklist = Some(s);
+ }
+ MainMenuMessage::ViewBookmarkMsg => {
+ self.view_bookmark_status = !self.view_bookmark_status;
+ if self.view_bookmark_status {
+ // Close other bookmarks
+ self.eta_bookmark_status = false;
+ self.developer_bookmark_status = false;
+ self.export_bookmark_status = false;
+ // Open corresponding page
+ self.page = Pages::InterfacePage;
+ }
+ }
+ MainMenuMessage::EtaBookmarkMsg => {
+ self.eta_bookmark_status = !self.eta_bookmark_status;
+ if self.eta_bookmark_status {
+ // Close other bookmarks
+ self.view_bookmark_status = false;
+ self.developer_bookmark_status = false;
+ self.export_bookmark_status = false;
+ // Open corresponding page
+ self.page = Pages::ChartPage;
+ }
+ }
+ MainMenuMessage::DeveloperBookmarkMsg => {
+ self.developer_bookmark_status = !self.developer_bookmark_status;
+ if self.developer_bookmark_status {
+ // Close other bookmarks
+ self.view_bookmark_status = false;
+ self.eta_bookmark_status = false;
+ self.export_bookmark_status = false;
+ // Open corresponding page
+ self.page = Pages::DeveloperPage;
+ }
+ }
+ MainMenuMessage::ExportBookmarkMsg => {
+ self.export_bookmark_status = !self.export_bookmark_status;
+ if self.export_bookmark_status {
+ // Close other bookmarks
+ self.view_bookmark_status = false;
+ self.eta_bookmark_status = false;
+ self.developer_bookmark_status = false;
+ // Open corresponding page
+ self.page = Pages::ExportPage;
+ }
+ }
+ }
Task::none()
}
pub fn view(&self) -> Element {
+ let file_picklist = functional_picklist(
+ [
+ "๐ New.. ",
+ "๐ Open..",
+ "๐ Open Recent",
+ "๐พ Save",
+ "๐ค Export",
+ ]
+ .map(|s| s.to_string())
+ .to_vec(),
+ self.file_picklist.clone(),
+ |s| MainMenuMessage::FilePicklistMsg(s),
+ "๐ File",
+ )
+ .style(freeeta_styles::functional_picklist_style);
+ let graphics_picklist = functional_picklist(
+ // FIXME: Better use container[svg/png]
+ ["โฝ Pop", "๐ Valve", "โ Add more..."]
+ .map(|s| s.to_string())
+ .to_vec(),
+ self.file_picklist.clone(),
+ |s| MainMenuMessage::GraphicsPicklistMsg(s),
+ "๐ Graphics",
+ )
+ .style(freeeta_styles::functional_picklist_style);
+ let analysis_picklist = functional_picklist(
+ ["๐ฒ Draw ETA Tree", "๐ Calculate Success & Failure Rates"]
+ .map(|s| s.to_string())
+ .to_vec(),
+ self.file_picklist.clone(),
+ |s| MainMenuMessage::AnalysisPicklistMsg(s),
+ "๐งญ Analysis",
+ )
+ .style(freeeta_styles::functional_picklist_style);
+ let settings_picklist = functional_picklist(
+ ["๐ฎ Themes", "๐ฃ๏ธ Languages"]
+ .map(|s| s.to_string())
+ .to_vec(),
+ self.file_picklist.clone(),
+ |s| MainMenuMessage::SettingsPicklistMsg(s),
+ "โ๏ธ Settings",
+ )
+ .style(freeeta_styles::functional_picklist_style);
+ let help_picklist = functional_picklist(
+ ["๐ FreeEta Handbook", "๐ About FreeEta", "๐ง About ICED"]
+ .map(|s| s.to_string())
+ .to_vec(),
+ self.file_picklist.clone(),
+ |s| MainMenuMessage::HelpPicklistMsg(s),
+ "๐ค Help",
+ )
+ .style(freeeta_styles::functional_picklist_style);
+
+ let view_bookmark = freeeta_buttons::bookmark(
+ MainMenuMessage::ViewBookmarkMsg,
+ Font::default(),
+ "View",
+ Color::from_rgb(0.92, 0.21, 0.36),
+ self.view_bookmark_status,
+ );
+ let eta_bookmark = freeeta_buttons::bookmark(
+ MainMenuMessage::EtaBookmarkMsg,
+ Font::default(),
+ "ETA",
+ Color::from_rgb(0., 0.64, 0.51),
+ self.eta_bookmark_status,
+ );
+ let developer_bookmark = freeeta_buttons::bookmark(
+ MainMenuMessage::DeveloperBookmarkMsg,
+ Font::default(),
+ "Developer",
+ Color::from_rgb(0.88, 0.6, 0.71),
+ self.developer_bookmark_status,
+ );
+ let export_bookmark = freeeta_buttons::bookmark(
+ MainMenuMessage::ExportBookmarkMsg,
+ Font::default(),
+ "Export",
+ Color::from_rgb(0.95, 0.6, 0.),
+ self.export_bookmark_status,
+ );
+
+ let logo = container(
+ svg(Handle::from_path("static/svg/logo.svg"))
+ .width(32.)
+ .height(32.)
+ .content_fit(ContentFit::ScaleDown),
+ )
+ .padding(0u16)
+ .style(container::rounded_box);
+
+ let mouse_position =
+ text(format!("{:?}", self.mouse_point)).color(Color::from_rgb(0.96, 0.31, 0.64));
+ let admonition = text(
+ "| CopyrightยฉShanghai Justlinking Safety Technology co.,ltd. \
+ Administroot ",
+ )
+ .style(freeeta_styles::bottomline_text_unselected)
+ .align_x(alignment::Horizontal::Center);
+
+ let screen = match self.page {
+ Pages::MainMenuPage => self.main_menu_page(),
+ Pages::InterfacePage => self.interface_page(),
+ Pages::ChartPage => self.chart_page(),
+ Pages::DeveloperPage => self.developer_page(),
+ Pages::ExportPage => self.export_page(),
+ };
+
column!(
- // Funtion row
+ // Functional row
row![
- // File
- pick_list(
- ["Other choices 1", "Other choices 2"]
- .map(|s| s.to_string())
- .to_vec(),
- self.file_picklist.clone(),
- |_| MainMenuMessage::DoNothing,
- )
- .placeholder("File")
- .style(freeeta_styles::pick_list_unselected),
- // Graphics
- pick_list(
- ["Other choices 1", "Other choices 2"]
- .map(|s| s.to_string())
- .to_vec(),
- self.file_picklist.clone(),
- |_| MainMenuMessage::DoNothing,
- )
- .placeholder("Graphics")
- .style(freeeta_styles::pick_list_unselected),
- // Tools
- pick_list(
- ["Other choices 1", "Other choices 2"]
- .map(|s| s.to_string())
- .to_vec(),
- self.file_picklist.clone(),
- |_| MainMenuMessage::DoNothing,
- )
- .placeholder("Tools")
- .style(freeeta_styles::pick_list_unselected),
- // Helps
- pick_list(
- ["Other choices 1", "Other choices 2"]
- .map(|s| s.to_string())
- .to_vec(),
- self.file_picklist.clone(),
- |_| MainMenuMessage::DoNothing,
- )
- .placeholder("Helps")
- .style(freeeta_styles::pick_list_unselected),
- // Space[ ]
+ file_picklist,
+ graphics_picklist,
+ analysis_picklist,
+ settings_picklist,
+ help_picklist,
horizontal_space(),
- // FreeEta logo
- container(
- svg(Handle::from_path("assets/logo.svg"))
- .width(32.)
- .height(32.)
- .content_fit(ContentFit::ScaleDown)
- )
- .padding(0u16)
- .style(container::rounded_box)
- ]
+ logo,
+ ],
+ horizontal_rule(0),
+ vertical_space(),
+ // Body
+ container(
+ row![
+ // Bookmarks
+ column![
+ view_bookmark,
+ eta_bookmark,
+ developer_bookmark,
+ export_bookmark,
+ ]
+ .spacing(10.)
+ .align_x(alignment::Horizontal::Left),
+
+ // Canvas
+ screen
+ ].spacing(10)
+ )
+ .align_x(alignment::Horizontal::Left),
+ vertical_space(),
+ // Bottom row
+ horizontal_rule(0),
+ row![mouse_position, admonition].align_y(alignment::Vertical::Bottom)
)
.into()
}
+
+ pub fn theme(&self) -> iced::Theme {
+ // TODO: Read from config struct var.
+ iced::Theme::Light
+ }
+
+ pub fn subscription(&self) -> Subscription {
+ event::listen_with(|event, status, _window| {
+ match (event, status) {
+ // Using mouse
+ (Event::Mouse(CursorMoved { position }), Status::Ignored)
+ // Or using touchboard
+ | (Event::Touch(FingerMoved {position, ..}), Status::Ignored) => {
+ Some(MainMenuMessage::PointUpdated(position))
+ }
+ _ => None
+ }
+ })
+ }
}
diff --git a/src/pages.rs b/src/pages.rs
new file mode 100644
index 0000000..ac9afa4
--- /dev/null
+++ b/src/pages.rs
@@ -0,0 +1,45 @@
+use iced::{alignment, widget::{container, text, Container}};
+
+use crate::main_menu::{FreeEta, MainMenuMessage};
+
+#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Pages {
+ #[default]
+ MainMenuPage,
+ InterfacePage,
+ ChartPage,
+ DeveloperPage,
+ ExportPage,
+}
+
+impl FreeEta {
+ pub fn main_menu_page(&self) -> Container{
+ container(
+ text("Hello, FreeEta!").size(80),
+ ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into()
+ }
+
+ pub fn interface_page(&self) -> Container{
+ container(
+ text("Hello, interface page!").size(70),
+ ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into()
+ }
+
+ pub fn chart_page(&self) -> Container{
+ container(
+ text("Hello, chart page!").size(65),
+ ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into()
+ }
+
+ pub fn developer_page(&self) -> Container{
+ container(
+ text("Hello, developer page!").size(60),
+ ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into()
+ }
+
+ pub fn export_page(&self) -> Container{
+ container(
+ text("Hello, export page!").size(50),
+ ).align_x(alignment::Horizontal::Center).align_y(alignment::Vertical::Center).into()
+ }
+}
\ No newline at end of file
diff --git a/static/png/Bookmark_View.png b/static/png/Bookmark_View.png
new file mode 100644
index 0000000..8114e52
Binary files /dev/null and b/static/png/Bookmark_View.png differ
diff --git a/assets/calculator.svg b/static/svg/calculator.svg
similarity index 100%
rename from assets/calculator.svg
rename to static/svg/calculator.svg
diff --git a/assets/code-slash.svg b/static/svg/code-slash.svg
similarity index 100%
rename from assets/code-slash.svg
rename to static/svg/code-slash.svg
diff --git a/assets/file-add.svg b/static/svg/file-add.svg
similarity index 100%
rename from assets/file-add.svg
rename to static/svg/file-add.svg
diff --git a/static/svg/get_it_on_github.svg b/static/svg/get_it_on_github.svg
new file mode 100644
index 0000000..5398824
--- /dev/null
+++ b/static/svg/get_it_on_github.svg
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+ Andrew Nayenko
+
+
+
+
+ https://f-droid.org
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GET IT ON
+ GitHub
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/logo.svg b/static/svg/logo.svg
similarity index 100%
rename from assets/logo.svg
rename to static/svg/logo.svg
diff --git a/assets/menu-boxed.svg b/static/svg/menu-boxed.svg
similarity index 100%
rename from assets/menu-boxed.svg
rename to static/svg/menu-boxed.svg
diff --git a/assets/more-r.svg b/static/svg/more-r.svg
similarity index 100%
rename from assets/more-r.svg
rename to static/svg/more-r.svg
diff --git a/assets/shape-hexagon.svg b/static/svg/shape-hexagon.svg
similarity index 100%
rename from assets/shape-hexagon.svg
rename to static/svg/shape-hexagon.svg
diff --git a/assets/software-download.svg b/static/svg/software-download.svg
similarity index 100%
rename from assets/software-download.svg
rename to static/svg/software-download.svg
diff --git a/assets/software-upload.svg b/static/svg/software-upload.svg
similarity index 100%
rename from assets/software-upload.svg
rename to static/svg/software-upload.svg
diff --git a/assets/view-comfortable.svg b/static/svg/view-comfortable.svg
similarity index 100%
rename from assets/view-comfortable.svg
rename to static/svg/view-comfortable.svg