river_bsp_layout/
user_cmd.rs

1use clap::Parser;
2
3use crate::{BSPLayout, BSPLayoutError};
4
5#[derive(Parser)]
6pub struct UserCmd {
7    /// The number of pixels to pad each inner edge of a window by default.
8    #[arg(short = 'i', long = "inner-gap", help_heading = "Inner Gap Options")]
9    pub default_inner_gap: Option<u32>,
10
11    /// The number of pixels to pad the left inner edge of each window. This Overrides
12    /// `default_inner_gap`. Optional
13    #[arg(long, short = 'l', help_heading = "Inner Gap Options")]
14    pub ig_left: Option<u32>,
15
16    /// The number of pixels to pad the right inner edge of each window. This Overrides
17    /// `default_inner_gap`. Optional
18    #[arg(long, short = 'r', help_heading = "Inner Gap Options")]
19    pub ig_right: Option<u32>,
20
21    /// The number of pixels to pad the bottom inner edge of each window. This Overrides
22    /// `default_inner_gap`. Optional
23    #[arg(long, short = 'b', help_heading = "Inner Gap Options")]
24    pub ig_bottom: Option<u32>,
25
26    /// The number of pixels to pad the top inner edge of each window. This Overrides
27    /// `default_inner_gap`. Optional
28    #[arg(long, short = 't', help_heading = "Inner Gap Options")]
29    pub ig_top: Option<u32>,
30
31    /// The default size of the gap between windows and the edge of the screen.
32    #[arg(short = 'o', long = "outer-gap", help_heading = "Outer Gap Options")]
33    pub default_outer_gap: Option<u32>,
34
35    /// The number of pixels to place between the left screen edge and any windows. Overrides
36    /// `default_outer_gap` for the left side. Optional.
37    #[arg(long, short = 'L', help_heading = "Outer Gap Options")]
38    pub og_left: Option<u32>,
39
40    /// The number of pixels to place between the right screen edge and any windows. Overrides
41    /// `default_outer_gap` for the right side. Optional.
42    #[arg(long, short = 'R', help_heading = "Outer Gap Options")]
43    pub og_right: Option<u32>,
44
45    /// The number of pixels to place between the bottom screen edge and any windows. Overrides
46    /// `default_outer_gap` for the bottom side. Optional.
47    #[arg(long, short = 'B', help_heading = "Outer Gap Options")]
48    pub og_bottom: Option<u32>,
49
50    /// The number of pixels to place between the top screen edge and any windows. Overrides
51    /// `default_outer_gap` for the top side. Optional.
52    #[arg(long, short = 'T', help_heading = "Outer Gap Options")]
53    pub og_top: Option<u32>,
54
55    /// The default percentage of available area that the primary window should occupy after any
56    /// split takes place.
57    #[arg(long = "split-perc", short = 's', help_heading = "Split Options")]
58    pub default_split_perc: Option<f32>,
59
60    /// The percentage of available area that the primary window should occupy after a horizontal
61    /// split. This will override the value of `default_split_perc` only for horizontal splits.
62    #[arg(long, short = 'H', help_heading = "Split Options")]
63    pub hsplit_perc: Option<f32>,
64
65    /// The percentage of available area that the primary window should occupy after a vertical
66    /// split. This will override the value of `default_split_perc` only for vertical splits.
67    #[arg(long, short, help_heading = "Split Options")]
68    pub vsplit_perc: Option<f32>,
69
70    /// Set the first split to horizontal
71    #[arg(long, help_heading = "Split Options")]
72    pub start_hsplit: bool,
73
74    /// Set the first split to vertical
75    #[arg(long, help_heading = "Split Options")]
76    pub start_vsplit: bool,
77
78    /// Increase the hsplit percentage by a certain amount.
79    #[arg(long, help_heading = "Split Options")]
80    pub inc_hsplit: Option<f32>,
81
82    /// Increase the vsplit percentage by a certain amount.
83    #[arg(long, help_heading = "Split Options")]
84    pub inc_vsplit: Option<f32>,
85
86    /// Decrease the vsplit percentage by a certain amount.
87    #[arg(long, help_heading = "Split Options")]
88    pub dec_vsplit: Option<f32>,
89
90    /// Decrease the hsplit percentage by a certain amount.
91    #[arg(long, help_heading = "Split Options")]
92    pub dec_hsplit: Option<f32>,
93
94    /// Reverse the order of the views as well as the order they are added.
95    #[arg(long, help_heading = "Other Options")]
96    pub reverse: bool,
97}
98
99impl UserCmd {
100    pub fn handle_outer_gaps(&self, layout: &mut BSPLayout) {
101        if let Some(g) = self.default_outer_gap {
102            layout.og_top = g;
103            layout.og_bottom = g;
104            layout.og_right = g;
105            layout.og_left = g;
106        }
107        if let Some(g) = self.og_top {
108            layout.og_top = g;
109        }
110        if let Some(g) = self.og_bottom {
111            layout.og_bottom = g;
112        }
113        if let Some(g) = self.og_right {
114            layout.og_right = g;
115        }
116        if let Some(g) = self.og_left {
117            layout.og_left = g;
118        }
119    }
120
121    pub fn handle_inner_gaps(&self, layout: &mut BSPLayout) {
122        if let Some(g) = self.default_inner_gap {
123            layout.ig_top = g;
124            layout.ig_bottom = g;
125            layout.ig_right = g;
126            layout.ig_left = g;
127        }
128        if let Some(g) = self.ig_top {
129            layout.ig_top = g;
130        }
131        if let Some(g) = self.ig_bottom {
132            layout.ig_bottom = g;
133        }
134        if let Some(g) = self.ig_right {
135            layout.ig_right = g;
136        }
137        if let Some(g) = self.ig_left {
138            layout.ig_left = g;
139        }
140    }
141
142    pub fn handle_ch_split(&self, layout: &mut BSPLayout) {
143        if let Some(p) = self.inc_hsplit {
144            if layout.hsplit_perc + p < 1.0 {
145                layout.hsplit_perc += p;
146            } else {
147                layout.hsplit_perc = 0.9999
148            }
149        }
150        if let Some(p) = self.inc_vsplit {
151            if layout.vsplit_perc + p < 1.0 {
152                layout.vsplit_perc += p;
153            } else {
154                layout.vsplit_perc = 0.9999;
155            }
156        }
157
158        if let Some(p) = self.dec_hsplit {
159            if layout.hsplit_perc - p > 0.0 {
160                layout.hsplit_perc -= p;
161            } else {
162                layout.hsplit_perc = 0.0001
163            }
164        }
165        if let Some(p) = self.dec_vsplit {
166            if layout.vsplit_perc - p > 0.0 {
167                layout.vsplit_perc -= p;
168            } else {
169                layout.vsplit_perc = 0.0001
170            }
171        }
172    }
173
174    pub fn handle_start_split(&self, layout: &mut BSPLayout) -> Result<(), BSPLayoutError> {
175        if self.start_hsplit && self.start_vsplit {
176            eprintln!(
177                "start-hsplit and start-vsplit are mutually exclusive. Please select only one"
178            );
179            return Err(BSPLayoutError::CmdError(
180                "start-hsplit and start-vsplit are mutually exclusive. Please select only one"
181                    .to_string(),
182            ));
183        } else if self.start_hsplit && !self.start_vsplit {
184            layout.start_hsplit = true;
185        } else if self.start_vsplit && !self.start_hsplit {
186            layout.start_hsplit = false;
187        }
188
189        Ok(())
190    }
191
192    pub fn handle_set_split(&self, layout: &mut BSPLayout) {
193        if let Some(p) = self.default_split_perc {
194            layout.hsplit_perc = p;
195            layout.vsplit_perc = p;
196        }
197        if let Some(p) = self.vsplit_perc {
198            layout.vsplit_perc = p;
199        }
200        if let Some(p) = self.hsplit_perc {
201            layout.hsplit_perc = p;
202        }
203    }
204
205    pub fn handle_reverse(&self, layout: &mut BSPLayout) {
206        if self.reverse {
207            layout.reversed = !layout.reversed;
208        }
209    }
210}