parent
60743ed251
commit
21eac9324f
5 changed files with 58 additions and 105 deletions
79
src/app.rs
79
src/app.rs
|
|
@ -166,9 +166,7 @@ impl Action {
|
||||||
Action::OpenTerminal => Message::OpenTerminal(entity_opt),
|
Action::OpenTerminal => Message::OpenTerminal(entity_opt),
|
||||||
Action::OpenWith => Message::ToggleContextPage(ContextPage::OpenWith),
|
Action::OpenWith => Message::ToggleContextPage(ContextPage::OpenWith),
|
||||||
Action::Paste => Message::Paste(entity_opt),
|
Action::Paste => Message::Paste(entity_opt),
|
||||||
Action::Preview => {
|
Action::Preview => Message::ToggleShowDetails,
|
||||||
Message::ToggleContextPage(ContextPage::Preview(entity_opt, PreviewKind::Selected))
|
|
||||||
}
|
|
||||||
Action::Rename => Message::Rename(entity_opt),
|
Action::Rename => Message::Rename(entity_opt),
|
||||||
Action::RestoreFromTrash => Message::RestoreFromTrash(entity_opt),
|
Action::RestoreFromTrash => Message::RestoreFromTrash(entity_opt),
|
||||||
Action::SearchActivate => Message::SearchActivate,
|
Action::SearchActivate => Message::SearchActivate,
|
||||||
|
|
@ -288,7 +286,6 @@ pub enum Message {
|
||||||
PendingComplete(u64),
|
PendingComplete(u64),
|
||||||
PendingError(u64, String),
|
PendingError(u64, String),
|
||||||
PendingProgress(u64, f32),
|
PendingProgress(u64, f32),
|
||||||
Preview(Entity, PreviewKind, time::Duration),
|
|
||||||
RescanTrash,
|
RescanTrash,
|
||||||
Rename(Option<Entity>),
|
Rename(Option<Entity>),
|
||||||
ReplaceResult(ReplaceResult),
|
ReplaceResult(ReplaceResult),
|
||||||
|
|
@ -308,6 +305,7 @@ pub enum Message {
|
||||||
TabRescan(Entity, Location, Vec<tab::Item>, Option<PathBuf>),
|
TabRescan(Entity, Location, Vec<tab::Item>, Option<PathBuf>),
|
||||||
TabView(Option<Entity>, tab::View),
|
TabView(Option<Entity>, tab::View),
|
||||||
ToggleContextPage(ContextPage),
|
ToggleContextPage(ContextPage),
|
||||||
|
ToggleShowDetails,
|
||||||
ToggleFoldersFirst,
|
ToggleFoldersFirst,
|
||||||
Undo(usize),
|
Undo(usize),
|
||||||
UndoTrash(widget::ToastId, Arc<[PathBuf]>),
|
UndoTrash(widget::ToastId, Arc<[PathBuf]>),
|
||||||
|
|
@ -473,7 +471,6 @@ pub struct App {
|
||||||
pending_operations: BTreeMap<u64, (Operation, f32)>,
|
pending_operations: BTreeMap<u64, (Operation, f32)>,
|
||||||
complete_operations: BTreeMap<u64, Operation>,
|
complete_operations: BTreeMap<u64, Operation>,
|
||||||
failed_operations: BTreeMap<u64, (Operation, String)>,
|
failed_operations: BTreeMap<u64, (Operation, String)>,
|
||||||
preview_opt: Option<(Entity, PreviewKind, time::Instant)>,
|
|
||||||
search_active: bool,
|
search_active: bool,
|
||||||
search_id: widget::Id,
|
search_id: widget::Id,
|
||||||
search_input: String,
|
search_input: String,
|
||||||
|
|
@ -1063,7 +1060,9 @@ impl Application for App {
|
||||||
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
fn init(mut core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) {
|
||||||
core.window.context_is_overlay = false;
|
core.window.context_is_overlay = false;
|
||||||
match flags.mode {
|
match flags.mode {
|
||||||
Mode::App => {}
|
Mode::App => {
|
||||||
|
core.window.show_context = flags.config.show_details;
|
||||||
|
}
|
||||||
Mode::Desktop => {
|
Mode::Desktop => {
|
||||||
core.window.content_container = false;
|
core.window.content_container = false;
|
||||||
core.window.show_window_menu = false;
|
core.window.show_window_menu = false;
|
||||||
|
|
@ -1086,7 +1085,7 @@ impl Application for App {
|
||||||
config: flags.config,
|
config: flags.config,
|
||||||
mode: flags.mode,
|
mode: flags.mode,
|
||||||
app_themes,
|
app_themes,
|
||||||
context_page: ContextPage::Settings,
|
context_page: ContextPage::Preview(None, PreviewKind::Selected),
|
||||||
dialog_pages: VecDeque::new(),
|
dialog_pages: VecDeque::new(),
|
||||||
dialog_text_input: widget::Id::unique(),
|
dialog_text_input: widget::Id::unique(),
|
||||||
key_binds: key_binds(),
|
key_binds: key_binds(),
|
||||||
|
|
@ -1101,7 +1100,6 @@ impl Application for App {
|
||||||
pending_operations: BTreeMap::new(),
|
pending_operations: BTreeMap::new(),
|
||||||
complete_operations: BTreeMap::new(),
|
complete_operations: BTreeMap::new(),
|
||||||
failed_operations: BTreeMap::new(),
|
failed_operations: BTreeMap::new(),
|
||||||
preview_opt: None,
|
|
||||||
search_active: false,
|
search_active: false,
|
||||||
search_id: widget::Id::unique(),
|
search_id: widget::Id::unique(),
|
||||||
search_input: String::new(),
|
search_input: String::new(),
|
||||||
|
|
@ -1250,6 +1248,19 @@ impl Application for App {
|
||||||
Some(Message::WindowClose)
|
Some(Message::WindowClose)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_context_drawer(&mut self) -> Command<Self::Message> {
|
||||||
|
match self.context_page {
|
||||||
|
ContextPage::Preview(_, _) => {
|
||||||
|
// Persist state of preview page
|
||||||
|
if self.core.window.show_context != self.config.show_details {
|
||||||
|
return self.update(Message::ToggleShowDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
Command::none()
|
||||||
|
}
|
||||||
|
|
||||||
fn on_escape(&mut self) -> Command<Self::Message> {
|
fn on_escape(&mut self) -> Command<Self::Message> {
|
||||||
let entity = self.tab_model.active();
|
let entity = self.tab_model.active();
|
||||||
|
|
||||||
|
|
@ -1360,8 +1371,10 @@ impl Application for App {
|
||||||
Message::Config(config) => {
|
Message::Config(config) => {
|
||||||
if config != self.config {
|
if config != self.config {
|
||||||
log::info!("update config");
|
log::info!("update config");
|
||||||
//TODO: update syntax theme by clearing tabs, only if needed
|
// Show details is preserved for existing instances
|
||||||
|
let show_details = self.config.show_details;
|
||||||
self.config = config;
|
self.config = config;
|
||||||
|
self.config.show_details = show_details;
|
||||||
return self.update_config();
|
return self.update_config();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1933,17 +1946,6 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
return self.update_notification();
|
return self.update_notification();
|
||||||
}
|
}
|
||||||
Message::Preview(entity, kind, timeout) => {
|
|
||||||
if self
|
|
||||||
.preview_opt
|
|
||||||
.as_ref()
|
|
||||||
.is_some_and(|(e, k, i)| *e == entity && *k == kind && i.elapsed() > timeout)
|
|
||||||
{
|
|
||||||
self.context_page = ContextPage::Preview(Some(entity), kind);
|
|
||||||
self.set_show_context(true);
|
|
||||||
self.set_context_title(self.context_page.title());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::RescanTrash => {
|
Message::RescanTrash => {
|
||||||
// Update trash icon if empty/full
|
// Update trash icon if empty/full
|
||||||
let maybe_entity = self.nav_model.iter().find(|&entity| {
|
let maybe_entity = self.nav_model.iter().find(|&entity| {
|
||||||
|
|
@ -2152,6 +2154,16 @@ impl Application for App {
|
||||||
return self.update_config();
|
return self.update_config();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::ToggleShowDetails => {
|
||||||
|
let show_details = !self.config.show_details;
|
||||||
|
//TODO: move to update_config?
|
||||||
|
if show_details {
|
||||||
|
self.context_page = ContextPage::Preview(None, PreviewKind::Selected);
|
||||||
|
self.core.window.show_context = true;
|
||||||
|
}
|
||||||
|
config_set!(show_details, show_details);
|
||||||
|
return self.update_config();
|
||||||
|
}
|
||||||
Message::ToggleFoldersFirst => {
|
Message::ToggleFoldersFirst => {
|
||||||
let mut config = self.config.tab;
|
let mut config = self.config.tab;
|
||||||
config.folders_first = !config.folders_first;
|
config.folders_first = !config.folders_first;
|
||||||
|
|
@ -2273,22 +2285,10 @@ impl Application for App {
|
||||||
log::error!("failed to get current executable path: {}", err);
|
log::error!("failed to get current executable path: {}", err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
tab::Command::Preview(kind, mut timeout) => {
|
tab::Command::Preview(kind) => {
|
||||||
self.preview_opt = Some((entity, kind.clone(), Instant::now()));
|
self.context_page = ContextPage::Preview(Some(entity), kind);
|
||||||
if self.core.window.show_context {
|
self.set_show_context(true);
|
||||||
// If the context window is already open, immediately show the preview
|
self.set_context_title(self.context_page.title());
|
||||||
timeout = time::Duration::new(0, 0)
|
|
||||||
};
|
|
||||||
commands.push(Command::perform(
|
|
||||||
async move {
|
|
||||||
tokio::time::sleep(timeout).await;
|
|
||||||
message::app(Message::Preview(entity, kind, timeout))
|
|
||||||
},
|
|
||||||
|x| x,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
tab::Command::PreviewCancel => {
|
|
||||||
self.preview_opt = None;
|
|
||||||
}
|
}
|
||||||
tab::Command::WindowDrag => {
|
tab::Command::WindowDrag => {
|
||||||
commands.push(window::drag(self.main_window_id()));
|
commands.push(window::drag(self.main_window_id()));
|
||||||
|
|
@ -3182,7 +3182,12 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_start(&self) -> Vec<Element<Self::Message>> {
|
fn header_start(&self) -> Vec<Element<Self::Message>> {
|
||||||
vec![menu::menu_bar(self.tab_model.active_data::<Tab>(), &self.key_binds).into()]
|
vec![menu::menu_bar(
|
||||||
|
self.tab_model.active_data::<Tab>(),
|
||||||
|
&self.config,
|
||||||
|
&self.key_binds,
|
||||||
|
)
|
||||||
|
.into()]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_end(&self) -> Vec<Element<Self::Message>> {
|
fn header_end(&self) -> Vec<Element<Self::Message>> {
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,7 @@ use cosmic::{
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{app::App, tab::View};
|
||||||
app::App,
|
|
||||||
tab::{HeadingOptions, View},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const CONFIG_VERSION: u64 = 1;
|
pub const CONFIG_VERSION: u64 = 1;
|
||||||
|
|
||||||
|
|
@ -96,6 +93,7 @@ impl Favorite {
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub app_theme: AppTheme,
|
pub app_theme: AppTheme,
|
||||||
pub favorites: Vec<Favorite>,
|
pub favorites: Vec<Favorite>,
|
||||||
|
pub show_details: bool,
|
||||||
pub tab: TabConfig,
|
pub tab: TabConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,6 +139,7 @@ impl Default for Config {
|
||||||
Favorite::Pictures,
|
Favorite::Pictures,
|
||||||
Favorite::Videos,
|
Favorite::Videos,
|
||||||
],
|
],
|
||||||
|
show_details: false,
|
||||||
tab: TabConfig::default(),
|
tab: TabConfig::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,6 @@ enum Message {
|
||||||
NotifyEvents(Vec<DebouncedEvent>),
|
NotifyEvents(Vec<DebouncedEvent>),
|
||||||
NotifyWatcher(WatcherWrapper),
|
NotifyWatcher(WatcherWrapper),
|
||||||
Open,
|
Open,
|
||||||
Preview(PreviewKind, time::Duration),
|
|
||||||
Save(bool),
|
Save(bool),
|
||||||
SearchActivate,
|
SearchActivate,
|
||||||
SearchClear,
|
SearchClear,
|
||||||
|
|
@ -378,7 +377,6 @@ struct App {
|
||||||
mounters: Mounters,
|
mounters: Mounters,
|
||||||
mounter_items: HashMap<MounterKey, MounterItems>,
|
mounter_items: HashMap<MounterKey, MounterItems>,
|
||||||
nav_model: segmented_button::SingleSelectModel,
|
nav_model: segmented_button::SingleSelectModel,
|
||||||
preview_opt: Option<(PreviewKind, time::Instant)>,
|
|
||||||
result_opt: Option<DialogResult>,
|
result_opt: Option<DialogResult>,
|
||||||
search_active: bool,
|
search_active: bool,
|
||||||
search_id: widget::Id,
|
search_id: widget::Id,
|
||||||
|
|
@ -683,6 +681,7 @@ impl Application for App {
|
||||||
core.window.show_close = false;
|
core.window.show_close = false;
|
||||||
core.window.show_maximize = false;
|
core.window.show_maximize = false;
|
||||||
core.window.show_minimize = false;
|
core.window.show_minimize = false;
|
||||||
|
core.window.show_context = true;
|
||||||
|
|
||||||
let title = flags.kind.title();
|
let title = flags.kind.title();
|
||||||
let accept_label = flags.kind.accept_label();
|
let accept_label = flags.kind.accept_label();
|
||||||
|
|
@ -711,7 +710,7 @@ impl Application for App {
|
||||||
title,
|
title,
|
||||||
accept_label,
|
accept_label,
|
||||||
choices: Vec::new(),
|
choices: Vec::new(),
|
||||||
context_page: ContextPage::Settings,
|
context_page: ContextPage::Preview(None, PreviewKind::Selected),
|
||||||
dialog_pages: VecDeque::new(),
|
dialog_pages: VecDeque::new(),
|
||||||
dialog_text_input: widget::Id::unique(),
|
dialog_text_input: widget::Id::unique(),
|
||||||
filters: Vec::new(),
|
filters: Vec::new(),
|
||||||
|
|
@ -721,7 +720,6 @@ impl Application for App {
|
||||||
mounters: mounters(),
|
mounters: mounters(),
|
||||||
mounter_items: HashMap::new(),
|
mounter_items: HashMap::new(),
|
||||||
nav_model: segmented_button::ModelBuilder::default().build(),
|
nav_model: segmented_button::ModelBuilder::default().build(),
|
||||||
preview_opt: None,
|
|
||||||
result_opt: None,
|
result_opt: None,
|
||||||
search_active: false,
|
search_active: false,
|
||||||
search_id: widget::Id::unique(),
|
search_id: widget::Id::unique(),
|
||||||
|
|
@ -1233,17 +1231,6 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::Preview(kind, timeout) => {
|
|
||||||
if self
|
|
||||||
.preview_opt
|
|
||||||
.as_ref()
|
|
||||||
.is_some_and(|(k, i)| *k == kind && i.elapsed() > timeout)
|
|
||||||
{
|
|
||||||
self.context_page = ContextPage::Preview(None, kind);
|
|
||||||
self.set_show_context(true);
|
|
||||||
self.set_context_title(self.context_page.title());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::Save(replace) => {
|
Message::Save(replace) => {
|
||||||
if let DialogKind::SaveFile { filename } = &self.flags.kind {
|
if let DialogKind::SaveFile { filename } = &self.flags.kind {
|
||||||
if !filename.is_empty() {
|
if !filename.is_empty() {
|
||||||
|
|
@ -1341,22 +1328,10 @@ impl Application for App {
|
||||||
commands.push(self.update(Message::Open));
|
commands.push(self.update(Message::Open));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tab::Command::Preview(kind, mut timeout) => {
|
tab::Command::Preview(kind) => {
|
||||||
self.preview_opt = Some((kind.clone(), time::Instant::now()));
|
self.context_page = ContextPage::Preview(None, kind);
|
||||||
if self.core.window.show_context {
|
self.set_show_context(true);
|
||||||
// If the context window is already open, immediately show the preview
|
self.set_context_title(self.context_page.title());
|
||||||
timeout = time::Duration::new(0, 0)
|
|
||||||
};
|
|
||||||
commands.push(Command::perform(
|
|
||||||
async move {
|
|
||||||
tokio::time::sleep(timeout).await;
|
|
||||||
message::app(Message::Preview(kind, timeout))
|
|
||||||
},
|
|
||||||
|x| x,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
tab::Command::PreviewCancel => {
|
|
||||||
self.preview_opt = None;
|
|
||||||
}
|
}
|
||||||
tab::Command::WindowDrag => {
|
tab::Command::WindowDrag => {
|
||||||
commands.push(window::drag(self.main_window_id()));
|
commands.push(window::drag(self.main_window_id()));
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{Action, Message},
|
app::{Action, Message},
|
||||||
|
config::Config,
|
||||||
fl,
|
fl,
|
||||||
tab::{self, HeadingOptions, Location, LocationMenuAction, Tab},
|
tab::{self, HeadingOptions, Location, LocationMenuAction, Tab},
|
||||||
};
|
};
|
||||||
|
|
@ -349,6 +350,7 @@ pub fn dialog_menu<'a>(
|
||||||
|
|
||||||
pub fn menu_bar<'a>(
|
pub fn menu_bar<'a>(
|
||||||
tab_opt: Option<&Tab>,
|
tab_opt: Option<&Tab>,
|
||||||
|
config: &Config,
|
||||||
key_binds: &HashMap<KeyBind, Action>,
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let sort_item = |label, sort, dir| {
|
let sort_item = |label, sort, dir| {
|
||||||
|
|
@ -459,7 +461,7 @@ pub fn menu_bar<'a>(
|
||||||
tab_opt.map_or(false, |tab| tab.config.folders_first),
|
tab_opt.map_or(false, |tab| tab.config.folders_first),
|
||||||
Action::ToggleFoldersFirst,
|
Action::ToggleFoldersFirst,
|
||||||
),
|
),
|
||||||
menu::Item::Button(fl!("show-details"), Action::Preview),
|
menu::Item::CheckBox(fl!("show-details"), config.show_details, Action::Preview),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
menu_button_optional(fl!("gallery-preview"), Action::Gallery, selected > 0),
|
menu_button_optional(fl!("gallery-preview"), Action::Gallery, selected > 0),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
|
|
|
||||||
36
src/tab.rs
36
src/tab.rs
|
|
@ -821,8 +821,7 @@ pub enum Command {
|
||||||
OpenFile(PathBuf),
|
OpenFile(PathBuf),
|
||||||
OpenInNewTab(PathBuf),
|
OpenInNewTab(PathBuf),
|
||||||
OpenInNewWindow(PathBuf),
|
OpenInNewWindow(PathBuf),
|
||||||
Preview(PreviewKind, Duration),
|
Preview(PreviewKind),
|
||||||
PreviewCancel,
|
|
||||||
WindowDrag,
|
WindowDrag,
|
||||||
WindowToggleMaximize,
|
WindowToggleMaximize,
|
||||||
}
|
}
|
||||||
|
|
@ -1750,7 +1749,6 @@ impl Tab {
|
||||||
let mut history_i_opt = None;
|
let mut history_i_opt = None;
|
||||||
let mod_ctrl = modifiers.contains(Modifiers::CTRL) && self.mode.multiple();
|
let mod_ctrl = modifiers.contains(Modifiers::CTRL) && self.mode.multiple();
|
||||||
let mod_shift = modifiers.contains(Modifiers::SHIFT) && self.mode.multiple();
|
let mod_shift = modifiers.contains(Modifiers::SHIFT) && self.mode.multiple();
|
||||||
let last_select_focus = self.select_focus;
|
|
||||||
match message {
|
match message {
|
||||||
Message::AddNetworkDrive => {
|
Message::AddNetworkDrive => {
|
||||||
commands.push(Command::AddNetworkDrive);
|
commands.push(Command::AddNetworkDrive);
|
||||||
|
|
@ -1804,9 +1802,6 @@ impl Tab {
|
||||||
} else {
|
} else {
|
||||||
log::warn!("no item for click index {:?}", click_i_opt);
|
log::warn!("no item for click index {:?}", click_i_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel any preview timers
|
|
||||||
commands.push(Command::PreviewCancel);
|
|
||||||
}
|
}
|
||||||
Message::Click(click_i_opt) => {
|
Message::Click(click_i_opt) => {
|
||||||
self.selected_clicked = false;
|
self.selected_clicked = false;
|
||||||
|
|
@ -1988,11 +1983,9 @@ impl Tab {
|
||||||
//TODO: blocking code, run in command
|
//TODO: blocking code, run in command
|
||||||
match item_from_path(&path, IconSizes::default()) {
|
match item_from_path(&path, IconSizes::default()) {
|
||||||
Ok(item) => {
|
Ok(item) => {
|
||||||
// Show preview instantly
|
commands.push(Command::Preview(PreviewKind::Custom(
|
||||||
commands.push(Command::Preview(
|
PreviewItem(item),
|
||||||
PreviewKind::Custom(PreviewItem(item)),
|
)));
|
||||||
Duration::new(0, 0),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::warn!("failed to get item from path {:?}: {}", path, err);
|
log::warn!("failed to get item from path {:?}: {}", path, err);
|
||||||
|
|
@ -2442,9 +2435,6 @@ impl Tab {
|
||||||
|x| x,
|
|x| x,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear preview timer
|
|
||||||
commands.push(Command::PreviewCancel);
|
|
||||||
}
|
}
|
||||||
Message::DndLeave(loc) => {
|
Message::DndLeave(loc) => {
|
||||||
if Some(&loc) == self.dnd_hovered.as_ref().map(|(l, _)| l) {
|
if Some(&loc) == self.dnd_hovered.as_ref().map(|(l, _)| l) {
|
||||||
|
|
@ -2459,24 +2449,6 @@ impl Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update preview timer
|
|
||||||
//TODO: make this configurable
|
|
||||||
if last_select_focus != self.select_focus {
|
|
||||||
if let Some(index) = self.select_focus {
|
|
||||||
if let Some(ref items) = self.items_opt {
|
|
||||||
if let Some(item) = items.get(index) {
|
|
||||||
if let Some(location) = item.location_opt.clone() {
|
|
||||||
// Show preview after double click timeout
|
|
||||||
commands.push(Command::Preview(
|
|
||||||
PreviewKind::Location(location),
|
|
||||||
DOUBLE_CLICK_DURATION,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scroll to top if needed
|
// Scroll to top if needed
|
||||||
if self.scroll_opt.is_none() {
|
if self.scroll_opt.is_none() {
|
||||||
let offset = AbsoluteOffset { x: 0.0, y: 0.0 };
|
let offset = AbsoluteOffset { x: 0.0, y: 0.0 };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue