summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main.rs (renamed from iced_builder/src/main.rs)124
1 files changed, 80 insertions, 44 deletions
diff --git a/iced_builder/src/main.rs b/src/main.rs
index a041c6f..5b95b94 100644
--- a/iced_builder/src/main.rs
+++ b/src/main.rs
@@ -1,26 +1,47 @@
+#![feature(test)]
+mod config;
+mod dialogs;
+mod environment;
+mod error;
+mod icon;
+mod panes;
+mod theme;
+mod types;
+mod widget;
+
use std::path::PathBuf;
+use config::Config;
+use dialogs::{error_dialog, unsaved_changes_dialog, warning_dialog};
+use error::Error;
use iced::advanced::widget::Id;
use iced::widget::pane_grid::{self, Pane, PaneGrid};
use iced::widget::{container, pick_list, row, text_editor, Column};
use iced::{clipboard, keyboard, Alignment, Element, Length, Task, Theme};
-use iced_anim::{Animation, Spring};
-use iced_builder::dialogs::{error_dialog, unsaved_changes_dialog};
-use iced_builder::icon;
-use iced_builder::panes::{code_view, designer_view, element_list};
-use iced_builder::types::{
- Action, DesignerPage, ElementName, Message, Project,
-};
-use rfd::MessageDialogResult;
+use iced_anim::transition::Easing;
+use iced_anim::{Animated, Animation};
+use panes::{code_view, designer_view, element_list};
+use tokio::runtime;
+use types::{Action, DesignerPage, ElementName, Message, Project};
+
+//pub(crate) type Result<T> = core::result::Result<T, Error>;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let config_load = {
+ let rt = runtime::Builder::new_current_thread()
+ .enable_all()
+ .build()?;
-const THEMES: &'static [Theme] = &[Theme::SolarizedDark, Theme::SolarizedLight];
+ rt.block_on(Config::load())
+ };
-fn main() -> iced::Result {
iced::application(App::title, App::update, App::view)
.font(icon::FONT)
.theme(|state| state.theme.value().clone())
.subscription(App::subscription)
- .run_with(App::new)
+ .run_with(move || App::new(config_load))?;
+
+ Ok(())
}
struct App {
@@ -28,7 +49,8 @@ struct App {
is_loading: bool,
project_path: Option<PathBuf>,
project: Project,
- theme: Spring<Theme>,
+ config: Config,
+ theme: Animated<Theme>,
pane_state: pane_grid::State<Panes>,
focus: Option<Pane>,
designer_page: DesignerPage,
@@ -43,7 +65,7 @@ enum Panes {
}
impl App {
- fn new() -> (Self, Task<Message>) {
+ fn new(config_load: Result<Config, Error>) -> (Self, Task<Message>) {
let state = pane_grid::State::with_configuration(
pane_grid::Configuration::Split {
axis: pane_grid::Axis::Vertical,
@@ -52,25 +74,46 @@ impl App {
b: Box::new(pane_grid::Configuration::Pane(Panes::ElementList)),
},
);
+
+ let config = config_load.unwrap_or_default();
+ let theme = config.selected_theme();
+
+ let mut task = Task::none();
+
+ if let Some(path) = config.last_project.clone() {
+ if path.exists() && path.is_file() {
+ task = Task::perform(
+ Project::from_path(path, config.clone()),
+ Message::FileOpened,
+ );
+ } else {
+ warning_dialog(format!(
+ "The file {} does not exist, or isn't a file.",
+ path.to_string_lossy()
+ ));
+ }
+ }
+
(
Self {
is_dirty: false,
is_loading: false,
project_path: None,
project: Project::new(),
- theme: Spring::new(Theme::SolarizedDark),
+ config,
+ theme: Animated::new(theme, Easing::EASE_IN),
pane_state: state,
focus: None,
designer_page: DesignerPage::DesignerView,
element_list: ElementName::ALL,
editor_content: text_editor::Content::new(),
},
- Task::none(),
+ task,
)
}
fn title(&self) -> String {
- let saved_state = if !self.is_dirty { "" } else { " *" };
+ let saved_state = if self.is_dirty { " *" } else { "" };
let project_name = match &self.project.title {
Some(n) => {
@@ -83,7 +126,7 @@ impl App {
}
)
}
- None => "".to_owned(),
+ None => String::new(),
};
format!("iced Builder{project_name}{saved_state}")
@@ -104,7 +147,7 @@ impl App {
}
}
Message::RefreshEditorContent => {
- match self.project.clone().app_code() {
+ match self.project.app_code(&self.config) {
Ok(code) => {
self.editor_content =
text_editor::Content::with_text(&code);
@@ -119,23 +162,19 @@ impl App {
None,
None,
)
- .into()
}
Message::HandleNew(name, zones) => {
let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect();
- if ids.len() > 0 {
- let action = Action::new(
- ids,
- &mut self.project.element_tree.clone(),
- None,
- );
+ if !ids.is_empty() {
+ let eltree_clone = self.project.element_tree.clone();
+ let action = Action::new(&ids, &eltree_clone, None);
let result = name.handle_action(
self.project.element_tree.as_mut(),
action,
);
match result {
Ok(Some(ref element)) => {
- self.project.element_tree = Some(element.clone())
+ self.project.element_tree = Some(element.clone());
}
Err(error) => error_dialog(error.to_string()),
_ => {}
@@ -152,14 +191,14 @@ impl App {
None,
None,
)
- .into()
}
Message::HandleMove(element, zones) => {
let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect();
- if ids.len() > 0 {
+ if !ids.is_empty() {
+ let eltree_clone = self.project.element_tree.clone();
let action = Action::new(
- ids,
- &mut self.project.element_tree.clone(),
+ &ids,
+ &eltree_clone,
Some(element.get_id()),
);
let result = element.handle_action(
@@ -193,13 +232,11 @@ impl App {
self.project = Project::new();
self.project_path = None;
self.editor_content = text_editor::Content::new();
- } else {
- if let MessageDialogResult::Ok = unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and create a new project?") {
+ } else if unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and create a new project?") {
self.is_dirty = false;
self.project = Project::new();
self.project_path = None;
self.editor_content = text_editor::Content::new();
- }
}
}
}
@@ -209,15 +246,13 @@ impl App {
self.is_loading = true;
return Task::perform(
- Project::from_path(),
+ Project::from_file(self.config.clone()),
Message::FileOpened,
);
- } else {
- if let MessageDialogResult::Ok = unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and open another project?") {
+ } else if unsaved_changes_dialog("You have unsaved changes. Do you wish to discard these and open another project?") {
self.is_dirty = false;
self.is_loading = true;
- return Task::perform(Project::from_path(), Message::FileOpened);
- }
+ return Task::perform(Project::from_file(self.config.clone()), Message::FileOpened);
}
}
}
@@ -227,11 +262,12 @@ impl App {
match result {
Ok((path, project)) => {
- self.project = project.clone();
+ self.project = project;
self.project_path = Some(path);
self.editor_content = text_editor::Content::with_text(
- &project
- .app_code()
+ &self
+ .project
+ .app_code(&self.config)
.unwrap_or_else(|err| err.to_string()),
);
}
@@ -299,7 +335,7 @@ impl App {
fn view(&self) -> Element<'_, Message> {
let header = row![pick_list(
- THEMES,
+ self.config.theme.all.clone(),
Some(self.theme.target().clone()),
|theme| { Message::ToggleTheme(theme.into()) }
)]
@@ -311,12 +347,12 @@ impl App {
Panes::Designer => match &self.designer_page {
DesignerPage::DesignerView => designer_view::view(
&self.project.element_tree,
- self.project.get_theme(),
+ self.project.get_theme(&self.config),
is_focused,
),
DesignerPage::CodeView => code_view::view(
&self.editor_content,
- self.theme.value().clone(),
+ self.theme.target().clone(),
is_focused,
),
},