From 5120686679f0c0d2d595b33e5453f1ec69d5bbb6 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Thu, 26 Sep 2024 12:17:12 -0700 Subject: [PATCH] context: fix hitbox, float on far right This updates the context menu to "float" instead of using the layout engine. This is so that we don't take up an unnecessary amount of space when we increase the hitbox height. Signed-off-by: William Casarin --- src/ui/note/context.rs | 32 ++++++++++++++++++++++++-------- src/ui/note/mod.rs | 24 ++++++++++++++++++------ 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/ui/note/context.rs b/src/ui/note/context.rs index ba4aed4..5ce9bf6 100644 --- a/src/ui/note/context.rs +++ b/src/ui/note/context.rs @@ -1,5 +1,5 @@ use crate::colors; -use egui::Vec2; +use egui::{Rect, Vec2}; use enostr::{NoteId, Pubkey}; use nostrdb::{Note, NoteKey}; @@ -38,18 +38,35 @@ impl NoteContextSelection { } pub struct NoteContextButton { + put_at: Option, note_key: NoteKey, } impl egui::Widget for NoteContextButton { fn ui(self, ui: &mut egui::Ui) -> egui::Response { - Self::show(ui, self.note_key) + let r = if let Some(r) = self.put_at { + r + } else { + let mut place = ui.available_rect_before_wrap(); + let size = Self::max_width(); + place.set_width(size); + place.set_height(size); + place + }; + + Self::show(ui, self.note_key, r) } } impl NoteContextButton { pub fn new(note_key: NoteKey) -> Self { - NoteContextButton { note_key } + let put_at: Option = None; + NoteContextButton { note_key, put_at } + } + + pub fn place_at(mut self, rect: Rect) -> Self { + self.put_at = Some(rect); + self } pub fn max_width() -> f32 { @@ -81,13 +98,12 @@ impl NoteContextButton { Self::max_distance_between_circles() / Self::expansion_multiple() } - pub fn show(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response { + 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 size = Self::size(); - let (rect, response) = ui.allocate_exact_size(size, egui::Sense::click()); + let response = ui.interact(put_at, id, egui::Sense::click()); let animation_progress = ui.ctx() @@ -99,7 +115,7 @@ impl NoteContextButton { let cur_radius = min_radius + (Self::max_radius() - min_radius) * animation_progress; - let center = rect.center(); + 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); @@ -109,7 +125,7 @@ impl NoteContextButton { let color = colors::GRAY_SECONDARY; // Draw circles - let painter = ui.painter_at(rect); + 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); diff --git a/src/ui/note/mod.rs b/src/ui/note/mod.rs index 6d9a5fb..544d242 100644 --- a/src/ui/note/mod.rs +++ b/src/ui/note/mod.rs @@ -20,7 +20,7 @@ use crate::{ notecache::{CachedNote, NoteCache}, ui::{self, View}, }; -use egui::{Id, Label, Response, RichText, Sense}; +use egui::{Id, Label, Pos2, Rect, Response, RichText, Sense}; use enostr::NoteId; use nostrdb::{Ndb, Note, NoteKey, NoteReply, Transaction}; @@ -396,6 +396,7 @@ impl<'a> NoteView<'a> { note: &Note, profile: &Result, nostrdb::Error>, options: NoteOptions, + container_right: Pos2, ) -> NoteResponse { let note_key = note.key().unwrap(); @@ -407,11 +408,14 @@ impl<'a> NoteView<'a> { render_reltime(ui, cached_note, true); if options.has_options_button() { - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - let resp = ui.add(NoteContextButton::new(note_key)); - NoteContextButton::menu(ui, resp) - }) - .inner + let context_pos = { + let size = NoteContextButton::max_width(); + let min = Pos2::new(container_right.x - size, container_right.y); + Rect::from_min_size(min, egui::vec2(size, size)) + }; + + let resp = ui.add(NoteContextButton::new(note_key).place_at(context_pos)); + NoteContextButton::menu(ui, resp.clone()) } else { None } @@ -429,6 +433,12 @@ impl<'a> NoteView<'a> { let mut selected_option: Option = None; let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey()); let maybe_hitbox = maybe_note_hitbox(ui, note_key); + let container_right = { + let r = ui.available_rect_before_wrap(); + let x = r.max.x; + let y = r.min.y; + Pos2::new(x, y) + }; // wide design let response = if self.options().has_wide() { @@ -445,6 +455,7 @@ impl<'a> NoteView<'a> { self.note, &profile, self.options(), + container_right, ) .context_selection; }) @@ -492,6 +503,7 @@ impl<'a> NoteView<'a> { self.note, &profile, self.options(), + container_right, ) .context_selection; ui.horizontal(|ui| {