Added pane resizing
This commit is contained in:
parent
41965454c7
commit
34c7fec4de
2 changed files with 104 additions and 33 deletions
110
src/action.rs
110
src/action.rs
|
|
@ -17,36 +17,66 @@ pub enum Dir {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Action {
|
||||
Char(char), // Insert a character
|
||||
Indent(bool), // Indent (indent vs deindent)
|
||||
Move(Dir, Dist, bool, bool), // Move the cursor (dir, dist, retain_base, word)
|
||||
PaneMove(Dir), // Move panes
|
||||
PaneOpen(Dir), // Create a new pane
|
||||
PaneClose, // Close the current pane
|
||||
Cancel, // Cancels the current action
|
||||
Continue, // Continue past an info-only element (like a help screen)
|
||||
Go, // Search, accept, or select the current option
|
||||
Yes, // A binary confirmation is answered 'yes'
|
||||
No, // A binary confirmation is answered 'no'
|
||||
Quit, // Quit the application
|
||||
OpenPrompt, // Open the command prompt
|
||||
Show(Option<String>, String), // Display an optionally titled informational text box to the user
|
||||
OpenSwitcher, // Open the buffer switcher
|
||||
OpenOpener(PathBuf), // Open the file opener
|
||||
OpenFinder(Option<String>), // Open the finder, with the given default query
|
||||
SwitchBuffer(BufferId), // Switch the current pane to the given buffer
|
||||
OpenFile(PathBuf, usize), // Open the file (on the given line) and switch the current pane to it
|
||||
CreateFile(PathBuf), // Create a new file and switch the current pane to it
|
||||
CommandStart(&'static str), // Start a new command
|
||||
GotoLine(isize), // Go to the specified file line
|
||||
BeginSearch(String), // Request to begin a search with the given needle
|
||||
OpenSearcher(PathBuf, String), // Start a project-wide search with the given location and needle
|
||||
SelectToken, // Fully select the token under the cursor
|
||||
SelectAll, // Fully select the entire input
|
||||
Save, // Save the current buffer
|
||||
Overwrite, // Save the current buffer, forcefully
|
||||
Reload, // Reload the current file from disk, losing unsaved changes
|
||||
Mouse(MouseAction, [isize; 2], bool, usize), // (action, pos, is_ctrl, drag_id)
|
||||
// Insert a character
|
||||
Char(char),
|
||||
// Indent (indent vs deindent)
|
||||
Indent(bool),
|
||||
// Move the cursor (dir, dist, retain_base, word)
|
||||
Move(Dir, Dist, bool, bool),
|
||||
// Move panes
|
||||
PaneMove(Dir),
|
||||
// Create a new pane
|
||||
PaneOpen(Dir),
|
||||
// Close the current pane
|
||||
PaneClose,
|
||||
// Cancels the current action
|
||||
Cancel,
|
||||
// Continue past an info-only element (like a help screen)
|
||||
Continue,
|
||||
// Search, accept, or select the current option
|
||||
Go,
|
||||
// A binary confirmation is answered 'yes'
|
||||
Yes,
|
||||
// A binary confirmation is answered 'no'
|
||||
No,
|
||||
// Quit the application
|
||||
Quit,
|
||||
// Open the command prompt
|
||||
OpenPrompt,
|
||||
// Display an optionally titled informational text box to the user
|
||||
Show(Option<String>, String),
|
||||
// Open the buffer switcher
|
||||
OpenSwitcher,
|
||||
// Open the file opener
|
||||
OpenOpener(PathBuf),
|
||||
// Open the finder, with the given default query
|
||||
OpenFinder(Option<String>),
|
||||
// Switch the current pane to the given buffer
|
||||
SwitchBuffer(BufferId),
|
||||
// Open the file (on the given line) and switch the current pane to it
|
||||
OpenFile(PathBuf, usize),
|
||||
// Create a new file and switch the current pane to it
|
||||
CreateFile(PathBuf),
|
||||
// Start a new command
|
||||
CommandStart(&'static str),
|
||||
// Go to the specified file line
|
||||
GotoLine(isize),
|
||||
// Request to begin a search with the given needle
|
||||
BeginSearch(String),
|
||||
// Start a project-wide search with the given location and needle
|
||||
OpenSearcher(PathBuf, String),
|
||||
// Fully select the token under the cursor
|
||||
SelectToken,
|
||||
// Fully select the entire input
|
||||
SelectAll,
|
||||
// Save the current buffer
|
||||
Save,
|
||||
// Save the current buffer, forcefully
|
||||
Overwrite,
|
||||
// Reload the current file from disk, losing unsaved changes
|
||||
Reload,
|
||||
// (action, pos, is_ctrl, drag_id)
|
||||
Mouse(MouseAction, [isize; 2], bool, usize),
|
||||
Confirm(String, Box<Self>),
|
||||
Undo,
|
||||
Redo,
|
||||
|
|
@ -55,6 +85,8 @@ pub enum Action {
|
|||
Paste,
|
||||
Duplicate,
|
||||
Comment,
|
||||
// Resize the current pane
|
||||
PaneResize(i32),
|
||||
}
|
||||
|
||||
/// How far should movement go?
|
||||
|
|
@ -435,6 +467,24 @@ impl RawEvent {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn to_pane_resize(&self) -> Option<Action> {
|
||||
match &self.0 {
|
||||
TerminalEvent::Key(KeyEvent {
|
||||
code: KeyCode::Char('='),
|
||||
modifiers: KeyModifiers::ALT,
|
||||
kind: KeyEventKind::Press,
|
||||
..
|
||||
}) => Some(Action::PaneResize(1)),
|
||||
TerminalEvent::Key(KeyEvent {
|
||||
code: KeyCode::Char('-'),
|
||||
modifiers: KeyModifiers::ALT,
|
||||
kind: KeyEventKind::Press,
|
||||
..
|
||||
}) => Some(Action::PaneResize(-1)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_edit(&self) -> Option<Action> {
|
||||
match &self.0 {
|
||||
TerminalEvent::Key(KeyEvent {
|
||||
|
|
|
|||
|
|
@ -87,8 +87,11 @@ pub struct HBox {
|
|||
selected: usize,
|
||||
panes: Vec<Pane>,
|
||||
last_area: Area,
|
||||
size_weight: usize,
|
||||
}
|
||||
|
||||
const DEFAULT_WEIGHT: usize = 4;
|
||||
|
||||
impl Element<()> for HBox {
|
||||
fn handle(&mut self, state: &mut State, event: Event) -> Result<Resp<()>, Event> {
|
||||
match event.to_action(|e| {
|
||||
|
|
@ -96,6 +99,7 @@ impl Element<()> for HBox {
|
|||
.map(Action::PaneMove)
|
||||
.or_else(|| e.to_pane_open().map(Action::PaneOpen))
|
||||
.or_else(|| e.to_pane_close())
|
||||
.or_else(|| e.to_pane_resize())
|
||||
}) {
|
||||
Some(Action::PaneMove(Dir::Left)) => {
|
||||
self.selected = (self.selected + self.panes.len() - 1) % self.panes.len();
|
||||
|
|
@ -142,6 +146,11 @@ impl Element<()> for HBox {
|
|||
self.selected = new_idx;
|
||||
Ok(Resp::handled(None))
|
||||
}
|
||||
Some(Action::PaneResize(by)) => {
|
||||
self.size_weight =
|
||||
(self.size_weight as i32 + by).clamp(1, DEFAULT_WEIGHT.pow(2) as i32) as usize;
|
||||
Ok(Resp::handled(None))
|
||||
}
|
||||
Some(action @ Action::Mouse(m_action, pos, is_ctrl, drag_id)) => {
|
||||
for (i, pane) in self.panes.iter_mut().enumerate() {
|
||||
if pane.last_area.contains(pos).is_some() {
|
||||
|
|
@ -212,6 +221,7 @@ impl Panes {
|
|||
task: None,
|
||||
}],
|
||||
last_area: Area::default(),
|
||||
size_weight: DEFAULT_WEIGHT,
|
||||
})
|
||||
.collect(),
|
||||
last_area: Default::default(),
|
||||
|
|
@ -264,6 +274,7 @@ impl Element for Panes {
|
|||
task: None,
|
||||
}],
|
||||
last_area: Area::default(),
|
||||
size_weight: DEFAULT_WEIGHT,
|
||||
},
|
||||
);
|
||||
self.selected = new_idx;
|
||||
|
|
@ -321,19 +332,29 @@ impl Element for Panes {
|
|||
impl Visual for Panes {
|
||||
fn render(&mut self, state: &State, frame: &mut Rect) {
|
||||
let n = self.hboxes.len();
|
||||
let frame_h = frame.size()[1];
|
||||
let boundary = |i| frame_h * i / n;
|
||||
if n == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let total_weight = self.hboxes.iter().map(|h| h.size_weight).sum::<usize>();
|
||||
|
||||
self.last_area = frame.area();
|
||||
|
||||
let mut y0 = 0;
|
||||
for (i, hbox) in self.hboxes.iter_mut().enumerate() {
|
||||
let (y0, y1) = (boundary(i), boundary(i + 1));
|
||||
let y1 = if i == n - 1 {
|
||||
frame.size()[1]
|
||||
} else {
|
||||
y0 + hbox.size_weight * frame.size()[1] / total_weight
|
||||
};
|
||||
|
||||
// Draw pane contents
|
||||
frame
|
||||
.rect([0, y0], [frame.size()[0], y1 - y0])
|
||||
.with_focus(self.selected == i)
|
||||
.with(|frame| hbox.render(state, frame));
|
||||
|
||||
y0 = y1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue