From 794f47a601878936ffe3123a8e447a65d255f651 Mon Sep 17 00:00:00 2001 From: Adrian Wozniak Date: Mon, 27 May 2019 21:52:55 +0200 Subject: [PATCH] Add save button --- .gitignore | 1 - README.md | 4 +- rider-editor/src/app/app_state.rs | 3 +- rider-editor/src/ui/menu_bar.rs | 42 +++++-- rider-editor/src/ui/mod.rs | 2 + rider-editor/src/ui/save_button.rs | 106 ++++++++++++++++++ .../themes/default/images/save-48x84.png | Bin 0 -> 1515 bytes .../themes/default/images/save-512x512.png | Bin 0 -> 3696 bytes .../themes/default/images/save-64x64.png | Bin 0 -> 1598 bytes .../themes/railscasts/images/save-48x84.png | Bin 0 -> 1515 bytes .../themes/railscasts/images/save-512x512.png | Bin 0 -> 3696 bytes .../themes/railscasts/images/save-64x64.png | Bin 0 -> 1598 bytes rider-generator/src/images.rs | 7 ++ rider-themes/src/images.rs | 22 +++- rider-themes/src/predef/railscasts.rs | 1 + 15 files changed, 174 insertions(+), 14 deletions(-) create mode 100644 rider-editor/src/ui/save_button.rs create mode 100644 rider-generator/assets/themes/default/images/save-48x84.png create mode 100644 rider-generator/assets/themes/default/images/save-512x512.png create mode 100644 rider-generator/assets/themes/default/images/save-64x64.png create mode 100644 rider-generator/assets/themes/railscasts/images/save-48x84.png create mode 100644 rider-generator/assets/themes/railscasts/images/save-512x512.png create mode 100644 rider-generator/assets/themes/railscasts/images/save-64x64.png diff --git a/.gitignore b/.gitignore index a9591cd..6892901 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,3 @@ log .codecov cobertura.xml cov - diff --git a/README.md b/README.md index b0ffaea..01dee9a 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ rustup run nightly cargo run -p rider-editor * [x] Handle caret movement with arrow keys * [x] Add text content * [x] Open file menu -* [ ] `Save file` with button -* [ ] `Save file` with shortcut +* [x] `Save file` with button +* [x] `Save file` with shortcut * [ ] `Save file as...` with shortcut * [x] Theme based menu UI * [x] Lock scroll when no available content diff --git a/rider-editor/src/app/app_state.rs b/rider-editor/src/app/app_state.rs index b7a63f7..fcedc8b 100644 --- a/rider-editor/src/app/app_state.rs +++ b/rider-editor/src/app/app_state.rs @@ -113,7 +113,8 @@ impl AppState { self.file_editor.render(canvas, renderer); // menu bar - self.menu_bar.render(canvas, &RenderContext::Nothing); + self.menu_bar + .render(canvas, renderer, &RenderContext::Nothing); // project tree self.project_tree.render(canvas, renderer); diff --git a/rider-editor/src/ui/menu_bar.rs b/rider-editor/src/ui/menu_bar.rs index ac8fd03..d1c9e80 100644 --- a/rider-editor/src/ui/menu_bar.rs +++ b/rider-editor/src/ui/menu_bar.rs @@ -1,14 +1,19 @@ use crate::app::UpdateResult as UR; +use crate::renderer::Renderer; use crate::ui::*; use rider_config::ConfigAccess; use sdl2::pixels::Color; use sdl2::rect::{Point, Rect}; +const SAVE_BUTTON_OFFSET_LEFT: i32 = 16; +const SAVE_BUTTON_OFFSET_TOP: i32 = 16; + pub struct MenuBar { border_color: Color, background_color: Color, dest: Rect, config: ConfigAccess, + save_button: SaveButton, } impl MenuBar { @@ -26,6 +31,7 @@ impl MenuBar { border_color, background_color, dest: Rect::new(0, 0, w as u32, h as u32), + save_button: SaveButton::new(config.clone()), config, } } @@ -34,19 +40,22 @@ impl MenuBar { &self.background_color } - pub fn render(&self, canvas: &mut C, context: &RenderContext) + pub fn render(&self, canvas: &mut C, renderer: &mut R, context: &RenderContext) where C: CanvasAccess, + R: Renderer, { use std::borrow::*; + let relative_position = match context.borrow() { + RenderContext::RelativePosition(p) => p.clone(), + _ => Point::new(0, 0), + }; + canvas.set_clipping(self.dest.clone()); canvas .render_rect( - match context.borrow() { - RenderContext::RelativePosition(p) => move_render_point(p.clone(), &self.dest), - _ => self.dest(), - }, + move_render_point(relative_position.clone(), &self.dest), self.background_color.clone(), ) .unwrap_or_else(|_| panic!("Failed to draw main menu background")); @@ -61,6 +70,11 @@ impl MenuBar { self.border_color.clone(), ) .unwrap_or_else(|_| panic!("Failed to draw main menu background")); + + let context = RenderContext::RelativePosition( + relative_position.offset(SAVE_BUTTON_OFFSET_LEFT, SAVE_BUTTON_OFFSET_TOP), + ); + self.save_button.render(canvas, renderer, &context); } pub fn prepare_ui(&mut self) { @@ -79,7 +93,19 @@ impl Update for MenuBar { } impl ClickHandler for MenuBar { - fn on_left_click(&mut self, _point: &Point, _context: &UpdateContext) -> UR { + fn on_left_click(&mut self, point: &Point, context: &UpdateContext) -> UR { + use std::borrow::*; + + let relative_position = match context.borrow() { + UpdateContext::ParentPosition(p) => p.clone(), + _ => Point::new(0, 0), + }; + let context = UpdateContext::ParentPosition( + relative_position.offset(SAVE_BUTTON_OFFSET_LEFT, SAVE_BUTTON_OFFSET_TOP), + ); + if self.save_button.is_left_click_target(point, &context) { + return self.save_button.on_left_click(point, &context); + } UR::NoOp } @@ -218,6 +244,7 @@ mod test_click_handler { #[cfg(test)] mod test_render { + use crate::tests::support::SimpleRendererMock; use crate::tests::*; use crate::ui::*; use sdl2::pixels::Color; @@ -277,9 +304,10 @@ mod test_render { border_rect: Rect::new(0, 0, 0, 0), border_color: Color::RGB(0, 0, 0), }; + let mut renderer = SimpleRendererMock::new(config.clone()); let mut widget = MenuBar::new(Arc::clone(&config)); widget.prepare_ui(); - widget.render(&mut canvas, &context); + widget.render(&mut canvas, &mut renderer, &context); assert_eq!(widget.dest(), Rect::new(0, 0, 1024, 60)); let expected = CanvasMock { clipping: Rect::new(0, 0, 1024, 60), diff --git a/rider-editor/src/ui/mod.rs b/rider-editor/src/ui/mod.rs index 3d7d19e..1993988 100644 --- a/rider-editor/src/ui/mod.rs +++ b/rider-editor/src/ui/mod.rs @@ -15,6 +15,7 @@ pub mod filesystem; pub mod menu_bar; pub mod modal; pub mod project_tree; +pub mod save_button; pub mod scroll_bar; pub mod text_character; @@ -25,6 +26,7 @@ pub use crate::ui::filesystem::*; pub use crate::ui::menu_bar::*; pub use crate::ui::modal::*; pub use crate::ui::project_tree::*; +pub use crate::ui::save_button::*; pub use crate::ui::scroll_bar::*; pub use crate::ui::text_character::*; diff --git a/rider-editor/src/ui/save_button.rs b/rider-editor/src/ui/save_button.rs new file mode 100644 index 0000000..2834fd4 --- /dev/null +++ b/rider-editor/src/ui/save_button.rs @@ -0,0 +1,106 @@ +use crate::app::{ConfigAccess, ConfigHolder, UpdateResult as UR}; +use crate::renderer::Renderer; +use crate::ui::{ + move_render_point, CanvasAccess, ClickHandler, RenderBox, RenderContext, Update, UpdateContext, +}; +use sdl2::rect::{Point, Rect}; + +const ICON_DEST_WIDTH: u32 = 32; +const ICON_DEST_HEIGHT: u32 = 32; +const ICON_SRC_WIDTH: u32 = 64; +const ICON_SRC_HEIGHT: u32 = 64; + +pub struct SaveButton { + source: Rect, + dest: Rect, + config: ConfigAccess, +} + +impl SaveButton { + pub fn new(config: ConfigAccess) -> Self { + Self { + dest: Rect::new(0, 0, ICON_DEST_WIDTH, ICON_DEST_HEIGHT), + source: Rect::new(0, 0, ICON_SRC_WIDTH, ICON_SRC_HEIGHT), + config, + } + } + + pub fn render(&self, canvas: &mut C, renderer: &mut R, context: &RenderContext) + where + C: CanvasAccess, + R: Renderer, + { + use std::borrow::*; + let mut dest = match context { + &RenderContext::RelativePosition(p) => move_render_point(p.clone(), &self.dest), + _ => self.dest.clone(), + }; + + canvas.set_clipping(dest.clone()); + let save_texture_path = { + let c = self.config.read().unwrap(); + let mut themes_dir = c.directories().themes_dir.clone(); + let path = c.theme().images().save_icon(); + themes_dir.push(path); + themes_dir.to_str().unwrap().to_owned() + }; + let maybe_tex = renderer.load_image(save_texture_path.clone()); + if let Ok(texture) = maybe_tex { + dest.set_width(ICON_DEST_WIDTH); + dest.set_height(ICON_DEST_HEIGHT); + canvas + .render_image(texture, self.source.clone(), dest.clone()) + .unwrap_or_else(|_| panic!("Failed to draw directory entry texture")); + } + } + + pub fn prepare_ui<'l, T>(&mut self, _renderer: &mut T) + where + T: ConfigHolder + Renderer, + { + } + + pub fn source(&self) -> &Rect { + &self.source + } + + pub fn set_dest(&mut self, rect: &Rect) { + self.dest = rect.clone(); + } + + pub fn set_source(&mut self, rect: &Rect) { + self.source = rect.clone(); + } +} + +impl Update for SaveButton { + fn update(&mut self, _ticks: i32, _context: &UpdateContext) -> UR { + let config = self.config.read().unwrap(); + self.dest.set_width(config.width()); + UR::NoOp + } +} + +impl ClickHandler for SaveButton { + fn on_left_click(&mut self, _point: &Point, _context: &UpdateContext) -> UR { + UR::SaveCurrentFile + } + + fn is_left_click_target(&self, point: &Point, context: &UpdateContext) -> bool { + match *context { + UpdateContext::ParentPosition(p) => move_render_point(p.clone(), &self.dest), + _ => self.dest(), + } + .contains_point(point.clone()) + } +} + +impl RenderBox for SaveButton { + fn render_start_point(&self) -> Point { + self.dest.top_left() + } + + fn dest(&self) -> Rect { + self.dest + } +} diff --git a/rider-generator/assets/themes/default/images/save-48x84.png b/rider-generator/assets/themes/default/images/save-48x84.png new file mode 100644 index 0000000000000000000000000000000000000000..ca55ea014c7eff6d8406c4d431b2a7d409d8311b GIT binary patch literal 1515 zcmeAS@N?(olHy`uVBq!ia0vp^1|TfJ0wmYYe(MjUn3BBRT^Rni_n+Ah4nJ z=qZCRW5rVYGN2%PiKnkC`(svVVNHv~8_Vn%7#I&$g+!DDC6+4`6y>L7=Ag z_jSS)^9vle=icPk{cEsKbG1aKiPU7@WDh$D38{AH>CIQpn6pUhyFZvY_x;1y5kGc@ zHJbjkdMk~#vGY-YQO5df2*zTic@m3PTaY-VZFePAJ^N~1o5nL&eSt1ZLhizVYIDu zpHiBKQ-SD#a;BH>c|QG2P}ndl(PXx-#w>$s#kY?ge@vI>dGJwXUXF&uJ(f4Kf|L%W zJEpCWnR#iQT~ENXo2OE4L^pQcKWFnlw{%fh`odQ_c7_+^CSSa`SYc|v&qQy2x4$#C z7hXOk&z-dK<@V%%pD)T>c(Z9|za`h(vx|3~-Bl5#<9Nzv$ppzcMb#H$CEhv}1kLU| zq-e0NlxhXzbYFCR z=@8Jk!yxL&npM3bid#K67v*q?bDcGKaNOd@#tT=9p4G;Pm$!*Lvs6B4ZCvnw_VK;X z<9__VU;X@m<-(ArW$R~rXADca@nl&;=^cwx_nSG5r+s>8kX!9JUEo$=Uv6Z3%NO-S zmUVfL_r4dJH7hcH$y3>NF-!hfm>oA;d)RZ5uFjj2de3cUKHz%EnOA%0_GQc8BCWj} zeUGdC?NC4W@odzkyqb9mM~hZPOWruTH2#Bg&eiq}lf1Max~}nd%e%Ir=|b;K4qrKe*)|Ghl@2+d8g4vc+<1~XX)^nfv=a9)2l=h6J@0DN zw71UwA$;^V^S?zuB>le!{hQ%bopW}h=l4w?47<8L>W^=m*sx`0r1;NA3|pID^sS9* z=gRDT_VkPVgZ=Rja=sbvXO`WltA2p(jO*(cD)YJ~SKe|ta{0!z$2(Q{D;G}coz5RP zuQOfQ<9l$#;WMWzo(3`ty?e8)WS0Fc1MhG9vqj7~s%QL_j=df6^#tRNy_1F8XWTtm zob3^xHK+c@!3V!<_IH2&zbWg?@?)GFvpME}IwtTt?%3C3tOwTT7iKA!U8_z~T7BN+ zl4!4}yy{=U>jMA$8E!tz=UH_ul5_c^U-Q|0v=H7-5MH?T+>bI7!EHw_YKv^_`Jkp} zV<8rI{8`Jw&oS?kOU19cY~y#Rn7)wj&cj!Azt~pP-E{cL_{%@=bxH;E)#oci1TP+#G~ z?tA9~w06Fao?mr`IYVhl!Se}oWPoLmWQl7;iF1B#Zfaf$gL6@8Vo7R>LV0FMhJw4N zZ$Nk>pEyvFDo9ZZP|7M9tb)PFz|d0Hz*N`BJjBq_%EZvh*h1UDz{p; iya}g(3i#j(@>5cC7(iO16Fi-PG7O%selF{r5}E+mvZB=h literal 0 HcmV?d00001 diff --git a/rider-generator/assets/themes/default/images/save-512x512.png b/rider-generator/assets/themes/default/images/save-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..7d62924eb96349b82744aec7f6d85517bcbe4656 GIT binary patch literal 3696 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7zEgW)RGq*JAo8Sx}&cn1H;CC?mvmF3=E8| zna<7up3cq+1x5L3nK`Kp3>p(_C)#=(c91z5AMEX_)l?=RdM045PDj^^WuY2QtpVCw zUL_R$6`EzDqN&%{lzs4E|It;=-J93(t!q;F!T9LWt0ga#RR8H~Zt3{=V2Awsced~D zF*>b160$j0B*65v$FbxjtIbMm@q!Nay9_%rXU_b!Mn(03<-T_hAHR;Bl3qFgcX3Ht zu^MxY(np@lyxkRZD~c{(vV1Sx9vOH}Xufd2M2X`g_jTHO`wR6fbUvKfFwyIrV0-6L zCvI)sGhJ<7HjXkUS4lnP&YZq^&UTB{OS!V|Ox|xW*xL^jG;X?XbMNlGTetV8Oa1-JaKNkR*rXqC zCITafEy>&6h2cL4F4((#GEjuGz$3Dlfk96hgc&QA+Lr+Z*-JcqUD+SAN(*bM&AvW6 z7APcH;u=xnoS&PUnpeW$T$GwvlA5AWo>`Ki;O^-g5Z=fq&cMK9?&;zfQgQ3;9mBrc z4m=Klh8L!`w@b*)(ri*Vnzk@awSUQXDRVZR3%x%~%Sy`2^MU3bX#Q&iN=O1g3`{W~ zf*_Lxr0PN7w@`f@W8=-Y!-4z*vZ0}&t|jH`H{8`LRuroPDqv}3XJg>D2eO(DlsZ26 z^q*nF4`!gsZM}xaB<>0d3i9)S%sKE?kDFoMACOFV_*|9(kYgC)9(-YVa1x|f#`?EP zgD^&3fwX8b^7mY+Oxrsn;z=U^WZ zG!97ty2(hEpfel5_9N-V!&G3907U^F6&R+`%q1Xa4+6tU2@9}V1(3subU7)8lMogV z+i7HY1K59qz;FeyLr4e~Qd~}o;iQBGSS_s#Cm}2bO%gep+*`Q*4ZwR;; zzy0c;Wvzl(CNPG>IGB=q43GW#{W6mAus=|Mp<>H!oqy@zGT8ydX8@O;1epY@6(j}3 znFz6x@c<}J30jY&0LdbPOp;szbO&T09L`>zyLIE_IMYkrWeT5)39J1tf*opp82u4`FALbp}lwed~C?KxQ2DS%7FCI^zJB(mDq?O@#+=$&u0fq<1l$4a}-ib0W+?lS#00M+c z<_54TJQc}-EXIU$md|?(vVbao!~t`YOL_TsUSP8o*fOo0&dQ(;iiZcQH_!hQF9#BA zIB&Vvphn%;__Of*GjspyCWG>!G^p+SZN>7p=HYLj%5yU`fgQ%dAolOIjxYlYBgn4; z3_5@GAx-1+AJrRxA__oE*b5Lp;_*TQ*cc=Q;6V8hvY(OnVN}=GIaY^33Orr?T-G@y GGywoz&FS0# literal 0 HcmV?d00001 diff --git a/rider-generator/assets/themes/default/images/save-64x64.png b/rider-generator/assets/themes/default/images/save-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..55fa15e4074058ddc11f7828de801ce916811357 GIT binary patch literal 1598 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 literal 0 HcmV?d00001 diff --git a/rider-generator/assets/themes/railscasts/images/save-512x512.png b/rider-generator/assets/themes/railscasts/images/save-512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..7d62924eb96349b82744aec7f6d85517bcbe4656 GIT binary patch literal 3696 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7zEgW)RGq*JAo8Sx}&cn1H;CC?mvmF3=E8| zna<7up3cq+1x5L3nK`Kp3>p(_C)#=(c91z5AMEX_)l?=RdM045PDj^^WuY2QtpVCw zUL_R$6`EzDqN&%{lzs4E|It;=-J93(t!q;F!T9LWt0ga#RR8H~Zt3{=V2Awsced~D zF*>b160$j0B*65v$FbxjtIbMm@q!Nay9_%rXU_b!Mn(03<-T_hAHR;Bl3qFgcX3Ht zu^MxY(np@lyxkRZD~c{(vV1Sx9vOH}Xufd2M2X`g_jTHO`wR6fbUvKfFwyIrV0-6L zCvI)sGhJ<7HjXkUS4lnP&YZq^&UTB{OS!V|Ox|xW*xL^jG;X?XbMNlGTetV8Oa1-JaKNkR*rXqC zCITafEy>&6h2cL4F4((#GEjuGz$3Dlfk96hgc&QA+Lr+Z*-JcqUD+SAN(*bM&AvW6 z7APcH;u=xnoS&PUnpeW$T$GwvlA5AWo>`Ki;O^-g5Z=fq&cMK9?&;zfQgQ3;9mBrc z4m=Klh8L!`w@b*)(ri*Vnzk@awSUQXDRVZR3%x%~%Sy`2^MU3bX#Q&iN=O1g3`{W~ zf*_Lxr0PN7w@`f@W8=-Y!-4z*vZ0}&t|jH`H{8`LRuroPDqv}3XJg>D2eO(DlsZ26 z^q*nF4`!gsZM}xaB<>0d3i9)S%sKE?kDFoMACOFV_*|9(kYgC)9(-YVa1x|f#`?EP zgD^&3fwX8b^7mY+Oxrsn;z=U^WZ zG!97ty2(hEpfel5_9N-V!&G3907U^F6&R+`%q1Xa4+6tU2@9}V1(3subU7)8lMogV z+i7HY1K59qz;FeyLr4e~Qd~}o;iQBGSS_s#Cm}2bO%gep+*`Q*4ZwR;; zzy0c;Wvzl(CNPG>IGB=q43GW#{W6mAus=|Mp<>H!oqy@zGT8ydX8@O;1epY@6(j}3 znFz6x@c<}J30jY&0LdbPOp;szbO&T09L`>zyLIE_IMYkrWeT5)39J1tf*opp82u4`FALbp}lwed~C?KxQ2DS%7FCI^zJB(mDq?O@#+=$&u0fq<1l$4a}-ib0W+?lS#00M+c z<_54TJQc}-EXIU$md|?(vVbao!~t`YOL_TsUSP8o*fOo0&dQ(;iiZcQH_!hQF9#BA zIB&Vvphn%;__Of*GjspyCWG>!G^p+SZN>7p=HYLj%5yU`fgQ%dAolOIjxYlYBgn4; z3_5@GAx-1+AJrRxA__oE*b5Lp;_*TQ*cc=Q;6V8hvY(OnVN}=GIaY^33Orr?T-G@y GGywoz&FS0# literal 0 HcmV?d00001 diff --git a/rider-generator/assets/themes/railscasts/images/save-64x64.png b/rider-generator/assets/themes/railscasts/images/save-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..55fa15e4074058ddc11f7828de801ce916811357 GIT binary patch literal 1598 zcmZ{keKga19LImOE=D*-d79>_C~VU@W0kgeXj z6aavABtIfqqqx;DhG=roN9IP2Xh-||5`mSRqCT0X(&PGtB>{k|-D+s1*6mH!GE4JNyumr$-OI?!D|Miw~4#*V8g-shJc9mQOd@hLvV+3B8W8 zy>H{aAJQBT(ZzMCCvYEt;Bzq!c5C|oiWGk|dfqujEyX<69jaCuxhx^OoEptQw1qH` z?&oP{W|8A1%6i&|fmkAZN6V{c#->8&+b9`3)z}G(+X`zv#QfnI>7KF5VpXm2;zP*c zz7DKl>&d&ayaQPc7hBv1lACAbYny$z$q0AOtH0x_ti)RuPWdlxY0QtbCG4WLbqcN- zOXml(o5%(YUZATRKPT;Rs9Oua%QnW3z%}ho(Vm}9+N&&V6;-@U@(U!ufbeCOW~W;;J=2 zV2VV<2dBQA9tzA2XPRY?P1)n$p^tji!ipvN`WUiv@(#%^xL z(Tx40B;lKG(tb*#QsB`j{9Jcu&XS`lhfWopi&fOSB9sP&9)>6H_eqAobQj)lk!d^?Eb%~^XX$?^bA?oCA(aSY7{t={f3ZBS( z)u>mJc`tds%509U-A_&{k+bs$iC18*S1X-1N?Okd8jU2JQuUvVC~seDw|mD<_pXV6 z{LD8BA2Mq3-D>SNB;lyJ&(ig_tZodO)Sip9+_$t_-@O>VuiOvDf-hFj_gH=aC_) zN2Cr|o{=@7E=81(Ekop@Ev6^yj2zF>^{;})P3h z8nhX`{YW|ne|F&kB3j%mT0kqEJcoOFC{Gmy;*NqvwaR2ID9u?j=XrhT$d+Q64VHoi1*eV3Y?Ijl%A5 z-;P9Lk;q*ggp2<%us94b=J@{`_KhvTGzQDn4Vue|rE|E)6T#Rx9uUNjP5|j}B8No- z*)1iga1Cbr9b+()=!qbg2XffJ>O std::io::Result<()> { Ok(()) } +fn create_railscasts_save_icon(dir: &PathBuf) -> std::io::Result<()> { + let blob = include_bytes!("../assets/themes/railscasts/images/save-64x64.png"); + write_bytes_to(dir, "save-64x64.png", blob)?; + Ok(()) +} + fn railscasts_theme(directories: &Directories) -> std::io::Result<()> { let mut dir = PathBuf::new(); dir.push(directories.themes_dir.clone()); @@ -55,6 +61,7 @@ fn railscasts_theme(directories: &Directories) -> std::io::Result<()> { create_dir_all(&dir)?; create_railscasts_directory_icon(&dir)?; create_railscasts_file_icon(&dir)?; + create_railscasts_save_icon(&dir)?; Ok(()) } diff --git a/rider-themes/src/images.rs b/rider-themes/src/images.rs index ad9e833..46148e7 100644 --- a/rider-themes/src/images.rs +++ b/rider-themes/src/images.rs @@ -2,13 +2,15 @@ pub struct ThemeImages { directory_icon: String, file_icon: String, + save_icon: String, } impl ThemeImages { - pub fn new(directory_icon: String, file_icon: String) -> Self { + pub fn new(directory_icon: String, file_icon: String, save_icon: String) -> Self { Self { file_icon, directory_icon, + save_icon, } } @@ -19,6 +21,10 @@ impl ThemeImages { pub fn file_icon(&self) -> String { self.file_icon.clone() } + + pub fn save_icon(&self) -> String { + self.save_icon.clone() + } } impl Default for ThemeImages { @@ -26,6 +32,7 @@ impl Default for ThemeImages { Self { directory_icon: "default/images/directory-64x64.png".to_string(), file_icon: "default/images/file-64x64.png".to_string(), + save_icon: "default/images/save-64x64.png".to_string(), } } } @@ -36,16 +43,25 @@ mod test { #[test] fn assert_directory_icon() { - let config = ThemeImages::new("foo".to_owned(), "bar".to_owned()); + let config = ThemeImages::new("foo".to_owned(), "bar".to_owned(), "baz".to_owned()); let result = config.directory_icon(); let expected = "foo".to_owned(); assert_eq!(result, expected); } + #[test] fn assert_file_icon() { - let config = ThemeImages::new("foo".to_owned(), "bar".to_owned()); + let config = ThemeImages::new("foo".to_owned(), "bar".to_owned(), "baz".to_owned()); let result = config.file_icon(); let expected = "bar".to_owned(); assert_eq!(result, expected); } + + #[test] + fn assert_save_icon() { + let config = ThemeImages::new("foo".to_owned(), "bar".to_owned(), "baz".to_owned()); + let result = config.save_icon(); + let expected = "baz".to_owned(); + assert_eq!(result, expected); + } } diff --git a/rider-themes/src/predef/railscasts.rs b/rider-themes/src/predef/railscasts.rs index 29b6c07..9959bb3 100644 --- a/rider-themes/src/predef/railscasts.rs +++ b/rider-themes/src/predef/railscasts.rs @@ -44,6 +44,7 @@ pub fn build_theme() -> Theme { ThemeImages::new( "railscasts/images/directory-64x64.png".to_owned(), "railscasts/images/file-64x64.png".to_owned(), + "railscasts/images/save-64x64.png".to_owned(), ), ) }