Switched to vertical-first plane splitting
This commit is contained in:
parent
1b4268b078
commit
cffa6fe487
2 changed files with 56 additions and 50 deletions
10
README.md
10
README.md
|
|
@ -21,8 +21,14 @@
|
|||
## Todo
|
||||
|
||||
- [ ] Replace
|
||||
- [ ] Terminal windows
|
||||
- [ ] Terminal buffers
|
||||
- [ ] Ability to resize panes (weighted sum?)
|
||||
- [ ] Matching delimiter highlighting
|
||||
|
||||
## Issues to fix
|
||||
|
||||
- Undo history changes should not join so easily
|
||||
- Undo history changes should not join so easily
|
||||
- Double click should select ident, not highlighted token
|
||||
- Switcher search should allow searching whole path, not just parent
|
||||
- Scroll drag should work in opener preview
|
||||
- Switching buffers should preserve scroll position
|
||||
|
|
@ -11,13 +11,13 @@ pub struct Pane {
|
|||
last_area: Area,
|
||||
}
|
||||
|
||||
pub struct VBox {
|
||||
pub struct HBox {
|
||||
selected: usize,
|
||||
panes: Vec<Pane>,
|
||||
last_area: Area,
|
||||
}
|
||||
|
||||
impl Element<()> for VBox {
|
||||
impl Element<()> for HBox {
|
||||
fn handle(&mut self, state: &mut State, event: Event) -> Result<Resp<()>, Event> {
|
||||
match event.to_action(|e| {
|
||||
e.to_pane_move()
|
||||
|
|
@ -25,11 +25,11 @@ impl Element<()> for VBox {
|
|||
.or_else(|| e.to_pane_open().map(Action::PaneOpen))
|
||||
.or_else(|| e.to_pane_close())
|
||||
}) {
|
||||
Some(Action::PaneMove(Dir::Up)) => {
|
||||
Some(Action::PaneMove(Dir::Left)) => {
|
||||
self.selected = (self.selected + self.panes.len() - 1) % self.panes.len();
|
||||
Ok(Resp::handled(None))
|
||||
}
|
||||
Some(Action::PaneMove(Dir::Down)) => {
|
||||
Some(Action::PaneMove(Dir::Right)) => {
|
||||
self.selected = (self.selected + 1) % self.panes.len();
|
||||
Ok(Resp::handled(None))
|
||||
}
|
||||
|
|
@ -51,9 +51,9 @@ impl Element<()> for VBox {
|
|||
}
|
||||
Some(Action::PaneOpen(dir)) => {
|
||||
let new_idx = match dir {
|
||||
Dir::Up => self.selected.clamp(0, self.panes.len()),
|
||||
Dir::Down => (self.selected + 1).min(self.panes.len()),
|
||||
Dir::Left | Dir::Right => return Err(event),
|
||||
Dir::Left => self.selected.clamp(0, self.panes.len()),
|
||||
Dir::Right => (self.selected + 1).min(self.panes.len()),
|
||||
Dir::Up | Dir::Down => return Err(event),
|
||||
};
|
||||
let kind = match state.buffers.keys().next() {
|
||||
Some(b) => PaneKind::Doc(Doc::new(state, b)),
|
||||
|
|
@ -105,20 +105,20 @@ impl Element<()> for VBox {
|
|||
}
|
||||
}
|
||||
|
||||
impl Visual for VBox {
|
||||
impl Visual for HBox {
|
||||
fn render(&mut self, state: &State, frame: &mut Rect) {
|
||||
let n = self.panes.len();
|
||||
let frame_h = frame.size()[1];
|
||||
let boundary = |i| frame_h * i / n;
|
||||
let frame_w = frame.size()[0];
|
||||
let boundary = |i| frame_w * i / n;
|
||||
|
||||
self.last_area = frame.area();
|
||||
|
||||
for (i, pane) in self.panes.iter_mut().enumerate() {
|
||||
let (y0, y1) = (boundary(i), boundary(i + 1));
|
||||
let (x0, x1) = (boundary(i), boundary(i + 1));
|
||||
|
||||
// Draw pane contents
|
||||
frame
|
||||
.rect([0, y0], [frame.size()[0], y1 - y0])
|
||||
.rect([x0, 0], [x1 - x0, frame.size()[0]])
|
||||
.with_focus(self.selected == i)
|
||||
.with(|frame| {
|
||||
pane.last_area = frame.area();
|
||||
|
|
@ -133,7 +133,7 @@ impl Visual for VBox {
|
|||
|
||||
pub struct Panes {
|
||||
selected: usize,
|
||||
vboxes: Vec<VBox>,
|
||||
hboxes: Vec<HBox>,
|
||||
last_area: Area,
|
||||
}
|
||||
|
||||
|
|
@ -141,9 +141,9 @@ impl Panes {
|
|||
pub fn new(state: &mut State, buffers: &[BufferId]) -> Self {
|
||||
Self {
|
||||
selected: 0,
|
||||
vboxes: buffers
|
||||
hboxes: buffers
|
||||
.iter()
|
||||
.map(|b| VBox {
|
||||
.map(|b| HBox {
|
||||
selected: 0,
|
||||
panes: vec![Pane {
|
||||
kind: PaneKind::Doc(Doc::new(state, *b)),
|
||||
|
|
@ -157,12 +157,12 @@ impl Panes {
|
|||
}
|
||||
|
||||
pub fn selected_mut(&mut self) -> Option<&mut Pane> {
|
||||
let vbox = self.vboxes.get_mut(self.selected)?;
|
||||
vbox.panes.get_mut(vbox.selected)
|
||||
let hbox = self.hboxes.get_mut(self.selected)?;
|
||||
hbox.panes.get_mut(hbox.selected)
|
||||
}
|
||||
|
||||
pub fn selected_vbox_mut(&mut self) -> Option<&mut VBox> {
|
||||
self.vboxes.get_mut(self.selected)
|
||||
pub fn selected_hbox_mut(&mut self) -> Option<&mut HBox> {
|
||||
self.hboxes.get_mut(self.selected)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,27 +174,27 @@ impl Element for Panes {
|
|||
.or_else(|| e.to_pane_open().map(Action::PaneOpen))
|
||||
.or_else(|| e.to_pane_close())
|
||||
}) {
|
||||
Some(Action::PaneMove(Dir::Left)) => {
|
||||
self.selected = (self.selected + self.vboxes.len() - 1) % self.vboxes.len();
|
||||
Some(Action::PaneMove(Dir::Up)) => {
|
||||
self.selected = (self.selected + self.hboxes.len() - 1) % self.hboxes.len();
|
||||
Ok(Resp::handled(None))
|
||||
}
|
||||
Some(Action::PaneMove(Dir::Right)) => {
|
||||
self.selected = (self.selected + 1) % self.vboxes.len();
|
||||
Some(Action::PaneMove(Dir::Down)) => {
|
||||
self.selected = (self.selected + 1) % self.hboxes.len();
|
||||
Ok(Resp::handled(None))
|
||||
}
|
||||
Some(Action::PaneOpen(dir @ (Dir::Left | Dir::Right))) => {
|
||||
Some(Action::PaneOpen(dir @ (Dir::Up | Dir::Down))) => {
|
||||
let new_idx = match dir {
|
||||
Dir::Left => self.selected.clamp(0, self.vboxes.len()),
|
||||
Dir::Right => (self.selected + 1).min(self.vboxes.len()),
|
||||
Dir::Up => self.selected.clamp(0, self.hboxes.len()),
|
||||
Dir::Down => (self.selected + 1).min(self.hboxes.len()),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let kind = match state.buffers.keys().next() {
|
||||
Some(b) => PaneKind::Doc(Doc::new(state, b)),
|
||||
None => PaneKind::Empty,
|
||||
};
|
||||
self.vboxes.insert(
|
||||
self.hboxes.insert(
|
||||
new_idx,
|
||||
VBox {
|
||||
HBox {
|
||||
selected: 0,
|
||||
panes: vec![Pane {
|
||||
kind,
|
||||
|
|
@ -207,15 +207,15 @@ impl Element for Panes {
|
|||
Ok(Resp::handled(None))
|
||||
}
|
||||
Some(action @ Action::Mouse(m_action, pos, is_ctrl, drag_id)) => {
|
||||
for (i, vbox) in self.vboxes.iter_mut().enumerate() {
|
||||
if vbox.last_area.contains(pos).is_some() {
|
||||
for (i, hbox) in self.hboxes.iter_mut().enumerate() {
|
||||
if hbox.last_area.contains(pos).is_some() {
|
||||
if matches!(m_action, MouseAction::Click) {
|
||||
self.selected = i;
|
||||
}
|
||||
let resp = vbox.handle(state, action.clone().into())?;
|
||||
let resp = hbox.handle(state, action.clone().into())?;
|
||||
if resp.is_end() {
|
||||
self.vboxes.remove(self.selected);
|
||||
self.selected = self.selected.min(self.vboxes.len()).saturating_sub(1);
|
||||
self.hboxes.remove(self.selected);
|
||||
self.selected = self.selected.min(self.hboxes.len()).saturating_sub(1);
|
||||
}
|
||||
return Ok(Resp::handled(resp.event));
|
||||
}
|
||||
|
|
@ -225,10 +225,10 @@ impl Element for Panes {
|
|||
// Pass anything else through to the active pane
|
||||
action => {
|
||||
let mut to_handle = self.selected;
|
||||
// Set selected vbox on mouse click
|
||||
// Set selected hbox on mouse click
|
||||
if let Some(Action::Mouse(ref m_action, pos, is_ctrl, drag_id)) = action {
|
||||
for (i, vbox) in self.vboxes.iter_mut().enumerate() {
|
||||
if vbox.last_area.contains(pos).is_some() {
|
||||
for (i, hbox) in self.hboxes.iter_mut().enumerate() {
|
||||
if hbox.last_area.contains(pos).is_some() {
|
||||
if matches!(m_action, MouseAction::Click) {
|
||||
self.selected = i;
|
||||
}
|
||||
|
|
@ -238,12 +238,12 @@ impl Element for Panes {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(vbox) = self.vboxes.get_mut(to_handle) {
|
||||
// Pass to vbox
|
||||
let resp = vbox.handle(state, event)?;
|
||||
if let Some(hbox) = self.hboxes.get_mut(to_handle) {
|
||||
// Pass to hbox
|
||||
let resp = hbox.handle(state, event)?;
|
||||
if resp.is_end() {
|
||||
self.vboxes.remove(self.selected);
|
||||
self.selected = self.selected.min(self.vboxes.len().saturating_sub(1));
|
||||
self.hboxes.remove(self.selected);
|
||||
self.selected = self.selected.min(self.hboxes.len().saturating_sub(1));
|
||||
}
|
||||
Ok(Resp::handled(resp.event))
|
||||
} else {
|
||||
|
|
@ -257,20 +257,20 @@ impl Element for Panes {
|
|||
|
||||
impl Visual for Panes {
|
||||
fn render(&mut self, state: &State, frame: &mut Rect) {
|
||||
let n = self.vboxes.len();
|
||||
let frame_w = frame.size()[0];
|
||||
let boundary = |i| frame_w * i / n;
|
||||
let n = self.hboxes.len();
|
||||
let frame_h = frame.size()[1];
|
||||
let boundary = |i| frame_h * i / n;
|
||||
|
||||
self.last_area = frame.area();
|
||||
|
||||
for (i, vbox) in self.vboxes.iter_mut().enumerate() {
|
||||
let (x0, x1) = (boundary(i), boundary(i + 1));
|
||||
for (i, hbox) in self.hboxes.iter_mut().enumerate() {
|
||||
let (y0, y1) = (boundary(i), boundary(i + 1));
|
||||
|
||||
// Draw pane contents
|
||||
frame
|
||||
.rect([x0, 0], [x1 - x0, frame.size()[1]])
|
||||
.rect([0, y0], [frame.size()[0], y1 - y0])
|
||||
.with_focus(self.selected == i)
|
||||
.with(|frame| vbox.render(state, frame));
|
||||
.with(|frame| hbox.render(state, frame));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue