Some checks are pending
Validate .desktop files / validate (push) Waiting to run
147 lines
4.7 KiB
Rust
147 lines
4.7 KiB
Rust
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
use cosmic::widget::RcElementWrapper;
|
|
use cosmic::widget::menu::key_bind::KeyBind;
|
|
use cosmic::widget::menu::{self, ItemHeight, ItemWidth, MenuBar};
|
|
use cosmic::{Element, theme};
|
|
use std::collections::HashMap;
|
|
use std::path::PathBuf;
|
|
|
|
use crate::{Action, Config, ConfigState, Message, fl};
|
|
|
|
pub fn menu_bar<'a>(
|
|
_config: &Config,
|
|
config_state: &ConfigState,
|
|
key_binds: &HashMap<KeyBind, Action>,
|
|
projects: &[(String, PathBuf)],
|
|
ab_repeat: &Option<(Option<f64>, Option<f64>)>,
|
|
has_video: bool,
|
|
) -> Element<'a, Message> {
|
|
let home_dir_opt = std::env::home_dir();
|
|
let format_path = |path: &PathBuf| -> String {
|
|
if let Some(home_dir) = &home_dir_opt
|
|
&& let Ok(part) = path.strip_prefix(home_dir)
|
|
{
|
|
return format!("~/{}", part.display());
|
|
}
|
|
path.display().to_string()
|
|
};
|
|
let format_url = |url: &url::Url| -> String {
|
|
match url.to_file_path() {
|
|
Ok(path) => format_path(&path),
|
|
Err(()) => url.to_string(),
|
|
}
|
|
};
|
|
|
|
let files_len = if config_state.recent_files.is_empty() {
|
|
0
|
|
} else {
|
|
config_state.recent_files.len() + 2
|
|
};
|
|
let mut recent_files = Vec::with_capacity(files_len);
|
|
for (i, path) in config_state.recent_files.iter().enumerate() {
|
|
recent_files.push(menu::Item::Button(
|
|
format_url(path),
|
|
None,
|
|
Action::FileOpenRecent(i),
|
|
));
|
|
}
|
|
if files_len > 0 {
|
|
recent_files.push(menu::Item::Divider);
|
|
recent_files.push(menu::Item::Button(
|
|
fl!("clear-recent"),
|
|
None,
|
|
Action::FileClearRecents,
|
|
));
|
|
}
|
|
|
|
let projects_len = if config_state.recent_projects.is_empty() {
|
|
0
|
|
} else {
|
|
config_state.recent_projects.len() + 2
|
|
};
|
|
let mut recent_projects = Vec::with_capacity(projects_len);
|
|
for (i, path) in config_state.recent_projects.iter().enumerate() {
|
|
recent_projects.push(menu::Item::Button(
|
|
format_path(path),
|
|
None,
|
|
Action::FolderOpenRecent(i),
|
|
));
|
|
}
|
|
if projects_len > 0 {
|
|
recent_projects.push(menu::Item::Divider);
|
|
recent_projects.push(menu::Item::Button(
|
|
fl!("clear-recent"),
|
|
None,
|
|
Action::FolderClearRecents,
|
|
));
|
|
}
|
|
|
|
let mut close_projects = Vec::with_capacity(projects.len());
|
|
for (folder_i, (name, _path)) in projects.iter().enumerate() {
|
|
close_projects.push(menu::Item::Button(
|
|
name.clone(),
|
|
None,
|
|
Action::FolderClose(folder_i),
|
|
));
|
|
}
|
|
|
|
let mut playback = Vec::with_capacity(3);
|
|
|
|
if has_video {
|
|
playback.push(menu::Item::Button(
|
|
fl!("next-frame"),
|
|
None,
|
|
Action::NextFrame,
|
|
));
|
|
playback.push(menu::Item::Button(
|
|
fl!("previous-frame"),
|
|
None,
|
|
Action::PreviousFrame,
|
|
));
|
|
}
|
|
|
|
playback.push(menu::Item::Button(
|
|
match ab_repeat {
|
|
None => fl!("ab-repeat-set-a"),
|
|
Some((_, None)) => fl!("ab-repeat-set-b"),
|
|
Some((_, Some(_))) => fl!("ab-repeat-clear"),
|
|
},
|
|
None,
|
|
Action::AbRepeat,
|
|
));
|
|
MenuBar::new(vec![
|
|
menu::Tree::with_children(
|
|
RcElementWrapper::new(Element::from(menu::root(fl!("file")))),
|
|
menu::items(
|
|
key_binds,
|
|
vec![
|
|
menu::Item::Button(fl!("open-media"), None, Action::FileOpen),
|
|
menu::Item::Folder(fl!("open-recent-media"), recent_files),
|
|
menu::Item::Button(fl!("close-file"), None, Action::FileClose),
|
|
menu::Item::Divider,
|
|
menu::Item::Button(fl!("open-media-folder"), None, Action::FolderOpen),
|
|
menu::Item::Folder(fl!("open-recent-media-folder"), recent_projects),
|
|
menu::Item::Folder(fl!("close-media-folder"), close_projects),
|
|
menu::Item::Divider,
|
|
menu::Item::Button(fl!("quit"), None, Action::WindowClose),
|
|
],
|
|
),
|
|
),
|
|
menu::Tree::with_children(
|
|
RcElementWrapper::new(Element::from(menu::root(fl!("playback")))),
|
|
menu::items(key_binds, playback),
|
|
),
|
|
menu::Tree::with_children(
|
|
RcElementWrapper::new(Element::from(menu::root(fl!("help")))),
|
|
menu::items(
|
|
key_binds,
|
|
vec![menu::Item::Button(fl!("menu-about"), None, Action::About)],
|
|
),
|
|
),
|
|
])
|
|
.item_height(ItemHeight::Dynamic(40))
|
|
.item_width(ItemWidth::Uniform(320))
|
|
.spacing(theme::active().cosmic().spacing.space_xxxs.into())
|
|
.into()
|
|
}
|