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 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<Rect>,
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<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 {
@@ -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);

View File

@@ -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::ProfileRecord<'_>, 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<NoteContextSelection> = 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| {