MoreMenu: Move button creation outside of MoreMenu to give more control over button style

This commit is contained in:
Bu5hm4nn 2024-04-25 19:12:11 -06:00
parent 0cbd000245
commit f97bdf4733
7 changed files with 104 additions and 91 deletions

View File

@ -420,9 +420,14 @@ pub fn render_note_inner(
let mut next_page = None; let mut next_page = None;
ui.with_layout(Layout::right_to_left(Align::TOP), |ui| { ui.with_layout(Layout::right_to_left(Align::TOP), |ui| {
widgets::MoreMenu::simple(&app.theme, &app.assets, ui.next_auto_id()) let text = egui::RichText::new("=").size(13.0);
.small_button() let response = widgets::Button::primary(&app.theme, text)
.show(ui, |ui, keep_open| { .small(true)
.show(ui);
widgets::MoreMenu::simple(ui.next_auto_id()).show(
ui,
response,
|ui, keep_open| {
let relays: Vec<UncheckedUrl> = note let relays: Vec<UncheckedUrl> = note
.seen_on .seen_on
.iter() .iter()
@ -562,7 +567,8 @@ pub fn render_note_inner(
app.notes.cache_invalidate_note(&note.event.id); app.notes.cache_invalidate_note(&note.event.id);
*keep_open = false; *keep_open = false;
} }
}); },
);
ui.add_space(4.0); ui.add_space(4.0);
let is_thread_view: bool = { let is_thread_view: bool = {

View File

@ -229,11 +229,12 @@ fn dm_posting_area(
ui.add_space(8.0); ui.add_space(8.0);
ui.horizontal(|ui| { ui.horizontal(|ui| {
widgets::MoreMenu::bubble(&app.theme, &app.assets, ui.next_auto_id()) let response = widgets::options_menu_button(ui, &app.theme, &app.assets);
widgets::MoreMenu::bubble(ui.next_auto_id())
.with_max_size(vec2(190.0, 40.0)) .with_max_size(vec2(190.0, 40.0))
.with_min_size(vec2(190.0, 40.0)) .with_min_size(vec2(190.0, 40.0))
.place_above(!read_setting!(posting_area_at_top)) .place_above(!read_setting!(posting_area_at_top))
.show(ui, |ui, is_open| { .show(ui, response, |ui, is_open| {
ui.vertical_centered_justified(|ui| { ui.vertical_centered_justified(|ui| {
if app.dm_draft_data.include_subject { if app.dm_draft_data.include_subject {
if widgets::Button::primary(&app.theme, "Remove Subject") if widgets::Button::primary(&app.theme, "Remove Subject")
@ -530,11 +531,12 @@ fn real_posting_area(app: &mut GossipUi, ctx: &Context, ui: &mut Ui) {
if app.draft_data.raw.is_empty() { if app.draft_data.raw.is_empty() {
// show advanced action menu // show advanced action menu
if app.draft_data.repost.is_none() { if app.draft_data.repost.is_none() {
widgets::MoreMenu::bubble(&app.theme, &app.assets, ui.next_auto_id()) let response = widgets::options_menu_button(ui, &app.theme, &app.assets);
widgets::MoreMenu::bubble(ui.next_auto_id())
.with_max_size(vec2(180.0, 80.0)) .with_max_size(vec2(180.0, 80.0))
.with_min_size(vec2(180.0, 80.0)) .with_min_size(vec2(180.0, 80.0))
.place_above(!read_setting!(posting_area_at_top)) .place_above(!read_setting!(posting_area_at_top))
.show(ui, |ui, is_open| { .show(ui, response, |ui, is_open| {
ui.vertical_centered_justified(|ui| { ui.vertical_centered_justified(|ui| {
if app.draft_data.include_subject { if app.draft_data.include_subject {
if widgets::Button::primary(&app.theme, "Remove Subject") if widgets::Button::primary(&app.theme, "Remove Subject")

View File

@ -293,12 +293,14 @@ pub(super) fn update(
egui::Layout::right_to_left(egui::Align::Min) egui::Layout::right_to_left(egui::Align::Min)
.with_cross_align(egui::Align::Center), .with_cross_align(egui::Align::Center),
|ui| { |ui| {
widgets::MoreMenu::simple( let text = egui::RichText::new("=").size(13.0);
&app.theme, let response = widgets::Button::primary(&app.theme, text)
&app.assets, .small(true)
ui.next_auto_id(), .show(ui);
) widgets::MoreMenu::simple(ui.next_auto_id()).show(
.show(ui, |ui, is_open| { ui,
response,
|ui, is_open| {
// actions // actions
if ui.button("Remove").clicked() { if ui.button("Remove").clicked() {
let _ = GLOBALS.storage.remove_person_from_list( let _ = GLOBALS.storage.remove_person_from_list(
@ -308,7 +310,8 @@ pub(super) fn update(
); );
*is_open = false; *is_open = false;
} }
}); },
);
ui.add_space(20.0); ui.add_space(20.0);
@ -768,11 +771,16 @@ pub(super) fn render_more_list_actions(
return; return;
} }
let menu = widgets::MoreMenu::simple(&app.theme, &app.assets, ui.next_auto_id()) let text = egui::RichText::new("=").size(13.0);
let response = widgets::Button::primary(&app.theme, text)
.small(true)
.show(ui);
let menu = widgets::MoreMenu::simple(ui.next_auto_id())
.with_min_size(vec2(100.0, 0.0)) .with_min_size(vec2(100.0, 0.0))
.with_max_size(vec2(160.0, f32::INFINITY)); .with_max_size(vec2(160.0, f32::INFINITY));
menu.show(ui, |ui, is_open| { menu.show(ui, response, |ui, is_open| {
ui.with_layout(egui::Layout::top_down_justified(egui::Align::LEFT), |ui| { ui.with_layout(egui::Layout::top_down_justified(egui::Align::LEFT), |ui| {
if on_list { if on_list {
app.theme.primary_button_style(ui.style_mut()); app.theme.primary_button_style(ui.style_mut());

View File

@ -471,10 +471,11 @@ pub(super) fn configure_list_btn(app: &mut GossipUi, ui: &mut Ui) {
ui.add_enabled_ui(true, |ui| { ui.add_enabled_ui(true, |ui| {
let min_size = vec2(180.0, 20.0); let min_size = vec2(180.0, 20.0);
widgets::MoreMenu::bubble(&app.theme, &app.assets, ui.next_auto_id()) let response = widgets::options_menu_button(ui, &app.theme, &app.assets);
widgets::MoreMenu::bubble(ui.next_auto_id())
.with_min_size(min_size) .with_min_size(min_size)
.with_hover_text("Configure List View".to_owned()) .with_hover_text("Configure List View".to_owned())
.show(ui, |ui, is_open| { .show(ui, response, |ui, is_open| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
if widgets::Switch::small(&app.theme, &mut app.relays.show_details) if widgets::Switch::small(&app.theme, &mut app.relays.show_details)
.show(ui) .show(ui)

View File

@ -14,7 +14,7 @@ pub(crate) mod list_entry;
pub use copy_button::{CopyButton, COPY_SYMBOL_SIZE}; pub use copy_button::{CopyButton, COPY_SYMBOL_SIZE};
mod nav_item; mod nav_item;
use eframe::egui::{FontId, Galley}; use eframe::egui::{vec2, FontId, Galley, Rect};
use egui_winit::egui::text::LayoutJob; use egui_winit::egui::text::LayoutJob;
use egui_winit::egui::{ use egui_winit::egui::{
self, Align, FontSelection, Response, RichText, Rounding, Sense, Ui, WidgetText, self, Align, FontSelection, Response, RichText, Rounding, Sense, Ui, WidgetText,
@ -42,6 +42,7 @@ pub use switch::Switch;
mod textedit; mod textedit;
pub use textedit::TextEdit; pub use textedit::TextEdit;
use super::assets::Assets;
use super::{GossipUi, Theme}; use super::{GossipUi, Theme};
pub const DROPDOWN_DISTANCE: f32 = 10.0; pub const DROPDOWN_DISTANCE: f32 = 10.0;
@ -162,6 +163,24 @@ pub fn break_anywhere_hyperlink_to(ui: &mut Ui, text: impl Into<WidgetText>, url
ui.hyperlink_to(job, url); ui.hyperlink_to(job, url);
} }
pub fn options_menu_button(ui: &mut Ui, theme: &Theme, assets: &Assets) -> Response {
let (response, painter) = ui.allocate_painter(vec2(20.0, 20.0), egui::Sense::click());
let btn_rect = response.rect;
let color = if response.hovered() {
theme.accent_color()
} else {
ui.visuals().text_color()
};
let mut mesh = egui::Mesh::with_texture((&assets.options_symbol).into());
mesh.add_rect_with_uv(
btn_rect.shrink(2.0),
Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)),
color,
);
painter.add(egui::Shape::mesh(mesh));
response
}
pub(super) fn set_important_button_visuals(ui: &mut Ui, app: &GossipUi) { pub(super) fn set_important_button_visuals(ui: &mut Ui, app: &GossipUi) {
let visuals = ui.visuals_mut(); let visuals = ui.visuals_mut();
visuals.widgets.inactive.weak_bg_fill = app.theme.accent_color(); visuals.widgets.inactive.weak_bg_fill = app.theme.accent_color();

View File

@ -1,9 +1,5 @@
use eframe::epaint::PathShape; use eframe::{egui::Response, epaint::PathShape};
use egui_winit::egui::{ use egui_winit::egui::{self, vec2, AboveOrBelow, Align2, Id, Ui, Vec2};
self, vec2, AboveOrBelow, Align2, Color32, Id, Rect, TextureHandle, Ui, Vec2,
};
use crate::ui::{assets::Assets, Theme};
static POPUP_MARGIN: Vec2 = Vec2 { x: 20.0, y: 16.0 }; static POPUP_MARGIN: Vec2 = Vec2 { x: 20.0, y: 16.0 };
@ -13,21 +9,17 @@ enum MoreMenuStyle {
Bubble, Bubble,
} }
pub(in crate::ui) struct MoreMenu<'a> { pub(in crate::ui) struct MoreMenu {
id: Id, id: Id,
min_size: Vec2, min_size: Vec2,
max_size: Vec2, max_size: Vec2,
above_or_below: Option<AboveOrBelow>, above_or_below: Option<AboveOrBelow>,
hover_text: Option<String>, hover_text: Option<String>,
small_button: bool,
accent_color: Color32,
options_symbol: TextureHandle,
style: MoreMenuStyle, style: MoreMenuStyle,
theme: &'a Theme,
} }
impl<'a> MoreMenu<'a> { impl MoreMenu {
pub fn simple(theme: &'a Theme, assets: &'a Assets, id: Id) -> Self { pub fn simple(id: Id) -> Self {
Self { Self {
id, id,
min_size: Vec2 { x: 0.0, y: 0.0 }, min_size: Vec2 { x: 0.0, y: 0.0 },
@ -37,15 +29,11 @@ impl<'a> MoreMenu<'a> {
}, },
above_or_below: None, above_or_below: None,
hover_text: None, hover_text: None,
small_button: false,
accent_color: theme.accent_color(),
options_symbol: assets.options_symbol.clone(),
style: MoreMenuStyle::Simple, style: MoreMenuStyle::Simple,
theme,
} }
} }
pub fn bubble(theme: &'a Theme, assets: &'a Assets, id: Id) -> Self { pub fn bubble(id: Id) -> Self {
Self { Self {
id, id,
min_size: Vec2 { x: 0.0, y: 0.0 }, min_size: Vec2 { x: 0.0, y: 0.0 },
@ -55,20 +43,10 @@ impl<'a> MoreMenu<'a> {
}, },
above_or_below: None, above_or_below: None,
hover_text: None, hover_text: None,
small_button: false,
accent_color: theme.accent_color(),
options_symbol: assets.options_symbol.clone(),
style: MoreMenuStyle::Bubble, style: MoreMenuStyle::Bubble,
theme,
} }
} }
#[allow(unused)]
pub fn small_button(mut self) -> Self {
self.small_button = true;
self
}
#[allow(unused)] #[allow(unused)]
pub fn with_id(mut self, id: impl Into<Id>) -> Self { pub fn with_id(mut self, id: impl Into<Id>) -> Self {
self.id = id.into(); self.id = id.into();
@ -103,37 +81,36 @@ impl<'a> MoreMenu<'a> {
self self
} }
pub fn show(&self, ui: &mut Ui, content: impl FnOnce(&mut Ui, &mut bool)) { pub fn show(&self, ui: &mut Ui, response: Response, content: impl FnOnce(&mut Ui, &mut bool)) {
let mut active = self.load_state(ui); let mut active = self.load_state(ui);
let response = match self.style { // let response = match self.style {
MoreMenuStyle::Simple => { // MoreMenuStyle::Simple => {
let text = egui::RichText::new("=").size(13.0); // let text = egui::RichText::new("=").size(13.0);
super::Button::primary(self.theme, text) // super::Button::primary(self.theme, text)
.small(self.small_button) // .small(self.small_button)
.show(ui) // .show(ui)
} // }
MoreMenuStyle::Bubble => { // MoreMenuStyle::Bubble => {
let (response, painter) = // let (response, painter) =
ui.allocate_painter(vec2(20.0, 20.0), egui::Sense::click()); // ui.allocate_painter(vec2(20.0, 20.0), egui::Sense::click());
let btn_rect = response.rect; // let btn_rect = response.rect;
let color = if response.hovered() { // let color = if response.hovered() {
self.accent_color // self.accent_color
} else { // } else {
ui.visuals().text_color() // ui.visuals().text_color()
}; // };
let mut mesh = egui::Mesh::with_texture((&self.options_symbol).into()); // let mut mesh = egui::Mesh::with_texture((&self.options_symbol).into());
mesh.add_rect_with_uv( // mesh.add_rect_with_uv(
btn_rect.shrink(2.0), // btn_rect.shrink(2.0),
Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)), // Rect::from_min_max(egui::pos2(0.0, 0.0), egui::pos2(1.0, 1.0)),
color, // color,
); // );
painter.add(egui::Shape::mesh(mesh)); // painter.add(egui::Shape::mesh(mesh));
response // response
} // }
}; // };
let response = response.on_hover_cursor(egui::CursorIcon::PointingHand);
let response = if let Some(text) = &self.hover_text { let response = if let Some(text) = &self.hover_text {
if !active { if !active {
response.on_hover_text(text) response.on_hover_text(text)

View File

@ -136,13 +136,13 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra
egui::Layout::right_to_left(egui::Align::Min) egui::Layout::right_to_left(egui::Align::Min)
.with_cross_align(egui::Align::Center), .with_cross_align(egui::Align::Center),
|ui| { |ui| {
widgets::MoreMenu::simple( let text = egui::RichText::new("=").size(13.0);
&app.theme, let response = widgets::Button::primary(&app.theme, text)
&app.assets, .small(true)
ui.next_auto_id(), .show(ui);
) widgets::MoreMenu::simple(ui.next_auto_id()).show(
.show(
ui, ui,
response,
|ui, is_open| { |ui, is_open| {
// actions // actions
if ui.button("Remove").clicked() { if ui.button("Remove").clicked() {