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 <jb55@jb55.com>
This commit is contained in:
William Casarin
2024-09-26 12:17:12 -07:00
parent 2dba41186d
commit 5120686679
2 changed files with 42 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
use crate::colors; use crate::colors;
use egui::Vec2; use egui::{Rect, Vec2};
use enostr::{NoteId, Pubkey}; use enostr::{NoteId, Pubkey};
use nostrdb::{Note, NoteKey}; use nostrdb::{Note, NoteKey};
@@ -38,18 +38,35 @@ impl NoteContextSelection {
} }
pub struct NoteContextButton { pub struct NoteContextButton {
put_at: Option<Rect>,
note_key: NoteKey, note_key: NoteKey,
} }
impl egui::Widget for NoteContextButton { impl egui::Widget for NoteContextButton {
fn ui(self, ui: &mut egui::Ui) -> egui::Response { 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 { impl NoteContextButton {
pub fn new(note_key: NoteKey) -> Self { pub fn new(note_key: NoteKey) -> Self {
NoteContextButton { note_key } let put_at: Option<Rect> = 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 { pub fn max_width() -> f32 {
@@ -81,13 +98,12 @@ impl NoteContextButton {
Self::max_distance_between_circles() / Self::expansion_multiple() 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 id = ui.id().with(("more_options_anim", note_key));
let min_radius = Self::min_radius(); let min_radius = Self::min_radius();
let anim_speed = 0.05; let anim_speed = 0.05;
let size = Self::size(); let response = ui.interact(put_at, id, egui::Sense::click());
let (rect, response) = ui.allocate_exact_size(size, egui::Sense::click());
let animation_progress = let animation_progress =
ui.ctx() ui.ctx()
@@ -99,7 +115,7 @@ impl NoteContextButton {
let cur_radius = min_radius + (Self::max_radius() - min_radius) * animation_progress; 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 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 right_circle_center = center + egui::vec2(cur_distance + cur_radius, 0.0);
@@ -109,7 +125,7 @@ impl NoteContextButton {
let color = colors::GRAY_SECONDARY; let color = colors::GRAY_SECONDARY;
// Draw circles // 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(left_circle_center, translated_radius, color);
painter.circle_filled(center, translated_radius, color); painter.circle_filled(center, translated_radius, color);
painter.circle_filled(right_circle_center, translated_radius, color); painter.circle_filled(right_circle_center, translated_radius, color);

View File

@@ -20,7 +20,7 @@ use crate::{
notecache::{CachedNote, NoteCache}, notecache::{CachedNote, NoteCache},
ui::{self, View}, ui::{self, View},
}; };
use egui::{Id, Label, Response, RichText, Sense}; use egui::{Id, Label, Pos2, Rect, Response, RichText, Sense};
use enostr::NoteId; use enostr::NoteId;
use nostrdb::{Ndb, Note, NoteKey, NoteReply, Transaction}; use nostrdb::{Ndb, Note, NoteKey, NoteReply, Transaction};
@@ -396,6 +396,7 @@ impl<'a> NoteView<'a> {
note: &Note, note: &Note,
profile: &Result<nostrdb::ProfileRecord<'_>, nostrdb::Error>, profile: &Result<nostrdb::ProfileRecord<'_>, nostrdb::Error>,
options: NoteOptions, options: NoteOptions,
container_right: Pos2,
) -> NoteResponse { ) -> NoteResponse {
let note_key = note.key().unwrap(); let note_key = note.key().unwrap();
@@ -407,11 +408,14 @@ impl<'a> NoteView<'a> {
render_reltime(ui, cached_note, true); render_reltime(ui, cached_note, true);
if options.has_options_button() { if options.has_options_button() {
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { let context_pos = {
let resp = ui.add(NoteContextButton::new(note_key)); let size = NoteContextButton::max_width();
NoteContextButton::menu(ui, resp) let min = Pos2::new(container_right.x - size, container_right.y);
}) Rect::from_min_size(min, egui::vec2(size, size))
.inner };
let resp = ui.add(NoteContextButton::new(note_key).place_at(context_pos));
NoteContextButton::menu(ui, resp.clone())
} else { } else {
None None
} }
@@ -429,6 +433,12 @@ impl<'a> NoteView<'a> {
let mut selected_option: Option<NoteContextSelection> = None; let mut selected_option: Option<NoteContextSelection> = None;
let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey()); let profile = self.ndb.get_profile_by_pubkey(txn, self.note.pubkey());
let maybe_hitbox = maybe_note_hitbox(ui, note_key); 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 // wide design
let response = if self.options().has_wide() { let response = if self.options().has_wide() {
@@ -445,6 +455,7 @@ impl<'a> NoteView<'a> {
self.note, self.note,
&profile, &profile,
self.options(), self.options(),
container_right,
) )
.context_selection; .context_selection;
}) })
@@ -492,6 +503,7 @@ impl<'a> NoteView<'a> {
self.note, self.note,
&profile, &profile,
self.options(), self.options(),
container_right,
) )
.context_selection; .context_selection;
ui.horizontal(|ui| { ui.horizontal(|ui| {