From 69ea3f0216fceeaf72f2a01ff4bbec804ccbc761 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 18 May 2023 19:35:16 +0100 Subject: [PATCH] add zoom in/out --- Cargo.lock | 6 +-- defaults/keymaps-macos.toml | 8 +++ defaults/keymaps-nonmacos.toml | 8 +++ lapce-app/Cargo.toml | 2 +- lapce-app/src/app.rs | 96 +++++++++++++++++++--------------- lapce-app/src/command.rs | 15 ++++++ lapce-app/src/window.rs | 8 ++- lapce-app/src/window_tab.rs | 25 +++++++++ 8 files changed, 122 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 958bea9a..2824c4ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1615,7 +1615,7 @@ dependencies = [ [[package]] name = "floem" version = "0.1.0" -source = "git+https://github.com/lapce/floem?rev=f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0#f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0" +source = "git+https://github.com/lapce/floem?rev=dfc4191e4860859b2da77693362bc08e027f4877#dfc4191e4860859b2da77693362bc08e027f4877" dependencies = [ "bitflags 2.2.1", "crossbeam-channel", @@ -1643,7 +1643,7 @@ dependencies = [ [[package]] name = "floem_renderer" version = "0.1.0" -source = "git+https://github.com/lapce/floem?rev=f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0#f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0" +source = "git+https://github.com/lapce/floem?rev=dfc4191e4860859b2da77693362bc08e027f4877#dfc4191e4860859b2da77693362bc08e027f4877" dependencies = [ "cosmic-text", "peniko", @@ -1653,7 +1653,7 @@ dependencies = [ [[package]] name = "floem_vger" version = "0.1.0" -source = "git+https://github.com/lapce/floem?rev=f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0#f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0" +source = "git+https://github.com/lapce/floem?rev=dfc4191e4860859b2da77693362bc08e027f4877#dfc4191e4860859b2da77693362bc08e027f4877" dependencies = [ "anyhow", "floem_renderer", diff --git a/defaults/keymaps-macos.toml b/defaults/keymaps-macos.toml index 7b562557..a9318f5b 100644 --- a/defaults/keymaps-macos.toml +++ b/defaults/keymaps-macos.toml @@ -31,6 +31,14 @@ command = "open_keyboard_shortcuts" # key = "meta+q" # command = "quit" +[[keymaps]] +key = "meta+=" +command = "zoom_in" + +[[keymaps]] +key = "meta+-" +command = "zoom_out" + # --------------------------------- Basic editing --------------------------------------- [[keymaps]] diff --git a/defaults/keymaps-nonmacos.toml b/defaults/keymaps-nonmacos.toml index b89b3389..03de123b 100644 --- a/defaults/keymaps-nonmacos.toml +++ b/defaults/keymaps-nonmacos.toml @@ -27,6 +27,14 @@ command = "open_settings" key = "ctrl+k ctrl+s" command = "open_keyboard_shortcuts" +[[keymaps]] +key = "ctrl+=" +command = "zoom_in" + +[[keymaps]] +key = "ctrl+-" +command = "zoom_out" + # --------------------------------- Terminal copy/paste --------------------------------- [[keymaps]] diff --git a/lapce-app/Cargo.toml b/lapce-app/Cargo.toml index 14597a76..4048c9a9 100644 --- a/lapce-app/Cargo.toml +++ b/lapce-app/Cargo.toml @@ -37,7 +37,7 @@ fuzzy-matcher = "0.3.7" sled = "0.34.7" tokio = { version = "1.21", features = ["full"] } futures = "0.3.26" -floem = { git = "https://github.com/lapce/floem", rev = "f4d6c0a9721f306bbee58bbbb3b1148d6043b8e0" } +floem = { git = "https://github.com/lapce/floem", rev = "dfc4191e4860859b2da77693362bc08e027f4877" } # floem = { path = "../../workspaces/floem" } config = { version = "0.13.2", default-features = false, features = ["toml"] } structdesc = { git = "https://github.com/lapce/structdesc" } diff --git a/lapce-app/src/app.rs b/lapce-app/src/app.rs index 8b23c56c..5e847f87 100644 --- a/lapce-app/src/app.rs +++ b/lapce-app/src/app.rs @@ -19,7 +19,7 @@ }, view::View, views::{ - container, container_box, label, list, scroll, stack, svg, tab, + container, container_box, empty, label, list, scroll, stack, svg, tab, virtual_list, Decorators, VirtualListDirection, VirtualListItemSize, VirtualListVector, }, @@ -73,6 +73,7 @@ pub struct AppInfo { #[derive(Clone)] pub struct AppData { pub windows: RwSignal>, + pub window_scale: RwSignal, } fn editor_tab_header( @@ -107,6 +108,7 @@ fn editor_tab_header( let view_fn = move |(i, child): (RwSignal, EditorTabChild)| { let local_child = child.clone(); + let child_for_close = child.clone(); let child_view = move || match child { EditorTabChild::Editor(editor_id) => { #[derive(PartialEq)] @@ -199,38 +201,30 @@ struct Info { ) }, ), - container(|| { - svg(move || { - config.get().ui_svg( - if info.with(|info| info.is_pristine) { - LapceIcons::CLOSE - } else { - LapceIcons::UNSAVED + clickable_icon( + move || { + if info.with(|info| info.is_pristine) { + LapceIcons::CLOSE + } else { + LapceIcons::UNSAVED + } + }, + move || { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.set(Some( + InternalCommand::EditorTabChildClose { + editor_tab_id, + child: child_for_close.clone(), }, - ) - }) - .style(move || { - let config = config.get(); - let size = config.ui.icon_size() as f32; - Style::BASE.size_px(size, size).color( - *config.get_color(LapceColor::LAPCE_ICON_ACTIVE), - ) - }) - }) - .style(|| { - Style::BASE - .border_radius(6.0) - .padding_px(4.0) - .margin_horiz_px(6.0) - .cursor(CursorStyle::Pointer) - }) - .hover_style(move || { - Style::BASE.background( - *config - .get() - .get_color(LapceColor::PANEL_HOVERED_BACKGROUND), - ) - }), + )); + }, + || false, + || false, + config, + ) + .on_event(EventListner::PointerDown, |_| true) + .style(|| Style::BASE.margin_horiz_px(6.0)), ) }) .style(move || { @@ -262,7 +256,7 @@ struct Info { } true }) - .on_click(move |_| { + .on_event(EventListner::PointerDown, move |_| { editor_tab.update(|editor_tab| { editor_tab.active = i.get_untracked(); }); @@ -274,7 +268,7 @@ struct Info { .height_pct(100.0) }), container(|| { - label(|| "".to_string()).style(move || { + empty().style(move || { Style::BASE .size_pct(100.0, 100.0) .border_bottom(if active() == i.get() { @@ -352,8 +346,20 @@ struct Info { config, ) .style(|| Style::BASE.margin_left_px(6.0)), - clickable_icon(|| LapceIcons::CLOSE, || {}, || false, || false, config) - .style(|| Style::BASE.margin_horiz_px(6.0)), + clickable_icon( + || LapceIcons::CLOSE, + move || { + let editor_tab_id = + editor_tab.with_untracked(|t| t.editor_tab_id); + internal_command.set(Some(InternalCommand::EditorTabClose { + editor_tab_id, + })); + }, + || false, + || false, + config, + ) + .style(|| Style::BASE.margin_horiz_px(6.0)), ) }) .style(move || { @@ -2143,6 +2149,7 @@ fn app_view(cx: AppContext, window_data: WindowData) -> impl View { // let window_data = WindowData::new(cx); let window_size = window_data.size; let position = window_data.position; + let window_scale = window_data.window_scale; stack(|| { ( workspace_tab_header(window_data.clone()), @@ -2150,6 +2157,7 @@ fn app_view(cx: AppContext, window_data: WindowData) -> impl View { ) }) .style(|| Style::BASE.flex_col().size_pct(100.0, 100.0)) + .window_scale(move || window_scale.get()) .on_event(EventListner::KeyDown, move |event| { if let Event::KeyDown(key_event) = event { window_data.key_down(key_event); @@ -2216,12 +2224,17 @@ pub fn launch() { let scope = app.scope(); provide_context(scope, db.clone()); + let window_scale = create_rw_signal(scope, 1.0); + let mut windows = im::Vector::new(); - app = create_windows(scope, db.clone(), app, paths, &mut windows); + app = create_windows(scope, db.clone(), app, paths, &mut windows, window_scale); let windows = create_rw_signal(scope, windows); - let app_data = AppData { windows }; + let app_data = AppData { + windows, + window_scale, + }; app.on_event(move |event| match event { floem::AppEvent::WillTerminate => { @@ -2237,6 +2250,7 @@ fn create_windows( mut app: floem::Application, paths: Vec, windows: &mut im::Vector, + window_scale: RwSignal, ) -> floem::Application { let dirs: Vec<&PathBuf> = paths.iter().filter(|p| p.is_dir()).collect(); let files: Vec<&PathBuf> = paths.iter().filter(|p| p.is_file()).collect(); @@ -2280,7 +2294,7 @@ fn create_windows( pos += (50.0, 50.0); let config = WindowConfig::default().size(info.size).position(info.pos); - let window_data = WindowData::new(scope, info); + let window_data = WindowData::new(scope, info, window_scale); windows.push_back(window_data.clone()); app = app.window(move |cx| app_view(cx, window_data), Some(config)); } @@ -2290,7 +2304,7 @@ fn create_windows( for info in app_info.windows { let config = WindowConfig::default().size(info.size).position(info.pos); - let window_data = WindowData::new(scope, info); + let window_data = WindowData::new(scope, info, window_scale); windows.push_back(window_data.clone()); app = app.window(move |cx| app_view(cx, window_data), Some(config)); } @@ -2308,7 +2322,7 @@ fn create_windows( }, }); let config = WindowConfig::default().size(info.size).position(info.pos); - let window_data = WindowData::new(scope, info); + let window_data = WindowData::new(scope, info, window_scale); windows.push_back(window_data.clone()); app = app.window(|cx| app_view(cx, window_data), Some(config)); } diff --git a/lapce-app/src/command.rs b/lapce-app/src/command.rs index efccd272..d8c05a6c 100644 --- a/lapce-app/src/command.rs +++ b/lapce-app/src/command.rs @@ -204,6 +204,18 @@ pub enum LapceWorkbenchCommand { #[strum(message = "Open Plugins Directory")] OpenPluginsDirectory, + #[strum(serialize = "zoom_in")] + #[strum(message = "Zoom In")] + ZoomIn, + + #[strum(serialize = "zoom_out")] + #[strum(message = "Zoom Out")] + ZoomOut, + + #[strum(serialize = "zoom_reset")] + #[strum(message = "Reset Zoom")] + ZoomReset, + #[strum(serialize = "close_window_tab")] #[strum(message = "Close Current Window Tab")] CloseWindowTab, @@ -512,6 +524,9 @@ pub enum InternalCommand { SplitTerminalExchange { term_id: TermId, }, + EditorTabClose { + editor_tab_id: EditorTabId, + }, EditorTabChildClose { editor_tab_id: EditorTabId, child: EditorTabChild, diff --git a/lapce-app/src/window.rs b/lapce-app/src/window.rs index 536ab59e..d243b051 100644 --- a/lapce-app/src/window.rs +++ b/lapce-app/src/window.rs @@ -50,11 +50,12 @@ pub struct WindowData { pub size: RwSignal, pub position: RwSignal, pub root_view_id: RwSignal, + pub window_scale: RwSignal, pub config: RwSignal>, } impl WindowData { - pub fn new(cx: Scope, info: WindowInfo) -> Self { + pub fn new(cx: Scope, info: WindowInfo, window_scale: RwSignal) -> Self { let config = LapceConfig::load(&LapceWorkspace::default(), &[]); let config = create_rw_signal(cx, Arc::new(config)); let root_view_id = create_rw_signal(cx, floem::id::Id::next()); @@ -69,6 +70,7 @@ pub fn new(cx: Scope, info: WindowInfo) -> Self { cx, Arc::new(w), window_command.write_only(), + window_scale, )); window_tabs.push_back((create_rw_signal(cx, 0), window_tab)); } @@ -78,6 +80,7 @@ pub fn new(cx: Scope, info: WindowInfo) -> Self { cx, Arc::new(LapceWorkspace::default()), window_command.write_only(), + window_scale, )); window_tabs.push_back((create_rw_signal(cx, 0), window_tab)); } @@ -95,6 +98,7 @@ pub fn new(cx: Scope, info: WindowInfo) -> Self { size, position, root_view_id, + window_scale, config, }; @@ -118,6 +122,7 @@ pub fn run_window_command(&self, cmd: WindowCommand) { self.scope, Arc::new(workspace), self.window_command.write_only(), + self.window_scale, )); let active = self.active.get_untracked(); self.window_tabs.update(|window_tabs| { @@ -138,6 +143,7 @@ pub fn run_window_command(&self, cmd: WindowCommand) { self.scope, Arc::new(workspace), self.window_command.write_only(), + self.window_scale, )); let active = self.active.get_untracked(); let active = self diff --git a/lapce-app/src/window_tab.rs b/lapce-app/src/window_tab.rs index 8a07dd4a..3b54b91a 100644 --- a/lapce-app/src/window_tab.rs +++ b/lapce-app/src/window_tab.rs @@ -100,6 +100,7 @@ pub struct WindowTabData { pub window_origin: RwSignal, pub layout_rect: RwSignal, pub proxy: ProxyData, + pub window_scale: RwSignal, pub common: CommonData, } @@ -135,6 +136,7 @@ pub fn new( cx: Scope, workspace: Arc, window_command: WriteSignal>, + window_scale: RwSignal, ) -> Self { let db: Arc = use_context(cx).unwrap(); @@ -305,6 +307,7 @@ pub fn new( window_origin: create_rw_signal(cx, Point::ZERO), layout_rect: create_rw_signal(cx, Rect::ZERO), proxy, + window_scale, common, }; @@ -413,6 +416,25 @@ pub fn run_workbench_command( OpenProxyDirectory => {} OpenThemesDirectory => {} OpenPluginsDirectory => {} + ZoomIn => { + let mut scale = self.window_scale.get_untracked(); + scale += 0.1; + if scale > 4.0 { + scale = 4.0 + } + self.window_scale.set(scale); + } + ZoomOut => { + let mut scale = self.window_scale.get_untracked(); + scale -= 0.1; + if scale < 0.1 { + scale = 0.1 + } + self.window_scale.set(scale); + } + ZoomReset => { + self.window_scale.set(1.0); + } NewWindowTab => { self.common.window_command.set(Some( WindowCommand::NewWorkspaceTab { @@ -682,6 +704,9 @@ pub fn run_internal_command(&self, cmd: InternalCommand) { InternalCommand::SplitExchange { editor_tab_id } => { self.main_split.split_exchange(cx, editor_tab_id); } + InternalCommand::EditorTabClose { editor_tab_id } => { + self.main_split.editor_tab_close(cx, editor_tab_id); + } InternalCommand::EditorTabChildClose { editor_tab_id, child,