Flexible routing

Another massive refactor to change the way routing works. Now any
column can route anywhere.

Also things are generally just much better and more modular via the
new struct split borrowing technique.

I didn't even try to split this into smaller commits for my sanity.

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2024-09-11 19:43:41 -07:00
parent b4a8cddc48
commit 36c0971fd9
27 changed files with 973 additions and 963 deletions

View File

@@ -1,100 +1,86 @@
use crate::route::Route;
use crate::route::{Route, Router};
use crate::timeline::{Timeline, TimelineId};
use std::iter::Iterator;
use tracing::warn;
pub struct Column {
kind: ColumnKind,
routes: Vec<Route>,
pub navigating: bool,
pub returning: bool,
router: Router<Route>,
}
impl Column {
pub fn timeline(timeline: Timeline) -> Self {
let routes = vec![Route::Timeline(format!("{}", &timeline.kind))];
let kind = ColumnKind::Timeline(timeline);
Column::new(kind, routes)
pub fn new(routes: Vec<Route>) -> Self {
let router = Router::new(routes);
Column { router }
}
pub fn kind(&self) -> &ColumnKind {
&self.kind
pub fn router(&self) -> &Router<Route> {
&self.router
}
pub fn kind_mut(&mut self) -> &mut ColumnKind {
&mut self.kind
}
pub fn view_id(&self) -> egui::Id {
self.kind.view_id()
}
pub fn routes(&self) -> &[Route] {
&self.routes
}
pub fn routes_mut(&mut self) -> &mut Vec<Route> {
&mut self.routes
}
pub fn new(kind: ColumnKind, routes: Vec<Route>) -> Self {
let navigating = false;
let returning = false;
Column {
kind,
routes,
navigating,
returning,
}
pub fn router_mut(&mut self) -> &mut Router<Route> {
&mut self.router
}
}
#[derive(Default)]
pub struct Columns {
/// Columns are simply routers into settings, timelines, etc
columns: Vec<Column>,
/// Timeline state is not tied to routing logic separately, so that
/// different columns can navigate to and from settings to timelines,
/// etc.
pub timelines: Vec<Timeline>,
/// The selected column for key navigation
selected: i32,
}
impl Columns {
pub fn new() -> Self {
Columns::default()
}
pub fn add_timeline(&mut self, timeline: Timeline) {
let routes = vec![Route::timeline(timeline.id)];
self.timelines.push(timeline);
self.columns.push(Column::new(routes))
}
pub fn columns_mut(&mut self) -> &mut Vec<Column> {
&mut self.columns
}
pub fn timeline_mut(&mut self, timeline_ind: usize) -> &mut Timeline {
&mut self.timelines[timeline_ind]
}
pub fn column(&self, ind: usize) -> &Column {
&self.columns()[ind]
}
pub fn columns(&self) -> &[Column] {
pub fn columns(&self) -> &Vec<Column> {
&self.columns
}
pub fn new(columns: Vec<Column>) -> Self {
let selected = 0;
Columns { columns, selected }
}
pub fn selected(&mut self) -> &mut Column {
&mut self.columns[self.selected as usize]
}
pub fn timelines_mut(&mut self) -> impl Iterator<Item = &mut Timeline> {
self.columns
.iter_mut()
.filter_map(|c| c.kind_mut().timeline_mut())
pub fn timelines_mut(&mut self) -> &mut Vec<Timeline> {
&mut self.timelines
}
pub fn timelines(&self) -> impl Iterator<Item = &Timeline> {
self.columns.iter().filter_map(|c| c.kind().timeline())
pub fn timelines(&self) -> &Vec<Timeline> {
&self.timelines
}
pub fn find_timeline_mut(&mut self, id: TimelineId) -> Option<&mut Timeline> {
self.timelines_mut().find(|tl| tl.id == id)
self.timelines_mut().iter_mut().find(|tl| tl.id == id)
}
pub fn find_timeline(&self, id: TimelineId) -> Option<&Timeline> {
self.timelines().find(|tl| tl.id == id)
self.timelines().iter().find(|tl| tl.id == id)
}
pub fn column_mut(&mut self, ind: usize) -> &mut Column {
@@ -102,11 +88,11 @@ impl Columns {
}
pub fn select_down(&mut self) {
self.selected().kind_mut().select_down();
warn!("todo: implement select_down");
}
pub fn select_up(&mut self) {
self.selected().kind_mut().select_up();
warn!("todo: implement select_up");
}
pub fn select_left(&mut self) {
@@ -123,48 +109,3 @@ impl Columns {
self.selected += 1;
}
}
/// What type of column is it?
#[derive(Debug)]
pub enum ColumnKind {
Timeline(Timeline),
ManageAccount,
}
impl ColumnKind {
pub fn timeline_mut(&mut self) -> Option<&mut Timeline> {
match self {
ColumnKind::Timeline(tl) => Some(tl),
_ => None,
}
}
pub fn timeline(&self) -> Option<&Timeline> {
match self {
ColumnKind::Timeline(tl) => Some(tl),
_ => None,
}
}
pub fn view_id(&self) -> egui::Id {
match self {
ColumnKind::Timeline(timeline) => timeline.view_id(),
ColumnKind::ManageAccount => egui::Id::new("manage_account"),
}
}
pub fn select_down(&mut self) {
match self {
ColumnKind::Timeline(tl) => tl.current_view_mut().select_down(),
ColumnKind::ManageAccount => warn!("todo: manage account select_down"),
}
}
pub fn select_up(&mut self) {
match self {
ColumnKind::Timeline(tl) => tl.current_view_mut().select_down(),
ColumnKind::ManageAccount => warn!("todo: manage account select_down"),
}
}
}