use super::*;
impl App {
pub fn view(&self) -> Element<'_, Message> {
use iced::widget::stack;
if self.startup_page_open {
return self.view_startup_page();
}
let editor_area: Element<'_, Message> = if self.settings_open {
self.view_settings_panel()
} else {
let tab_bar = self.view_tab_bar();
let editor_widget = self.view_editor();
let mut editor_col_items: Vec<Element<'_, Message>> = Vec::new();
if self.find_replace.open {
editor_col_items.push(self.view_find_replace_panel());
}
editor_col_items.push(tab_bar);
editor_col_items.push(editor_widget);
if self.terminal_open {
editor_col_items.push(self.view_terminal_panel());
}
if self.command_input.open {
editor_col_items.push(self.view_command_input_bar());
}
let editor_container =
if self.active_tab.is_some() || self.pending_sensitive_open.is_some() {
container(column(editor_col_items))
} else {
self.view_welcome_screen()
}
.width(Length::Fill)
.height(Length::Fill)
.style(editor_container_style);
container(editor_container).padding(0).width(Length::Fill).into()
};
use crate::{
app::ActivePanel,
features::icons::{icon_handle, IconAsset, IconFormat},
};
static ICON_FILES: &[u8] = include_bytes!("../assets/icons/activity-bar-files.svg");
static ICON_GIT: &[u8] = include_bytes!("../assets/icons/activity-bar-git.svg");
static ICON_SETTINGS: &[u8] = include_bytes!("../assets/icons/settings.svg");
let make_activity_icon =
|bytes: &'static [u8], panel: ActivePanel| -> Element<'_, Message> {
let is_active = self.active_panel == panel && self.sidebar_visible;
let icon_color = if is_active {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.88)
} else {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.35)
};
let asset = IconAsset {
format: IconFormat::Svg,
bytes,
};
let img = iced::widget::image::Image::new(icon_handle(asset, 40))
.width(Length::Fixed(20.0))
.height(Length::Fixed(20.0));
let bg = if is_active {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.08)
} else {
iced::Color::TRANSPARENT
};
iced::widget::button(
container(img)
.width(Length::Fixed(40.0))
.height(Length::Fixed(40.0))
.center_x(Length::Fixed(40.0))
.center_y(Length::Fixed(40.0))
.style(move |_t| container::Style {
background: Some(Background::Color(bg)),
border: iced::Border {
radius: 6.0.into(),
..Default::default()
},
..Default::default()
}),
)
.on_press(Message::SetActivePanel(panel))
.style(move |_t, status| iced::widget::button::Style {
background: Some(Background::Color(match status {
iced::widget::button::Status::Hovered => {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.06)
},
_ => iced::Color::TRANSPARENT,
})),
border: iced::Border {
radius: 6.0.into(),
..Default::default()
},
text_color: icon_color,
..Default::default()
})
.padding(0)
.into()
};
let make_bottom_icon =
|bytes: &'static [u8], message: Message, is_active: bool| -> Element<'_, Message> {
let icon_color = if is_active {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.88)
} else {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.35)
};
let asset = IconAsset {
format: IconFormat::Svg,
bytes,
};
let img = iced::widget::image::Image::new(icon_handle(asset, 40))
.width(Length::Fixed(20.0))
.height(Length::Fixed(20.0));
let bg = if is_active {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.08)
} else {
iced::Color::TRANSPARENT
};
iced::widget::button(
container(img)
.width(Length::Fixed(40.0))
.height(Length::Fixed(40.0))
.center_x(Length::Fixed(40.0))
.center_y(Length::Fixed(40.0))
.style(move |_t| container::Style {
background: Some(Background::Color(bg)),
border: iced::Border {
radius: 6.0.into(),
..Default::default()
},
..Default::default()
}),
)
.on_press(message)
.style(move |_t, status| iced::widget::button::Style {
background: Some(Background::Color(match status {
iced::widget::button::Status::Hovered => {
iced::Color::from_rgba(1.0, 1.0, 1.0, 0.06)
},
_ => iced::Color::TRANSPARENT,
})),
border: iced::Border {
radius: 6.0.into(),
..Default::default()
},
text_color: icon_color,
..Default::default()
})
.padding(0)
.into()
};
let activity_bar: Element<'_, Message> = container(
iced::widget::column![
make_activity_icon(ICON_FILES, ActivePanel::Files),
make_activity_icon(ICON_GIT, ActivePanel::Git),
iced::widget::Space::new().height(Length::Fill),
make_bottom_icon(ICON_SETTINGS, Message::ToggleSettings, self.settings_open),
]
.spacing(4)
.padding(iced::Padding {
top: 8.0,
right: 4.0,
bottom: 4.0,
left: 4.0,
}),
)
.width(Length::Fixed(48.0))
.height(Length::Fill)
.style(|_t| container::Style {
background: Some(Background::Color(crate::theme::theme().bg_secondary)),
..Default::default()
})
.into();
let base_content: Element<'_, Message> = if self.sidebar_visible {
let panel: Element<'_, Message> = match self.active_panel {
ActivePanel::Files => view_sidebar(
self.file_tree.as_ref(),
self.sidebar_width,
self.rename_target.as_ref(),
&self.rename_input,
self.rename_input_id.clone(),
),
ActivePanel::Git => {
crate::ui::view_git_panel(&self.git_changes, self.sidebar_width)
},
};
let activity_separator = container(text(""))
.width(Length::Fixed(1.0))
.height(Length::Fill)
.style(activity_panel_separator_style);
let separator = container(text(""))
.width(Length::Fixed(1.0))
.height(Length::Fill)
.style(sidebar_editor_separator_style);
let resize_zone =
mouse_area(container(text("")).width(Length::Fixed(4.0)).height(Length::Fill))
.on_press(Message::SidebarResizeStart)
.interaction(iced::mouse::Interaction::ResizingHorizontally);
row![
activity_bar,
activity_separator,
panel,
separator,
resize_zone,
editor_area
]
.into()
} else {
let activity_separator = container(text(""))
.width(Length::Fixed(1.0))
.height(Length::Fill)
.style(activity_panel_separator_style);
row![activity_bar, activity_separator, editor_area].into()
};
let status_bar = self.view_status_bar();
let with_status = iced::widget::column![
container(base_content)
.width(Length::Fill)
.height(Length::Fill)
.style(|_theme| container::Style {
background: Some(Background::Color(theme().bg_editor)),
..Default::default()
}),
status_bar,
];
let wrapped =
container(with_status).width(Length::Fill).height(Length::Fill).style(|_theme| {
container::Style {
background: Some(Background::Color(theme().bg_editor)),
..Default::default()
}
});
let base_view: Element<'_, Message> = if self.command_palette.open {
stack![wrapped, self.view_command_palette_overlay()].into()
} else if self.fuzzy_finder.open {
stack![wrapped, self.view_fuzzy_finder_overlay()].into()
} else if self.file_finder_visible {
stack![wrapped, self.view_file_finder_overlay()].into()
} else if self.search_visible {
let search_panel = container(self.view_search_panel())
.padding(iced::Padding {
top: 20.0,
right: 0.0,
bottom: 0.0,
left: 20.0,
})
.width(Length::Fill)
.height(Length::Fill);
stack![wrapped, search_panel].into()
} else {
wrapped.into()
};
let with_notification: Element<'_, Message> = if self.notification.is_some() {
stack![base_view, self.view_notification_toast()].into()
} else {
base_view
};
let with_drag_ghost: Element<'_, Message> =
if let Some(ghost) = self.view_floating_drag_ghost() {
stack![with_notification, ghost].into()
} else {
with_notification
};
let with_context_menu: Element<'_, Message> = if self.context_menu.is_some() {
stack![with_drag_ghost, self.view_context_menu_overlay()].into()
} else {
with_drag_ghost
};
if self.update_banner.is_some() {
stack![with_context_menu, self.view_update_banner()].into()
} else {
with_context_menu
}
}
}