diff --git a/generator/Cargo.lock b/generator/Cargo.lock index 4ddf073..4e8f5aa 100644 --- a/generator/Cargo.lock +++ b/generator/Cargo.lock @@ -357,6 +357,7 @@ dependencies = [ "arboard", "cosmic-text", "nvim-oxi", + "regex", "serde", "syntect", "thiserror", diff --git a/generator/Cargo.toml b/generator/Cargo.toml index c322df6..0c9e20e 100644 --- a/generator/Cargo.toml +++ b/generator/Cargo.toml @@ -11,6 +11,7 @@ cosmic-text = "0.11.2" serde = "1.0.197" arboard = "3.3.2" thiserror = "1.0.58" +regex = "1.10.3" [lib] crate-type = ["cdylib"] diff --git a/generator/src/components/editor.rs b/generator/src/components/editor.rs index 57bcb66..865586a 100644 --- a/generator/src/components/editor.rs +++ b/generator/src/components/editor.rs @@ -1,121 +1,2 @@ pub mod code; pub mod mac_title_bar; - -use crate::edges::{edge::Edge, padding::Padding}; - -use self::{code::Code, mac_title_bar::MacTitleBar}; -use super::{interface::component::Component, rect::Rect}; - -const CONTROL_BAR_RADIUS: f32 = 8.; - -pub struct Editor { - x: f32, - y: f32, - w: f32, - h: f32, - children: Vec>, - has_title_bar: bool, - padding: Padding, - code_y_offset: f32, -} - -impl Component for Editor { - fn children(&self) -> &Vec> { - &self.children - } - - // fn get_children(&self) -> &Vec> { - // &self.children - // } -} - -impl Editor { - pub fn new(x: f32, y: f32, w: f32, h: f32, has_title_bar: bool) -> Editor { - Editor { - x, - y, - w, - h, - has_title_bar, - padding: Padding { - left: 0., - right: 0., - top: 0., - bottom: 0., - }, - children: vec![], - code_y_offset: 0., - } - } - - // pub fn render_mac_title_bar(mut self) -> Self { - // if self.has_title_bar { - // let mac_title_bar = MacTitleBar::from_xyr( - // self.x + CONTROL_BAR_RADIUS + self.padding.left, - // self.y + CONTROL_BAR_RADIUS + self.padding.top, - // CONTROL_BAR_RADIUS, - // ); - // - // self.children.push(Box::new(mac_title_bar)); - // } - // - // self - // } - - // pub fn render_editor(mut self, radius: f32) -> Self { - // let roundrect = Rect::from_xywh( - // self.x, - // self.y, - // self.w + self.padding.horizontal(), - // self.h + self.header_height() + self.padding.vertical() + self.code_y_offset, - // ) - // .radius(radius); - // self.children.push(Box::new(roundrect)); - // - // self - // } - - pub fn width(&self) -> f32 { - self.w + self.padding.horizontal() - } - - pub fn height(&self) -> f32 { - self.h + self.header_height() + self.padding.vertical() + self.code_y_offset - } - - pub fn header_height(&self) -> f32 { - if self.has_title_bar { - CONTROL_BAR_RADIUS * 2. - } else { - 0. - } - } - - // pub fn render_code(mut self, code: &str, line_height: f32, font_size: f32) -> Self { - // let code = Code::new( - // self.x + self.padding.left, - // self.y + self.header_height() + self.padding.top + self.code_y_offset, - // self.w, - // self.h, - // code.to_string(), - // ) - // .line_height(line_height) - // .font_size(font_size); - // - // self.children.push(Box::new(code)); - // self - // } - - pub fn padding(mut self, padding: Padding) -> Self { - self.padding = padding; - self - } - - pub fn code_y_offset(mut self, code_y_offset: f32) -> Self { - if self.has_title_bar { - self.code_y_offset = code_y_offset; - } - - self - } -} diff --git a/generator/src/components/interface/component.rs b/generator/src/components/interface/component.rs index 01772cf..5461377 100644 --- a/generator/src/components/interface/component.rs +++ b/generator/src/components/interface/component.rs @@ -2,10 +2,7 @@ use std::sync::Arc; use tiny_skia::Pixmap; -use crate::{ - config::TakeSnapshotParams, - edges::{edge::Edge, padding::Padding}, -}; +use crate::{config::TakeSnapshotParams, edges::edge::Edge}; use super::{ render_error, diff --git a/generator/src/components/rect.rs b/generator/src/components/rect.rs index 80304ac..2fdc489 100644 --- a/generator/src/components/rect.rs +++ b/generator/src/components/rect.rs @@ -3,7 +3,7 @@ use crate::edges::padding::Padding; use super::interface::{ component::{Component, ComponentContext, RenderParams}, render_error, - style::{ComponentAlign, ComponentStyle, RawComponentStyle, Size, Style}, + style::{ComponentAlign, ComponentStyle, RawComponentStyle, Style}, }; use tiny_skia::{FillRule, Paint, PathBuilder, Pixmap, Transform}; diff --git a/generator/src/components/watermark.rs b/generator/src/components/watermark.rs index 0e27e1f..8007413 100644 --- a/generator/src/components/watermark.rs +++ b/generator/src/components/watermark.rs @@ -11,7 +11,7 @@ use super::interface::{ pub struct Watermark { children: Vec>, - value: Option, + value: String, } impl Component for Watermark { @@ -24,7 +24,7 @@ impl Component for Watermark { ) -> render_error::Result<()> { let params = &context.take_snapshot_params; - if let Some(value) = ¶ms.watermark { + if ¶ms.watermark != "" { let attrs = Attrs::new().family(Family::Name( &context.take_snapshot_params.watermark_font_family, )); @@ -40,7 +40,7 @@ impl Component for Watermark { render_params.y, pixmap.width() as f32, pixmap.height() as f32, - &value, + ¶ms.watermark, attrs, Some(Align::Center), pixmap, @@ -57,7 +57,7 @@ impl Component for Watermark { fn style(&self) -> RawComponentStyle { let default_style = RawComponentStyle::default(); - if self.value.is_some() { + if self.value != "" { default_style.margin(Margin { bottom: 22., top: 15., @@ -70,7 +70,7 @@ impl Component for Watermark { } impl Watermark { - pub fn new(value: Option) -> Watermark { + pub fn new(value: String) -> Watermark { Watermark { children: vec![], value, diff --git a/generator/src/config.rs b/generator/src/config.rs index 783dc8f..b55d50a 100644 --- a/generator/src/config.rs +++ b/generator/src/config.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone)] pub struct TakeSnapshotParams { pub mac_window_bar: bool, - pub watermark: Option, + pub watermark: String, pub title: Option, pub code_font_family: String, pub watermark_font_family: String, diff --git a/generator/src/lib.rs b/generator/src/lib.rs index 1df789d..7670d56 100644 --- a/generator/src/lib.rs +++ b/generator/src/lib.rs @@ -4,6 +4,7 @@ mod config; mod copy; mod edges; mod highlight; +mod path; mod save; mod snapshot; mod text; diff --git a/generator/src/path.rs b/generator/src/path.rs new file mode 100644 index 0000000..33d5164 --- /dev/null +++ b/generator/src/path.rs @@ -0,0 +1,10 @@ +use regex::Regex; +use std::env::{var, VarError}; + +pub fn parse_save_path(path: String) -> Result { + let home_path = var("HOME")?; + let regex = Regex::new(r"(~|$HOME)").unwrap(); + let path = regex.replace_all(&path, home_path); + + Ok(path.to_string()) +} diff --git a/generator/src/save.rs b/generator/src/save.rs index 825f8bc..9ccabdc 100644 --- a/generator/src/save.rs +++ b/generator/src/save.rs @@ -1,16 +1,24 @@ -use crate::{config::TakeSnapshotParams, snapshot::take_snapshot}; -use nvim_oxi::{lua, Result}; +use crate::{config::TakeSnapshotParams, path::parse_save_path, snapshot::take_snapshot}; +use nvim_oxi::{lua::Error::RuntimeError, Error, Result}; pub fn save_snapshot(config: TakeSnapshotParams) -> Result<()> { match &config.save_path { Some(path) => { + if !path.ends_with(".png") { + return Err(Error::Lua(RuntimeError( + "The save_path must ends with .png".to_string(), + ))); + } + let pixmap = take_snapshot(config.clone())?; + let path = parse_save_path(path.to_string()) + .map_err(|err| Error::Lua(RuntimeError(err.to_string())))?; pixmap .save_png(path) - .map_err(|err| nvim_oxi::Error::Lua(lua::Error::RuntimeError(err.to_string()))) + .map_err(|err| Error::Lua(RuntimeError(err.to_string()))) } - None => Err(nvim_oxi::Error::Lua(lua::Error::RuntimeError( + None => Err(Error::Lua(RuntimeError( "Cannot find 'save_path' in config".to_string(), ))), } diff --git a/generator/src/snapshot.rs b/generator/src/snapshot.rs index 8bd73a8..3c984c4 100644 --- a/generator/src/snapshot.rs +++ b/generator/src/snapshot.rs @@ -6,74 +6,21 @@ use crate::components::background::Background; use crate::components::container::Container; use crate::components::editor::code::Code; use crate::components::editor::mac_title_bar::MacTitleBar; -// use crate::components::editor::mac_title_bar::MacTitleBar; +use crate::components::interface::component::ComponentContext; use crate::components::interface::render_error; use crate::components::rect::Rect; use crate::components::watermark::Watermark; -// use crate::components::watermark::Watermark; use crate::config::TakeSnapshotParams; -use crate::{ - code::calc_wh, - components::interface::component::{Component, ComponentContext}, -}; // Scale the screenshot to 3 times its size const SCALE_FACTOR: f32 = 3.; // The params is come from neovim instance pub fn take_snapshot(params: TakeSnapshotParams) -> render_error::Result { - // let (width, height) = calc_wh(¶ms.code, 9.05, 20.); - // let pixmap_vertical_padding = 82.; - // let pixmap_horizontal_padding = 122.; - // // Padding of editor shape - // let padding = Padding { - // left: 20., - // right: 20., - // top: 20., - // bottom: 24., - // }; - - // let editor = Editor::new( - // pixmap_horizontal_padding, - // pixmap_vertical_padding, - // width, - // height, - // params.mac_window_bar, - // ) - // .code_y_offset(15.) - // .padding(padding.clone()) - // .render_editor(16.) - // .render_mac_title_bar() - // .render_code(¶ms.code, 20., 15.); - - // let pixmap_width = (pixmap_horizontal_padding * 2. + editor.width()) as u32; - // let pixmap_height = (pixmap_vertical_padding * 2. + editor.height()) as u32; - // let (watermark_bottom_margin, watermark_offset_y) = params - // .watermark - // .as_ref() - // .map(|_| (200., 40.)) - // .unwrap_or((0., 0.)); - // - // let mut pixmap = Pixmap::new( - // 0, - // 0, // pixmap_width * SCALE_FACTOR as u32, - // // (pixmap_height as f32 * SCALE_FACTOR + watermark_bottom_margin - watermark_offset_y) as u32, - // ) - // .unwrap(); - // .unwrap(); let context = ComponentContext { scale_factor: SCALE_FACTOR, take_snapshot_params: Arc::new(params.clone()), }; - // let watermark = Watermark::new( - // params.watermark, - // params.watermark_font_family, - // watermark_bottom_margin, - // ); - // let background = Background::create().children(vec![Box::new(editor), Box::new(watermark)]); - // - // background.draw_root(&mut pixmap, &context)?; - // let pixmap = Container::from_children(vec![Box::new(Background::from_children(vec![ Box::new(Rect::new( 16.,