styles: working on making it look just right
This commit is contained in:
@@ -1,29 +1,59 @@
|
||||
use iced::{Element, Length, widget::{container, pick_list, row}};
|
||||
use iced::{
|
||||
Background, Element, Length, Padding, Theme,
|
||||
widget::{container, pick_list, row},
|
||||
};
|
||||
|
||||
use crate::message::{FileAction, Message, ViewAction};
|
||||
|
||||
pub fn view(
|
||||
selected_file_action: Option<FileAction>,
|
||||
selected_view_action: Option<ViewAction>,
|
||||
selected_file_action: Option<FileAction>,
|
||||
selected_view_action: Option<ViewAction>,
|
||||
) -> Element<'static, Message> {
|
||||
|
||||
let file_menu = pick_list(
|
||||
FileAction::ALL,
|
||||
selected_file_action,
|
||||
Message::FileActionSelected,
|
||||
)
|
||||
.placeholder("File");
|
||||
let pick_list_padding = Padding {
|
||||
left: 4.0,
|
||||
right: 4.0,
|
||||
top: 2.0,
|
||||
bottom: 2.0,
|
||||
};
|
||||
|
||||
let view_menu = pick_list(
|
||||
ViewAction::ALL,
|
||||
selected_view_action,
|
||||
Message::ViewActionSelected,
|
||||
)
|
||||
.placeholder("View");
|
||||
let file_menu = pick_list(
|
||||
FileAction::ALL,
|
||||
selected_file_action,
|
||||
Message::FileActionSelected,
|
||||
)
|
||||
.padding(pick_list_padding)
|
||||
.style(pick_list_style)
|
||||
.placeholder("File");
|
||||
|
||||
container(
|
||||
row![file_menu, view_menu].spacing(10)
|
||||
)
|
||||
let view_menu = pick_list(
|
||||
ViewAction::ALL,
|
||||
selected_view_action,
|
||||
Message::ViewActionSelected,
|
||||
)
|
||||
.padding(pick_list_padding)
|
||||
.style(pick_list_style)
|
||||
.placeholder("View");
|
||||
|
||||
container(row![file_menu, view_menu].spacing(10))
|
||||
.style(|theme: &Theme| {
|
||||
let base = container::Style::default();
|
||||
|
||||
container::Style {
|
||||
background: container::primary(theme).background,
|
||||
..base
|
||||
}
|
||||
})
|
||||
.padding(5)
|
||||
.width(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn pick_list_style(theme: &Theme, status: pick_list::Status) -> pick_list::Style {
|
||||
let base = pick_list::default(theme, status);
|
||||
|
||||
pick_list::Style {
|
||||
placeholder_color: base.text_color,
|
||||
background: Background::Color(theme.palette().primary),
|
||||
..base
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use iced::{
|
||||
Element, Length, Theme, highlighter,
|
||||
Element, Length, Theme, border, highlighter,
|
||||
widget::{container, markdown, row, text_editor},
|
||||
};
|
||||
|
||||
@@ -9,9 +9,24 @@ pub fn view<'a>(file: &'a File, mode: Mode, font_size: u32) -> Element<'a, Messa
|
||||
match mode {
|
||||
Mode::Edit => {
|
||||
let editor = text_editor(file.content())
|
||||
.highlight(file.extension().unwrap_or("txt"), highlighter::Theme::Base16Ocean)
|
||||
.highlight(
|
||||
file.extension().unwrap_or("txt"),
|
||||
highlighter::Theme::Base16Ocean,
|
||||
)
|
||||
.padding(10)
|
||||
.size(font_size)
|
||||
.height(Length::Fill)
|
||||
.style(|theme: &Theme, status: text_editor::Status| {
|
||||
let base = text_editor::default(theme, status);
|
||||
|
||||
text_editor::Style {
|
||||
border: border::Border {
|
||||
width: 0.0,
|
||||
..Default::default()
|
||||
},
|
||||
..base
|
||||
}
|
||||
})
|
||||
.on_action(Message::Edit);
|
||||
|
||||
container(row![editor]).height(Length::Fill).into()
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
use iced::widget::{container, row, text};
|
||||
use iced::{Element, Length};
|
||||
use crate::file::File;
|
||||
use iced::widget::{container, row, text};
|
||||
use iced::{Element, Length, Padding, Theme};
|
||||
|
||||
pub fn view(file: &File) -> Element<'_, crate::Message> {
|
||||
let path_text = text(file.path_summary());
|
||||
let cursor_text = text(file.position_summary());
|
||||
let path_text = text(file.path_summary()).size(12);
|
||||
let cursor_text = text(file.position_summary()).size(12);
|
||||
|
||||
container(
|
||||
row![cursor_text, path_text]
|
||||
.spacing(20)
|
||||
)
|
||||
container(row![cursor_text, path_text].spacing(20))
|
||||
.style(|theme: &Theme| {
|
||||
let base = container::Style::default();
|
||||
|
||||
container::Style {
|
||||
background: container::primary(theme).background,
|
||||
..base
|
||||
}
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.padding(5)
|
||||
.padding(Padding {
|
||||
left: 20.0,
|
||||
right: 20.0,
|
||||
top: 5.0,
|
||||
bottom: 5.0,
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
+62
-30
@@ -1,41 +1,73 @@
|
||||
use crate::file::File;
|
||||
use crate::message::{FileAction, Message};
|
||||
use iced::{Background, Border, Theme, border};
|
||||
use iced::{Background, Border, Padding, Theme, border};
|
||||
use iced::{
|
||||
Element,
|
||||
widget::{button, container, row, scrollable, text},
|
||||
Element,
|
||||
widget::{button, container, row, scrollable, text},
|
||||
};
|
||||
|
||||
pub fn view<'a>(files: &'a [File], active_index: usize) -> Element<'a, Message> {
|
||||
let tabs = files.iter().enumerate().map(|(index, file)| {
|
||||
let is_focused = index == active_index;
|
||||
let tabs = files.iter().enumerate().map(|(index, file)| {
|
||||
let is_focused = index == active_index;
|
||||
|
||||
let label = text(file.display_name());
|
||||
let close_btn =
|
||||
button(text("x")).on_press(Message::FileActionSelected(FileAction::Close(Some(index))));
|
||||
let label = text(file.display_name());
|
||||
let close_btn =
|
||||
button(text("x")).padding(1).on_press(Message::FileActionSelected(FileAction::Close(Some(index))));
|
||||
|
||||
button(row![label, close_btn].spacing(5))
|
||||
.on_press(Message::SwitchTab(index))
|
||||
.padding(5)
|
||||
.style(move |theme: &Theme, status| {
|
||||
let base = button::primary(theme, status);
|
||||
let button_background = if is_focused {
|
||||
base.background
|
||||
} else {
|
||||
Some(Background::Color(theme.palette().background))
|
||||
};
|
||||
button(
|
||||
row![label, close_btn]
|
||||
.spacing(5)
|
||||
.align_y(iced::Alignment::Center),
|
||||
)
|
||||
.on_press(Message::SwitchTab(index))
|
||||
.padding(Padding {
|
||||
top: 5.0,
|
||||
bottom: 5.0,
|
||||
left: 10.0,
|
||||
right: 10.0,
|
||||
})
|
||||
.style(move |theme: &Theme, status: button::Status| {
|
||||
let base = button::primary(theme, status);
|
||||
|
||||
button::Style {
|
||||
background: button_background,
|
||||
border: Border {
|
||||
radius: border::radius(0).top_left(10).top_right(10),
|
||||
..base.border
|
||||
},
|
||||
..base
|
||||
}
|
||||
})
|
||||
.into()
|
||||
});
|
||||
let button_background = if is_focused {
|
||||
Some(Background::Color(theme.palette().primary))
|
||||
} else {
|
||||
Some(Background::Color(theme.palette().background))
|
||||
};
|
||||
|
||||
scrollable(container(row(tabs).spacing(2))).into()
|
||||
let button_style = button::Style {
|
||||
background: button_background,
|
||||
border: Border {
|
||||
radius: border::radius(0).top_left(10).top_right(10),
|
||||
..base.border
|
||||
},
|
||||
..base
|
||||
};
|
||||
|
||||
match status {
|
||||
button::Status::Hovered => button::Style {
|
||||
background: Some(Background::Color(theme.palette().primary)),
|
||||
..button_style
|
||||
},
|
||||
_ => button_style,
|
||||
}
|
||||
})
|
||||
.into()
|
||||
});
|
||||
|
||||
scrollable(container(row(tabs)).padding(Padding {
|
||||
top: 5.0,
|
||||
left: 5.0,
|
||||
right: 5.0,
|
||||
bottom: 0.0,
|
||||
}))
|
||||
.direction(scrollable::Direction::Horizontal(
|
||||
scrollable::Scrollbar::new().spacing(1)
|
||||
))
|
||||
.style(|theme: &Theme, status: scrollable::Status| {
|
||||
let mut style = scrollable::default(theme, status);
|
||||
style.horizontal_rail.background = Some(Background::Color(theme.palette().primary));
|
||||
style
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
+57
-49
@@ -7,9 +7,10 @@ mod key_bindings;
|
||||
mod message;
|
||||
mod state;
|
||||
|
||||
use iced::Theme;
|
||||
use iced::theme::Palette;
|
||||
use iced::widget::column;
|
||||
use iced::window::icon;
|
||||
use iced::{Color, Theme};
|
||||
use iced::{Element, Subscription, Task, event};
|
||||
use iced::{keyboard, window};
|
||||
|
||||
@@ -17,69 +18,76 @@ use crate::message::Message;
|
||||
use crate::state::State;
|
||||
|
||||
pub fn main() -> iced::Result {
|
||||
iced::application(boot, update, view)
|
||||
.subscription(subscription)
|
||||
.font(constants::CUSTOM_FONT_BYTES)
|
||||
.theme(theme)
|
||||
.settings(iced::Settings {
|
||||
default_font: constants::CUSTOM_FONT,
|
||||
..Default::default()
|
||||
})
|
||||
.window(window::Settings {
|
||||
icon: Some(
|
||||
icon::from_file_data(constants::ICON_BYTES, None).expect("Failed to load icon"),
|
||||
),
|
||||
..window::Settings::default()
|
||||
})
|
||||
.run()
|
||||
iced::application(boot, update, view)
|
||||
.subscription(subscription)
|
||||
.font(constants::CUSTOM_FONT_BYTES)
|
||||
.theme(theme)
|
||||
.settings(iced::Settings {
|
||||
default_font: constants::CUSTOM_FONT,
|
||||
..Default::default()
|
||||
})
|
||||
.window(window::Settings {
|
||||
icon: Some(icon::from_file_data(constants::ICON_BYTES, None).expect("Failed to load icon")),
|
||||
..window::Settings::default()
|
||||
})
|
||||
.run()
|
||||
}
|
||||
|
||||
fn boot() -> State {
|
||||
state::State::new()
|
||||
state::State::new()
|
||||
}
|
||||
|
||||
fn update(state: &mut State, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Edit(action) => handler::edit(state, action),
|
||||
Message::SwitchTab(index) => handler::switch_tab(state, index),
|
||||
Message::LinkClicked(url) => handler::link_clicked(url),
|
||||
Message::FileActionSelected(action) => handler::file_action(state, action),
|
||||
Message::ViewActionSelected(action) => handler::view_action(state, action),
|
||||
Message::FileOpened(result) => handler::opened_file(state, result),
|
||||
Message::FileSaved(result) => handler::saved_file(state, result),
|
||||
}
|
||||
match message {
|
||||
Message::Edit(action) => handler::edit(state, action),
|
||||
Message::SwitchTab(index) => handler::switch_tab(state, index),
|
||||
Message::LinkClicked(url) => handler::link_clicked(url),
|
||||
Message::FileActionSelected(action) => handler::file_action(state, action),
|
||||
Message::ViewActionSelected(action) => handler::view_action(state, action),
|
||||
Message::FileOpened(result) => handler::opened_file(state, result),
|
||||
Message::FileSaved(result) => handler::saved_file(state, result),
|
||||
}
|
||||
}
|
||||
|
||||
fn view(state: &State) -> Element<'_, Message> {
|
||||
let current_file = state.active_file();
|
||||
let current_file = state.active_file();
|
||||
|
||||
column![
|
||||
components::tabs::view(state.files(), state.current_file_index()),
|
||||
components::action_bar::view(state.selected_file_action(), state.selected_view_action()),
|
||||
components::editor::view(current_file, state.mode(), state.font_size()),
|
||||
components::status_bar::view(current_file),
|
||||
]
|
||||
.padding(10)
|
||||
.into()
|
||||
column![
|
||||
components::tabs::view(state.files(), state.current_file_index()),
|
||||
components::action_bar::view(state.selected_file_action(), state.selected_view_action()),
|
||||
components::editor::view(current_file, state.mode(), state.font_size()),
|
||||
components::status_bar::view(current_file),
|
||||
]
|
||||
.into()
|
||||
}
|
||||
|
||||
fn subscription(_state: &State) -> Subscription<Message> {
|
||||
event::listen_with(|e, _status, _win| -> Option<Message> {
|
||||
match e {
|
||||
iced::Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) => {
|
||||
for vb in key_bindings::ALL {
|
||||
if vb.should_handle(&key, &modifiers) {
|
||||
return Some(vb.message());
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
event::listen_with(|e, _status, _win| -> Option<Message> {
|
||||
match e {
|
||||
iced::Event::Keyboard(keyboard::Event::KeyPressed { key, modifiers, .. }) => {
|
||||
for vb in key_bindings::ALL {
|
||||
if vb.should_handle(&key, &modifiers) {
|
||||
return Some(vb.message());
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn theme(_state: &State) -> Theme {
|
||||
Theme::Dark
|
||||
Theme::custom(
|
||||
"Win11 Dark",
|
||||
Palette {
|
||||
background: Color::from_rgb8(0x20, 0x20, 0x20),
|
||||
text: Color::from_rgb8(0xF2, 0xF2, 0xF2),
|
||||
primary: Color::from_rgb8(0x2C, 0x2C, 0x2C),
|
||||
success: Color::from_rgb8(0x4C, 0xC3, 0x8A),
|
||||
warning: Color::from_rgb8(0xF5, 0xC8, 0x4B),
|
||||
danger: Color::from_rgb8(0xE8, 0x6A, 0x6A),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user