Skip to content

Commit

Permalink
title bar
Browse files Browse the repository at this point in the history
add title bar to columns with title specific to the column type.
also add column deletion button

Signed-off-by: kernelkind <[email protected]>
  • Loading branch information
kernelkind committed Oct 7, 2024
1 parent 0a22210 commit 932b091
Show file tree
Hide file tree
Showing 12 changed files with 432 additions and 117 deletions.
Binary file added assets/icons/column_delete_icon_4x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 12 additions & 9 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ fn try_process_event(damus: &mut Damus, ctx: &egui::Context) -> Result<()> {

if let Err(err) = Timeline::poll_notes_into_view(
timeline_ind,
&mut damus.columns.timelines,
damus.columns.timelines_mut(),
&damus.ndb,
&txn,
&mut damus.unknown_ids,
Expand Down Expand Up @@ -490,6 +490,8 @@ fn update_damus(damus: &mut Damus, ctx: &egui::Context) {
if let Err(err) = try_process_event(damus, ctx) {
error!("error processing event: {}", err);
}

damus.columns.attempt_perform_deletion_request();
}

fn process_event(damus: &mut Damus, _subid: &str, event: &str) {
Expand Down Expand Up @@ -952,7 +954,7 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) {
puffin::profile_function!();

let screen_size = ctx.screen_rect().width();
let calc_panel_width = (screen_size / app.columns.columns().len() as f32) - 30.0;
let calc_panel_width = (screen_size / app.columns.num_columns() as f32) - 30.0;
let min_width = 320.0;
let need_scroll = calc_panel_width < min_width;
let panel_sizes = if need_scroll {
Expand All @@ -965,18 +967,18 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) {
ui.spacing_mut().item_spacing.x = 0.0;
if need_scroll {
egui::ScrollArea::horizontal().show(ui, |ui| {
timelines_view(ui, panel_sizes, app, app.columns.columns().len());
timelines_view(ui, panel_sizes, app);
});
} else {
timelines_view(ui, panel_sizes, app, app.columns.columns().len());
timelines_view(ui, panel_sizes, app);
}
});
}

fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus, columns: usize) {
fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus) {
StripBuilder::new(ui)
.size(Size::exact(ui::side_panel::SIDE_PANEL_WIDTH))
.sizes(sizes, columns)
.sizes(sizes, app.columns.num_columns())
.clip(true)
.horizontal(|mut strip| {
strip.cell(|ui| {
Expand All @@ -988,6 +990,8 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus, columns: usiz
)
.show(ui);

let router = app.columns.get_first_router();

Check failure on line 993 in src/app.rs

View workflow job for this annotation

GitHub Actions / Clippy

unused variable: `router`

Check warning on line 993 in src/app.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused variable: `router`

if side_panel.response.clicked() {
DesktopSidePanel::perform_action(app.columns_mut(), side_panel.action);
}
Expand All @@ -1000,11 +1004,10 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus, columns: usiz
);
});

let n_cols = app.columns.columns().len();
for column_ind in 0..n_cols {
for col_index in 0..app.columns.num_columns() {
strip.cell(|ui| {
let rect = ui.available_rect_before_wrap();
nav::render_nav(column_ind, app, ui);
nav::render_nav(col_index, app, ui);

// vertical line
ui.painter().vline(
Expand Down
128 changes: 93 additions & 35 deletions src/column.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::route::{Route, Router};
use crate::timeline::{Timeline, TimelineId};
use indexmap::IndexMap;
use std::iter::Iterator;
use tracing::warn;
use std::sync::atomic::{AtomicU32, Ordering};
use tracing::{info, warn};

pub struct Column {
router: Router<Route>,
Expand All @@ -25,42 +27,61 @@ impl Column {
#[derive(Default)]
pub struct Columns {
/// Columns are simply routers into settings, timelines, etc
columns: Vec<Column>,
columns: IndexMap<u32, 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>,
pub timelines: IndexMap<u32, Timeline>,

/// The selected column for key navigation
selected: i32,
should_delete_column_at_index: Option<usize>,
}
static UIDS: AtomicU32 = AtomicU32::new(0);

impl Columns {
pub fn new() -> Self {
Columns::default()
}

pub fn add_timeline(&mut self, timeline: Timeline) {
let id = Self::get_new_id();
let routes = vec![Route::timeline(timeline.id)];
self.timelines.push(timeline);
self.columns.push(Column::new(routes))
}

pub fn add_timeline_to_column(&mut self, col: usize, timeline: Timeline) -> bool {
if let Some(column) = self.columns.get_mut(col) {
column
.router_mut()
.route_to_replaced(Route::timeline(timeline.id));
self.timelines.push(timeline);
true
} else {
false
}
self.timelines.insert(id, timeline);
self.columns.insert(id, Column::new(routes));
}

pub fn add_timeline_to_column(&mut self, col: usize, timeline: Timeline) {
let col_id = *self
.columns
.get_index(col)
.expect("expected index to be within bounds")
.0;
self.column_mut(col)
.router_mut()
.route_to_replaced(Route::timeline(timeline.id));
self.timelines.insert(col_id, timeline);
}

pub fn new_column_picker(&mut self) {
self.columns.push(Column::new(vec![Route::AddColumn]));
self.add_column(Column::new(vec![Route::AddColumn]));
}

fn get_new_id() -> u32 {
UIDS.fetch_add(1, Ordering::Relaxed)
}

pub fn add_column(&mut self, column: Column) {
self.columns.insert(Self::get_new_id(), column);
}

pub fn columns_mut(&mut self) -> Vec<&mut Column> {
self.columns.values_mut().collect()
}

pub fn num_columns(&self) -> usize {
self.columns.len()
}

// Get the first router in the columns if there are columns present.
Expand All @@ -70,49 +91,66 @@ impl Columns {
self.new_column_picker();
}
self.columns
.get_mut(0)
.get_index_mut(0)
.expect("There should be at least one column")
.1
.router_mut()
}

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]
self.timelines
.get_index_mut(timeline_ind)
.expect("expected index to be in bounds")
.1
}

pub fn column(&self, ind: usize) -> &Column {
&self.columns()[ind]
self.columns
.get_index(ind)
.expect("Expected index to be in bounds")
.1
}

pub fn columns(&self) -> Vec<&Column> {
self.columns.values().collect()
}

pub fn columns(&self) -> &Vec<Column> {
&self.columns
pub fn get_column_id_at_index(&self, ind: usize) -> u32 {
*self
.columns
.get_index(ind)
.expect("expected index to be within bounds")
.0
}

pub fn selected(&mut self) -> &mut Column {
&mut self.columns[self.selected as usize]
self.columns
.get_index_mut(self.selected as usize)
.expect("Expected selected index to be in bounds")
.1
}

pub fn timelines_mut(&mut self) -> &mut Vec<Timeline> {
&mut self.timelines
pub fn timelines_mut(&mut self) -> Vec<&mut Timeline> {
self.timelines.values_mut().collect()
}

pub fn timelines(&self) -> &Vec<Timeline> {
&self.timelines
pub fn timelines(&self) -> Vec<&Timeline> {
self.timelines.values().collect()
}

pub fn find_timeline_mut(&mut self, id: TimelineId) -> Option<&mut Timeline> {
self.timelines_mut().iter_mut().find(|tl| tl.id == id)
self.timelines_mut().into_iter().find(|tl| tl.id == id)
}

pub fn find_timeline(&self, id: TimelineId) -> Option<&Timeline> {
self.timelines().iter().find(|tl| tl.id == id)
self.timelines().into_iter().find(|tl| tl.id == id)
}

pub fn column_mut(&mut self, ind: usize) -> &mut Column {
&mut self.columns[ind]
self.columns
.get_index_mut(ind)
.expect("Expected index to be in bounds")
.1
}

pub fn select_down(&mut self) {
Expand All @@ -136,4 +174,24 @@ impl Columns {
}
self.selected += 1;
}

pub fn request_deletion_at_index(&mut self, index: usize) {
info!("sent deletion request");
self.should_delete_column_at_index = Some(index);
}

pub fn attempt_perform_deletion_request(&mut self) {
if let Some(index) = self.should_delete_column_at_index {
if let Some((key, _)) = self.columns.get_index_mut(index) {
self.timelines.shift_remove(key);
}

self.columns.shift_remove_index(index);
self.should_delete_column_at_index = None;

if self.columns.is_empty() {
self.new_column_picker();
}
}
}
}
15 changes: 12 additions & 3 deletions src/fonts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use tracing::debug;

pub enum NamedFontFamily {
Medium,
Bold,
}

impl NamedFontFamily {
pub fn as_str(&mut self) -> &'static str {
match self {
//Self::Bold => "bold",
Self::Bold => "bold",
Self::Medium => "medium",
}
}
Expand Down Expand Up @@ -43,14 +44,15 @@ pub fn setup_fonts(ctx: &egui::Context) {
"DejaVuSans".to_owned(),
FontData::from_static(include_bytes!("../assets/fonts/DejaVuSansSansEmoji.ttf")),
);
/*

font_data.insert(
"OnestBold".to_owned(),
FontData::from_static(include_bytes!(
"../assets/fonts/onest/OnestBold1602-hint.ttf"
)),
);

/*
font_data.insert(
"DejaVuSansBold".to_owned(),
FontData::from_static(include_bytes!(
Expand Down Expand Up @@ -119,14 +121,21 @@ pub fn setup_fonts(ctx: &egui::Context) {
medium.extend(base_fonts.clone());

let mut mono = vec!["Inconsolata".to_owned()];
mono.extend(base_fonts);
mono.extend(base_fonts.clone());

let mut bold = vec!["OnestBold".to_owned()];
bold.extend(base_fonts);

families.insert(egui::FontFamily::Proportional, proportional);
families.insert(egui::FontFamily::Monospace, mono);
families.insert(
egui::FontFamily::Name(NamedFontFamily::Medium.as_str().into()),
medium,
);
families.insert(
egui::FontFamily::Name(NamedFontFamily::Bold.as_str().into()),
bold,
);

debug!("fonts: {:?}", families);

Expand Down
Loading

0 comments on commit 932b091

Please sign in to comment.