Let the sidebar divider be dragged
This commit is contained in:
44
src/app.rs
44
src/app.rs
@@ -25,7 +25,7 @@ use crate::settings::{
|
||||
StreamingCacheBudget,
|
||||
};
|
||||
use iced::widget::{markdown, scrollable, text_input};
|
||||
use iced::{Size, Subscription, Task, keyboard, window};
|
||||
use iced::{Size, Subscription, Task, keyboard, mouse, window};
|
||||
use rfd::AsyncFileDialog;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::fs;
|
||||
@@ -38,6 +38,8 @@ use std::time::{Duration, Instant};
|
||||
|
||||
const APP_ID: &str = "de.rfc1437.ds4server";
|
||||
const METRICS_SAMPLE_INTERVAL: Duration = Duration::from_millis(200);
|
||||
pub(super) const MIN_SIDEBAR_WIDTH: i32 = 180;
|
||||
pub(super) const MAX_SIDEBAR_WIDTH: i32 = 520;
|
||||
|
||||
pub(crate) struct App {
|
||||
main_window: window::Id,
|
||||
@@ -64,6 +66,8 @@ pub(crate) struct App {
|
||||
session_rename: Option<(i32, String)>,
|
||||
/// Projects whose archived sessions are expanded in the sidebar.
|
||||
expanded_archives: HashSet<i32>,
|
||||
/// True while the sidebar divider is being dragged.
|
||||
sidebar_drag: bool,
|
||||
choosing_folder: bool,
|
||||
pending_project_path: Option<PathBuf>,
|
||||
project_name_input: String,
|
||||
@@ -194,6 +198,9 @@ pub(crate) enum Message {
|
||||
ShowChat,
|
||||
ShowStats,
|
||||
ToggleSidebar,
|
||||
StartSidebarDrag,
|
||||
DragSidebar(f32),
|
||||
EndSidebarDrag,
|
||||
MetricsTick,
|
||||
}
|
||||
|
||||
@@ -242,6 +249,7 @@ impl App {
|
||||
session_menu: None,
|
||||
session_rename: None,
|
||||
expanded_archives: HashSet::new(),
|
||||
sidebar_drag: false,
|
||||
choosing_folder: false,
|
||||
pending_project_path: None,
|
||||
project_name_input: String::new(),
|
||||
@@ -323,6 +331,7 @@ impl App {
|
||||
session_menu: None,
|
||||
session_rename: None,
|
||||
expanded_archives: HashSet::new(),
|
||||
sidebar_drag: false,
|
||||
choosing_folder: false,
|
||||
pending_project_path: None,
|
||||
project_name_input: String::new(),
|
||||
@@ -414,6 +423,26 @@ impl App {
|
||||
}
|
||||
Message::ShowChat => self.detail_tab = DetailTab::Chat,
|
||||
Message::ShowStats => self.detail_tab = DetailTab::Stats,
|
||||
// The sidebar starts at the window's left edge, so the cursor's x is
|
||||
// the width the user is asking for. Only the final width is stored.
|
||||
Message::StartSidebarDrag => self.sidebar_drag = true,
|
||||
Message::DragSidebar(x) => {
|
||||
if self.sidebar_drag {
|
||||
self.preferences.sidebar_width =
|
||||
(x.round() as i32).clamp(MIN_SIDEBAR_WIDTH, MAX_SIDEBAR_WIDTH);
|
||||
}
|
||||
}
|
||||
Message::EndSidebarDrag => {
|
||||
if self.sidebar_drag {
|
||||
self.sidebar_drag = false;
|
||||
if let Some(database) = self.database.as_mut()
|
||||
&& let Err(error) =
|
||||
database.set_sidebar_width(self.preferences.sidebar_width)
|
||||
{
|
||||
self.error = Some(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::ToggleSidebar => {
|
||||
let collapsed = !self.preferences.sidebar_collapsed;
|
||||
self.preferences.sidebar_collapsed = collapsed;
|
||||
@@ -969,6 +998,19 @@ impl App {
|
||||
iced::time::every(Duration::from_millis(50)).map(|_| Message::GenerationTick),
|
||||
);
|
||||
}
|
||||
// The cursor leaves the thin divider as soon as it moves, so the drag is
|
||||
// followed through raw window events instead of the widget.
|
||||
if self.sidebar_drag {
|
||||
subscriptions.push(iced::event::listen_with(|event, _, _| match event {
|
||||
iced::Event::Mouse(mouse::Event::CursorMoved { position }) => {
|
||||
Some(Message::DragSidebar(position.x))
|
||||
}
|
||||
iced::Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {
|
||||
Some(Message::EndSidebarDrag)
|
||||
}
|
||||
_ => None,
|
||||
}));
|
||||
}
|
||||
Subscription::batch(subscriptions)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user