mirror of
https://github.com/damus-io/notedeck.git
synced 2024-09-16 11:53:30 +00:00
ui: integrate egui-tabs for notes & replies selector
demo: https://cdn.jb55.com/s/notedeck-tabs.mp4 Fixes: https://github.com/damus-io/notedeck/issues/47 Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
029896627c
commit
9e8f7a2e5c
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -1035,6 +1035,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui-tabs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/damus-io/egui-tabs?rev=ed97a57fc66b3781bc10ab644f9e1ed125d7377a#ed97a57fc66b3781bc10ab644f9e1ed125d7377a"
|
||||
dependencies = [
|
||||
"egui",
|
||||
"egui_extras",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "egui-wgpu"
|
||||
version = "0.27.2"
|
||||
@ -2445,6 +2454,7 @@ dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"eframe",
|
||||
"egui",
|
||||
"egui-tabs",
|
||||
"egui_extras",
|
||||
"egui_virtual_list",
|
||||
"ehttp 0.2.0",
|
||||
|
@ -19,6 +19,7 @@ eframe = { version = "0.27.2", default-features = false, features = [ "glow", "w
|
||||
#eframe = "0.22.0"
|
||||
egui_extras = { version = "0.27.2", features = ["all_loaders"] }
|
||||
ehttp = "0.2.0"
|
||||
egui-tabs = { git = "https://github.com/damus-io/egui-tabs", rev = "ed97a57fc66b3781bc10ab644f9e1ed125d7377a" }
|
||||
reqwest = { version = "0.12.4", default-features = false, features = [ "rustls-tls-native-roots" ] }
|
||||
image = { version = "0.24", features = ["jpeg", "png", "webp"] }
|
||||
log = "0.4.17"
|
||||
|
@ -56,9 +56,9 @@ fn relay_setup(pool: &mut RelayPool, ctx: &egui::Context) {
|
||||
if let Err(e) = pool.add_url("wss://relay.damus.io".to_string(), wakeup.clone()) {
|
||||
error!("{:?}", e)
|
||||
}
|
||||
if let Err(e) = pool.add_url("wss://pyramid.fiatjaf.com".to_string(), wakeup.clone()) {
|
||||
error!("{:?}", e)
|
||||
}
|
||||
//if let Err(e) = pool.add_url("wss://pyramid.fiatjaf.com".to_string(), wakeup.clone()) {
|
||||
//error!("{:?}", e)
|
||||
//}
|
||||
if let Err(e) = pool.add_url("wss://nos.lol".to_string(), wakeup.clone()) {
|
||||
error!("{:?}", e)
|
||||
}
|
||||
|
@ -41,6 +41,10 @@ pub fn setup_cc(cc: &eframe::CreationContext<'_>) {
|
||||
setup_fonts(ctx);
|
||||
|
||||
//ctx.set_pixels_per_point(ctx.pixels_per_point() + UI_SCALE_FACTOR);
|
||||
//ctx.set_pixels_per_point(1.0);
|
||||
//
|
||||
//
|
||||
//ctx.tessellation_options_mut(|to| to.feathering = false);
|
||||
|
||||
egui_extras::install_image_loaders(ctx);
|
||||
|
||||
|
@ -15,6 +15,7 @@ const DARK_BG: Color32 = Color32::from_rgb(0x2C, 0x2C, 0x2C);
|
||||
const DARK_ISH_BG: Color32 = Color32::from_rgb(0x22, 0x22, 0x22);
|
||||
const SEMI_DARK_BG: Color32 = Color32::from_rgb(0x44, 0x44, 0x44);
|
||||
|
||||
const LIGHTER_GRAY: Color32 = Color32::from_rgb(0xe8, 0xe8, 0xe8);
|
||||
const LIGHT_GRAY: Color32 = Color32::from_rgb(0xc8, 0xc8, 0xc8); // 78%
|
||||
pub const MID_GRAY: Color32 = Color32::from_rgb(0xbd, 0xbd, 0xbd);
|
||||
const DARKER_GRAY: Color32 = Color32::from_rgb(0xa5, 0xa5, 0xa5); // 65%
|
||||
@ -99,7 +100,7 @@ pub fn light_color_theme() -> ColorTheme {
|
||||
// NONINTERACTIVE WIDGET
|
||||
noninteractive_bg_fill: Color32::WHITE,
|
||||
noninteractive_weak_bg_fill: EVEN_DARKER_GRAY,
|
||||
noninteractive_bg_stroke_color: DARKER_GRAY,
|
||||
noninteractive_bg_stroke_color: LIGHTER_GRAY,
|
||||
noninteractive_fg_stroke_color: GRAY_SECONDARY,
|
||||
|
||||
// INACTIVE WIDGET
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::{ui, Damus};
|
||||
use egui::containers::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Direction, Layout};
|
||||
use egui_tabs::TabColor;
|
||||
use egui_virtual_list::VirtualList;
|
||||
use enostr::Filter;
|
||||
use nostrdb::{NoteKey, Subscription, Transaction};
|
||||
@ -56,6 +58,90 @@ impl Timeline {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_label_width(ui: &mut egui::Ui, text: &str) -> f32 {
|
||||
let font_id = egui::FontId::default();
|
||||
let galley = ui.fonts(|r| r.layout_no_wrap(text.to_string(), font_id, egui::Color32::WHITE));
|
||||
galley.rect.width()
|
||||
}
|
||||
|
||||
fn shrink_range_to_width(range: egui::Rangef, width: f32) -> egui::Rangef {
|
||||
let midpoint = (range.min + range.max) / 2.0;
|
||||
let half_width = width / 2.0;
|
||||
|
||||
let min = midpoint - half_width;
|
||||
let max = midpoint + half_width;
|
||||
|
||||
egui::Rangef::new(min, max)
|
||||
}
|
||||
|
||||
fn tabs_ui(ui: &mut egui::Ui) {
|
||||
ui.spacing_mut().item_spacing.y = 0.0;
|
||||
|
||||
let tab_res = egui_tabs::Tabs::new(2)
|
||||
.hover_bg(TabColor::none())
|
||||
.selected_fg(TabColor::none())
|
||||
.selected_bg(TabColor::none())
|
||||
.hover_bg(TabColor::none())
|
||||
//.hover_bg(TabColor::custom(egui::Color32::RED))
|
||||
.height(32.0)
|
||||
.layout(Layout::centered_and_justified(Direction::TopDown))
|
||||
.show(ui, |ui, state| {
|
||||
ui.spacing_mut().item_spacing.y = 0.0;
|
||||
|
||||
let ind = state.index();
|
||||
|
||||
let txt = if ind == 0 { "Notes" } else { "Notes & Replies" };
|
||||
|
||||
let res = ui.add(egui::Label::new(txt).selectable(false));
|
||||
|
||||
// underline
|
||||
if state.is_selected() {
|
||||
let rect = res.rect;
|
||||
let underline = rect.x_range().shrink(rect.width() / 4.0);
|
||||
let underline = shrink_range_to_width(underline, get_label_width(ui, txt) * 1.15);
|
||||
let underline_y = ui.painter().round_to_pixel(rect.bottom()) - 1.5;
|
||||
return (underline, underline_y);
|
||||
}
|
||||
|
||||
(egui::Rangef::new(0.0, 0.0), 0.0)
|
||||
});
|
||||
|
||||
//ui.add_space(0.5);
|
||||
ui::hline(ui);
|
||||
|
||||
// fun animation
|
||||
if let Some(sel) = tab_res.selected() {
|
||||
let (underline, underline_y) = tab_res.inner()[sel as usize].inner;
|
||||
let underline_width = underline.span();
|
||||
|
||||
let tab_anim_id = ui.id().with("tab_anim");
|
||||
let tab_anim_size = tab_anim_id.with("size");
|
||||
|
||||
let stroke = egui::Stroke {
|
||||
color: ui.visuals().hyperlink_color,
|
||||
width: 3.0,
|
||||
};
|
||||
|
||||
let speed = 0.1f32;
|
||||
|
||||
// animate underline position
|
||||
let x = ui
|
||||
.ctx()
|
||||
.animate_value_with_time(tab_anim_id, underline.min, speed);
|
||||
|
||||
// animate underline width
|
||||
let w = ui
|
||||
.ctx()
|
||||
.animate_value_with_time(tab_anim_size, underline_width, speed);
|
||||
|
||||
let underline = egui::Rangef::new(x, x + w);
|
||||
|
||||
ui.painter().hline(underline, underline_y, stroke);
|
||||
}
|
||||
|
||||
ui.add_space(3.0);
|
||||
}
|
||||
|
||||
pub fn timeline_view(ui: &mut egui::Ui, app: &mut Damus, timeline: usize) {
|
||||
//padding(4.0, ui, |ui| ui.heading("Notifications"));
|
||||
/*
|
||||
@ -63,14 +149,10 @@ pub fn timeline_view(ui: &mut egui::Ui, app: &mut Damus, timeline: usize) {
|
||||
let row_height = ui.fonts(|f| f.row_height(&font_id)) + ui.spacing().item_spacing.y;
|
||||
*/
|
||||
|
||||
tabs_ui(ui);
|
||||
|
||||
egui::ScrollArea::vertical()
|
||||
.scroll_bar_visibility(ScrollBarVisibility::AlwaysVisible)
|
||||
//.auto_shrink([false; 2])
|
||||
/*
|
||||
.show_viewport(ui, |ui, viewport| {
|
||||
render_notes_in_viewport(ui, app, viewport, row_height, font_id);
|
||||
});
|
||||
*/
|
||||
.show(ui, |ui| {
|
||||
let len = app.timelines[timeline].notes.len();
|
||||
let list = app.timelines[timeline].list.clone();
|
||||
|
Loading…
Reference in New Issue
Block a user