notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit d8e027490ce0c2ad8a08a0f75702a4311522838c
parent 3ccd6a97a4352ba13e4d8c1dbe3da91e6b737a6e
Author: kernelkind <kernelkind@gmail.com>
Date:   Sun,  5 Oct 2025 15:32:51 -0400

refactor: move shared context stuff up in scope

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck_ui/src/context_menu.rs | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/notedeck_ui/src/note/context.rs | 62+++-----------------------------------------------------------
2 files changed, 55 insertions(+), 59 deletions(-)

diff --git a/crates/notedeck_ui/src/context_menu.rs b/crates/notedeck_ui/src/context_menu.rs @@ -51,3 +51,55 @@ pub fn input_context( // for keyboard visibility crate::include_input(ui, response) } + +pub fn stationary_arbitrary_menu_button<R>( + ui: &mut egui::Ui, + button_response: egui::Response, + add_contents: impl FnOnce(&mut egui::Ui) -> R, +) -> egui::InnerResponse<Option<R>> { + let bar_id = ui.id(); + let mut bar_state = egui::menu::BarState::load(ui.ctx(), bar_id); + + let inner = bar_state.bar_menu(&button_response, add_contents); + + bar_state.store(ui.ctx(), bar_id); + egui::InnerResponse::new(inner.map(|r| r.inner), button_response) +} + +pub fn context_button(ui: &mut egui::Ui, id: egui::Id, put_at: egui::Rect) -> egui::Response { + let min_radius = 2.0; + let anim_speed = 0.05; + let response = ui.interact(put_at, id, egui::Sense::click()); + + let hovered = response.hovered(); + let animation_progress = ui.ctx().animate_bool_with_time(id, hovered, anim_speed); + + if hovered { + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + } + + let max_distance = 2.0; + let expansion_mult = 2.0; + let min_distance = max_distance / expansion_mult; + let cur_distance = min_distance + (max_distance - min_distance) * animation_progress; + + let max_radius = 4.0; + let cur_radius = min_radius + (max_radius - min_radius) * animation_progress; + + let center = put_at.center(); + let left_circle_center = center - egui::vec2(cur_distance + cur_radius, 0.0); + let right_circle_center = center + egui::vec2(cur_distance + cur_radius, 0.0); + + let translated_radius = (cur_radius - 1.0) / 2.0; + + // This works in both themes + let color = ui.style().visuals.noninteractive().fg_stroke.color; + + // Draw circles + let painter = ui.painter_at(put_at); + painter.circle_filled(left_circle_center, translated_radius, color); + painter.circle_filled(center, translated_radius, color); + painter.circle_filled(right_circle_center, translated_radius, color); + + response +} diff --git a/crates/notedeck_ui/src/note/context.rs b/crates/notedeck_ui/src/note/context.rs @@ -2,6 +2,8 @@ use egui::{Rect, Vec2}; use nostrdb::NoteKey; use notedeck::{tr, BroadcastContext, Localization, NoteContextSelection}; +use crate::context_menu::{context_button, stationary_arbitrary_menu_button}; + pub struct NoteContextButton { put_at: Option<Rect>, note_key: NoteKey, @@ -47,59 +49,15 @@ impl NoteContextButton { 4.0 } - fn min_radius() -> f32 { - 2.0 - } - fn max_distance_between_circles() -> f32 { 2.0 } - fn expansion_multiple() -> f32 { - 2.0 - } - - fn min_distance_between_circles() -> f32 { - Self::max_distance_between_circles() / Self::expansion_multiple() - } - #[profiling::function] pub fn show(ui: &mut egui::Ui, note_key: NoteKey, put_at: Rect) -> egui::Response { let id = ui.id().with(("more_options_anim", note_key)); - let min_radius = Self::min_radius(); - let anim_speed = 0.05; - let response = ui.interact(put_at, id, egui::Sense::click()); - - let hovered = response.hovered(); - let animation_progress = ui.ctx().animate_bool_with_time(id, hovered, anim_speed); - - if hovered { - ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); - } - - let min_distance = Self::min_distance_between_circles(); - let cur_distance = min_distance - + (Self::max_distance_between_circles() - min_distance) * animation_progress; - - let cur_radius = min_radius + (Self::max_radius() - min_radius) * animation_progress; - - let center = put_at.center(); - let left_circle_center = center - egui::vec2(cur_distance + cur_radius, 0.0); - let right_circle_center = center + egui::vec2(cur_distance + cur_radius, 0.0); - - let translated_radius = (cur_radius - 1.0) / 2.0; - - // This works in both themes - let color = ui.style().visuals.noninteractive().fg_stroke.color; - - // Draw circles - let painter = ui.painter_at(put_at); - painter.circle_filled(left_circle_center, translated_radius, color); - painter.circle_filled(center, translated_radius, color); - painter.circle_filled(right_circle_center, translated_radius, color); - - response + context_button(ui, id, put_at) } #[profiling::function] @@ -189,17 +147,3 @@ impl NoteContextButton { context_selection } } - -fn stationary_arbitrary_menu_button<R>( - ui: &mut egui::Ui, - button_response: egui::Response, - add_contents: impl FnOnce(&mut egui::Ui) -> R, -) -> egui::InnerResponse<Option<R>> { - let bar_id = ui.id(); - let mut bar_state = egui::menu::BarState::load(ui.ctx(), bar_id); - - let inner = bar_state.bar_menu(&button_response, add_contents); - - bar_state.store(ui.ctx(), bar_id); - egui::InnerResponse::new(inner.map(|r| r.inner), button_response) -}