mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-29 08:21:47 +00:00
Merge pull request #855 from bu5hm4nn/feature/review-relays-issue-834
UI Review Relays section
This commit is contained in:
commit
81c17fe110
@ -286,10 +286,9 @@ fn dm_posting_area(
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
let response = widgets::options_menu_button(ui, &app.theme, &app.assets);
|
||||
let menu = widgets::MoreMenu::bubble(ui.next_auto_id())
|
||||
.with_max_size(vec2(190.0, 40.0))
|
||||
.with_min_size(vec2(190.0, 40.0))
|
||||
.place_above(!read_setting!(posting_area_at_top));
|
||||
let menu =
|
||||
widgets::MoreMenu::bubble(ui.next_auto_id(), vec2(190.0, 40.0), vec2(190.0, 40.0))
|
||||
.place_above(!read_setting!(posting_area_at_top));
|
||||
|
||||
let mut items: Vec<MoreMenuItem> = Vec::new();
|
||||
if app.dm_draft_data.include_subject {
|
||||
@ -589,10 +588,12 @@ fn real_posting_area(app: &mut GossipUi, ctx: &Context, ui: &mut Ui) {
|
||||
// show advanced action menu
|
||||
if app.draft_data.repost.is_none() {
|
||||
let response = widgets::options_menu_button(ui, &app.theme, &app.assets);
|
||||
let menu = widgets::MoreMenu::bubble(ui.next_auto_id())
|
||||
.with_max_size(vec2(180.0, 80.0))
|
||||
.with_min_size(vec2(180.0, 80.0))
|
||||
.place_above(!read_setting!(posting_area_at_top));
|
||||
let menu = widgets::MoreMenu::bubble(
|
||||
ui.next_auto_id(),
|
||||
vec2(180.0, 80.0),
|
||||
vec2(180.0, 80.0),
|
||||
)
|
||||
.place_above(!read_setting!(posting_area_at_top));
|
||||
|
||||
let mut items: Vec<MoreMenuItem> = Vec::new();
|
||||
|
||||
|
@ -1139,21 +1139,6 @@ impl GossipUi {
|
||||
self.add_menu_item_page(ui, Page::RelaysActivityMonitor, None, true);
|
||||
self.add_menu_item_page(ui, Page::RelaysMine, None, true);
|
||||
self.add_menu_item_page(ui, Page::RelaysKnownNetwork(None), None, true);
|
||||
ui.vertical(|ui| {
|
||||
ui.spacing_mut().button_padding *= 2.0;
|
||||
ui.visuals_mut().widgets.inactive.weak_bg_fill =
|
||||
self.theme.accent_color().linear_multiply(0.2);
|
||||
ui.visuals_mut().widgets.inactive.fg_stroke.width = 1.0;
|
||||
ui.visuals_mut().widgets.hovered.weak_bg_fill = self.theme.navigation_text_color();
|
||||
ui.visuals_mut().widgets.hovered.fg_stroke.color = self.theme.accent_color();
|
||||
if ui
|
||||
.button(RichText::new("Add Relay"))
|
||||
.on_hover_cursor(egui::CursorIcon::PointingHand)
|
||||
.clicked()
|
||||
{
|
||||
relays::start_entry_dialog(self);
|
||||
}
|
||||
});
|
||||
});
|
||||
self.after_openable_menu(ui, &cstate);
|
||||
}
|
||||
|
@ -302,13 +302,11 @@ pub(super) fn update(
|
||||
let response = widgets::Button::primary(&app.theme, text)
|
||||
.small(true)
|
||||
.show(ui);
|
||||
let menu =
|
||||
widgets::MoreMenu::bubble(ui.auto_id_with(person.pubkey))
|
||||
.with_min_size(vec2(100.0, 0.0))
|
||||
.with_max_size(vec2(
|
||||
100.0,
|
||||
ctx.available_rect().height(),
|
||||
));
|
||||
let menu = widgets::MoreMenu::bubble(
|
||||
ui.auto_id_with(person.pubkey),
|
||||
vec2(100.0, 0.0),
|
||||
vec2(100.0, ctx.available_rect().height()),
|
||||
);
|
||||
let mut items: Vec<MoreMenuItem> = Vec::new();
|
||||
|
||||
// actions
|
||||
@ -780,9 +778,11 @@ pub(super) fn render_more_list_actions(
|
||||
.small(true)
|
||||
.show(ui);
|
||||
|
||||
let menu = widgets::MoreMenu::bubble(ui.next_auto_id())
|
||||
.with_min_size(vec2(100.0, 0.0))
|
||||
.with_max_size(vec2(140.0, ui.ctx().available_rect().height()));
|
||||
let menu = widgets::MoreMenu::bubble(
|
||||
ui.next_auto_id(),
|
||||
vec2(100.0, 0.0),
|
||||
vec2(140.0, ui.ctx().available_rect().height()),
|
||||
);
|
||||
|
||||
let mut items: Vec<MoreMenuItem> = Vec::new();
|
||||
items.push(MoreMenuItem::Button(MoreMenuButton::new(
|
||||
|
@ -5,12 +5,12 @@ use crate::ui::widgets;
|
||||
use crate::ui::Page;
|
||||
use eframe::egui;
|
||||
use egui::{Context, Ui};
|
||||
use egui_winit::egui::{Id, RichText};
|
||||
use egui_winit::egui::Id;
|
||||
use gossip_lib::Relay;
|
||||
use gossip_lib::GLOBALS;
|
||||
use nostr_types::RelayUrl;
|
||||
|
||||
pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
|
||||
pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Frame, ui: &mut Ui) {
|
||||
let is_editing = app.relays.edit.is_some();
|
||||
widgets::page_header(ui, Page::RelaysActivityMonitor.name(), |ui| {
|
||||
if is_editing {
|
||||
@ -23,14 +23,13 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra
|
||||
super::relay_sort_combo(app, ui);
|
||||
btn_h_space!(ui);
|
||||
widgets::TextEdit::search(&app.theme, &app.assets, &mut app.relays.search)
|
||||
.desired_width(200.0)
|
||||
.desired_width(150.0)
|
||||
.show(ui);
|
||||
if ui
|
||||
.button(RichText::new(Page::RelaysCoverage.name()))
|
||||
.on_hover_cursor(egui::CursorIcon::PointingHand)
|
||||
if widgets::Button::primary(&app.theme, "Add Relay")
|
||||
.show(ui)
|
||||
.clicked()
|
||||
{
|
||||
app.set_page(ctx, crate::ui::Page::RelaysCoverage);
|
||||
super::start_entry_dialog(app);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -19,8 +19,14 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
super::relay_sort_combo(app, ui);
|
||||
btn_h_space!(ui);
|
||||
widgets::TextEdit::search(&app.theme, &app.assets, &mut app.relays.search)
|
||||
.desired_width(200.0)
|
||||
.desired_width(150.0)
|
||||
.show(ui);
|
||||
if widgets::Button::primary(&app.theme, "Add Relay")
|
||||
.show(ui)
|
||||
.clicked()
|
||||
{
|
||||
super::start_entry_dialog(app);
|
||||
}
|
||||
});
|
||||
|
||||
// TBD time how long this takes. We don't want expensive code in the UI
|
||||
|
@ -21,14 +21,19 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
super::relay_sort_combo(app, ui);
|
||||
btn_h_space!(ui);
|
||||
widgets::TextEdit::search(&app.theme, &app.assets, &mut app.relays.search)
|
||||
.desired_width(200.0)
|
||||
.desired_width(150.0)
|
||||
.show(ui);
|
||||
widgets::set_important_button_visuals(ui, app);
|
||||
if widgets::Button::primary(&app.theme, "Add Relay")
|
||||
.show(ui)
|
||||
.clicked()
|
||||
{
|
||||
super::start_entry_dialog(app);
|
||||
}
|
||||
|
||||
let advertise_remaining = GLOBALS.advertise_jobs_remaining.load(Ordering::Relaxed);
|
||||
if advertise_remaining == 0 {
|
||||
if ui.button("Advertise Relay List")
|
||||
.on_hover_cursor(egui::CursorIcon::PointingHand)
|
||||
if widgets::Button::secondary(&app.theme,"Advertise Relay List")
|
||||
.show(ui)
|
||||
.on_hover_text("Advertise my relays. Will send your relay usage information to every relay that seems to be working well so that other people know how to follow and contact you.")
|
||||
.clicked()
|
||||
{
|
||||
@ -39,7 +44,10 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
} else {
|
||||
ui.add_enabled(
|
||||
false,
|
||||
egui::Button::new(format!("Advertising, {} to go", advertise_remaining)),
|
||||
widgets::Button::secondary(
|
||||
&app.theme,
|
||||
format!("Advertising, {} to go", advertise_remaining),
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -1,9 +1,12 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use super::{widgets, GossipUi, Page};
|
||||
use super::{
|
||||
widgets::{self, MoreMenuButton, MoreMenuItem, MoreMenuSwitch},
|
||||
GossipUi, Page,
|
||||
};
|
||||
use eframe::egui;
|
||||
use egui::{Context, Ui};
|
||||
use egui_winit::egui::{vec2, Id, Rect, RichText};
|
||||
use egui_winit::egui::{vec2, Id, RichText};
|
||||
use gossip_lib::{comms::ToOverlordMessage, Relay, GLOBALS};
|
||||
use nostr_types::RelayUrl;
|
||||
|
||||
@ -295,58 +298,17 @@ pub(super) fn stop_entry_dialog(app: &mut GossipUi) {
|
||||
pub(super) fn entry_dialog(ctx: &Context, app: &mut GossipUi) {
|
||||
let dlg_size = vec2(ctx.screen_rect().width() * 0.66, 120.0);
|
||||
|
||||
egui::Area::new(Id::new("hide-background-area"))
|
||||
.fixed_pos(ctx.screen_rect().left_top())
|
||||
.movable(false)
|
||||
.interactable(false)
|
||||
.order(egui::Order::Middle)
|
||||
.show(ctx, |ui| {
|
||||
ui.painter().rect_filled(
|
||||
ctx.screen_rect(),
|
||||
egui::Rounding::same(0.0),
|
||||
egui::Color32::from_rgba_unmultiplied(0, 0, 0, 80),
|
||||
);
|
||||
});
|
||||
|
||||
let id: Id = "relays-add-dialog".into();
|
||||
let mut frame = egui::Frame::popup(&ctx.style());
|
||||
let area = egui::Area::new(id)
|
||||
.movable(false)
|
||||
.interactable(true)
|
||||
.order(egui::Order::Foreground)
|
||||
.fixed_pos(ctx.screen_rect().center() - vec2(dlg_size.x / 2.0, dlg_size.y));
|
||||
area.show(ctx, |ui| {
|
||||
frame.fill = ui.visuals().extreme_bg_color;
|
||||
frame.inner_margin = egui::Margin::symmetric(20.0, 10.0);
|
||||
frame.show(ui, |ui| {
|
||||
ui.set_min_size(dlg_size);
|
||||
ui.set_max_size(dlg_size);
|
||||
|
||||
// ui.max_rect is inner_margin size
|
||||
let tr = ui.max_rect().right_top();
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.heading("Add a new relay");
|
||||
let rect = Rect::from_x_y_ranges(tr.x..=tr.x + 10.0, tr.y - 20.0..=tr.y - 10.0);
|
||||
ui.allocate_ui_at_rect(rect, |ui| {
|
||||
if ui
|
||||
.add_sized(rect.size(), super::widgets::NavItem::new("\u{274C}", false))
|
||||
.clicked()
|
||||
{
|
||||
stop_entry_dialog(app);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
match app.relays.add_dialog_step {
|
||||
AddRelayDialogStep::Inactive => {}
|
||||
AddRelayDialogStep::Step1UrlEntry => entry_dialog_step1(ui, ctx, app),
|
||||
AddRelayDialogStep::Step2AwaitOverlord => entry_dialog_step2(ui, app),
|
||||
}
|
||||
});
|
||||
});
|
||||
let response = widgets::modal_popup(ctx, dlg_size, dlg_size, true, |ui| {
|
||||
match app.relays.add_dialog_step {
|
||||
AddRelayDialogStep::Inactive => {}
|
||||
AddRelayDialogStep::Step1UrlEntry => entry_dialog_step1(ui, ctx, app),
|
||||
AddRelayDialogStep::Step2AwaitOverlord => entry_dialog_step2(ui, app),
|
||||
}
|
||||
});
|
||||
|
||||
if response.inner.clicked() || response.response.clicked_elsewhere() {
|
||||
stop_entry_dialog(app);
|
||||
}
|
||||
}
|
||||
|
||||
fn entry_dialog_step1(ui: &mut Ui, ctx: &Context, app: &mut GossipUi) {
|
||||
@ -467,20 +429,40 @@ fn entry_dialog_step2(ui: &mut Ui, app: &mut GossipUi) {
|
||||
pub(super) fn configure_list_btn(app: &mut GossipUi, ui: &mut Ui) {
|
||||
ui.add_enabled_ui(true, |ui| {
|
||||
let min_size = vec2(180.0, 20.0);
|
||||
let max_size = vec2(180.0, ui.ctx().available_rect().height());
|
||||
|
||||
let response = widgets::options_menu_button(ui, &app.theme, &app.assets);
|
||||
widgets::MoreMenu::bubble(ui.next_auto_id())
|
||||
.with_min_size(min_size)
|
||||
.with_hover_text("Configure List View".to_owned())
|
||||
.show(ui, response, |ui, _is_open| {
|
||||
widgets::Switch::small(&app.theme, &mut app.relays.show_details)
|
||||
.with_label("Show details")
|
||||
.show(ui);
|
||||
ui.add_space(8.0);
|
||||
widgets::Switch::small(&app.theme, &mut app.relays.show_hidden)
|
||||
.with_label("Show hidden relays")
|
||||
.show(ui);
|
||||
});
|
||||
let text = egui::RichText::new("=").size(13.0);
|
||||
let response = widgets::Button::primary(&app.theme, text)
|
||||
.small(true)
|
||||
.show(ui);
|
||||
let menu = widgets::MoreMenu::bubble(ui.next_auto_id(), min_size, max_size);
|
||||
|
||||
let mut items: Vec<MoreMenuItem> = Vec::new();
|
||||
|
||||
items.push(MoreMenuItem::Switch(MoreMenuSwitch::new(
|
||||
"Show details",
|
||||
app.relays.show_details,
|
||||
Box::new(|_ui, app| {
|
||||
app.relays.show_details = !app.relays.show_details;
|
||||
}),
|
||||
)));
|
||||
|
||||
items.push(MoreMenuItem::Switch(MoreMenuSwitch::new(
|
||||
"Show hidden relays",
|
||||
app.relays.show_hidden,
|
||||
Box::new(|_ui, app| {
|
||||
app.relays.show_hidden = !app.relays.show_hidden;
|
||||
}),
|
||||
)));
|
||||
|
||||
items.push(MoreMenuItem::Button(MoreMenuButton::new(
|
||||
"Relay Coverage",
|
||||
Box::new(|ui, app| {
|
||||
app.set_page(ui.ctx(), crate::ui::Page::RelaysCoverage);
|
||||
}),
|
||||
)));
|
||||
|
||||
menu.show_entries(ui, app, response, items);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -18,32 +18,33 @@ impl DefaultTheme {
|
||||
}
|
||||
}
|
||||
|
||||
// Trait for creating different types of shadows
|
||||
pub trait ShadowBuilder {
|
||||
fn soft_dark() -> Self;
|
||||
fn soft_light() -> Self;
|
||||
}
|
||||
/// Trait for creating different types of shadows
|
||||
/// TODO @dtonon: This must be reviewed as shadow interface changed with egui 0.28
|
||||
// pub trait ShadowBuilder {
|
||||
// fn soft_dark() -> Self;
|
||||
// fn soft_light() -> Self;
|
||||
// }
|
||||
|
||||
// Implement the trait for Shadow
|
||||
impl ShadowBuilder for Shadow {
|
||||
fn soft_dark() -> Self {
|
||||
Self {
|
||||
offset: vec2(6.0, 10.0),
|
||||
blur: 30.0,
|
||||
spread: 0.0,
|
||||
color: Color32::from_black_alpha(40),
|
||||
}
|
||||
}
|
||||
// // Implement the trait for Shadow
|
||||
// impl ShadowBuilder for Shadow {
|
||||
// fn soft_dark() -> Self {
|
||||
// Self {
|
||||
// offset: vec2(6.0, 10.0),
|
||||
// blur: 30.0,
|
||||
// spread: 0.0,
|
||||
// color: Color32::from_black_alpha(40),
|
||||
// }
|
||||
// }
|
||||
|
||||
fn soft_light() -> Self {
|
||||
Self {
|
||||
offset: vec2(6.0, 10.0),
|
||||
blur: 30.0,
|
||||
spread: 0.0,
|
||||
color: Color32::from_black_alpha(10),
|
||||
}
|
||||
}
|
||||
}
|
||||
// fn soft_light() -> Self {
|
||||
// Self {
|
||||
// offset: vec2(6.0, 10.0),
|
||||
// blur: 30.0,
|
||||
// spread: 0.0,
|
||||
// color: Color32::from_black_alpha(10),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl ThemeDef for DefaultTheme {
|
||||
fn name() -> &'static str {
|
||||
|
@ -355,7 +355,7 @@ fn button_test(app: &mut GossipUi, ui: &mut Ui) {
|
||||
|
||||
fn textedit_test(app: &mut GossipUi, ui: &mut Ui) {
|
||||
ui.horizontal(|ui| {
|
||||
ui.heading("Button Test:");
|
||||
ui.heading("TextEdit Test:");
|
||||
ui.add_space(30.0);
|
||||
});
|
||||
ui.add_space(30.0);
|
||||
@ -428,6 +428,32 @@ fn textedit_test(app: &mut GossipUi, ui: &mut Ui) {
|
||||
.show(ui);
|
||||
});
|
||||
});
|
||||
ui.add_space(20.0);
|
||||
ui.horizontal(|ui| {
|
||||
ui.add_sized(CSIZE, egui::Label::new("with Paste"));
|
||||
ui.add_space(20.0);
|
||||
ui.vertical(|ui| {
|
||||
let output =
|
||||
widgets::TextEdit::singleline(theme, &mut app.theme_test.textedit_empty)
|
||||
.hint_text(HINT)
|
||||
.with_paste()
|
||||
.show(ui);
|
||||
if ui.link("focus").clicked() {
|
||||
output.response.request_focus();
|
||||
}
|
||||
});
|
||||
ui.add_space(20.0);
|
||||
ui.vertical(|ui| {
|
||||
let output =
|
||||
widgets::TextEdit::search(theme, assets, &mut app.theme_test.textedit_empty)
|
||||
.hint_text(HINT)
|
||||
.with_paste()
|
||||
.show(ui);
|
||||
if ui.link("focus").clicked() {
|
||||
output.response.request_focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ const HLINE_THICKNESS: f32 = 1.5;
|
||||
|
||||
pub(crate) fn allocate_space(ui: &mut Ui, height: f32) -> (Rect, Response) {
|
||||
let available_width = ui.available_size_before_wrap().x;
|
||||
ui.allocate_exact_size(vec2(available_width, height), Sense::hover())
|
||||
ui.allocate_exact_size(vec2(available_width, height), Sense::click())
|
||||
}
|
||||
|
||||
pub(crate) fn paint_frame(ui: &mut Ui, rect: &Rect, fill: Option<Color32>) {
|
||||
|
@ -29,7 +29,9 @@ mod modal_popup;
|
||||
pub use modal_popup::{modal_popup, modal_popup_dyn, ModalEntry};
|
||||
|
||||
mod more_menu;
|
||||
pub(super) use more_menu::{MoreMenu, MoreMenuButton, MoreMenuItem, MoreMenuSubMenu};
|
||||
pub(super) use more_menu::{
|
||||
MoreMenu, MoreMenuButton, MoreMenuItem, MoreMenuSubMenu, MoreMenuSwitch,
|
||||
};
|
||||
|
||||
mod information_popup;
|
||||
pub use information_popup::InformationPopup;
|
||||
|
@ -27,6 +27,7 @@ enum MoreMenuStyle {
|
||||
pub(in crate::ui) enum MoreMenuItem<'a> {
|
||||
Button(MoreMenuButton<'a>),
|
||||
SubMenu(MoreMenuSubMenu<'a>),
|
||||
Switch(MoreMenuSwitch<'a>),
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
@ -65,7 +66,7 @@ impl<'a> MoreMenuButton<'a> {
|
||||
galley.rect.width()
|
||||
}
|
||||
|
||||
fn show(self, app: &mut GossipUi, ui: &mut Ui) -> Response {
|
||||
pub fn show(self, app: &mut GossipUi, ui: &mut Ui) -> Response {
|
||||
if !self.enabled {
|
||||
ui.disable();
|
||||
}
|
||||
@ -133,7 +134,7 @@ impl<'a> MoreMenuSubMenu<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn show(self, app: &mut GossipUi, ui: &mut Ui) -> Response {
|
||||
pub fn show(self, app: &mut GossipUi, ui: &mut Ui) -> Response {
|
||||
if !self.enabled {
|
||||
ui.disable();
|
||||
}
|
||||
@ -155,6 +156,7 @@ impl<'a> MoreMenuSubMenu<'a> {
|
||||
.map(|item| match item {
|
||||
MoreMenuItem::Button(entry) => entry.calc_min_width(ui),
|
||||
MoreMenuItem::SubMenu(menu) => menu.calc_min_width(ui),
|
||||
MoreMenuItem::Switch(switch) => switch.calc_min_width(ui),
|
||||
})
|
||||
.reduce(f32::max)
|
||||
.unwrap_or(150.0)
|
||||
@ -221,6 +223,9 @@ impl<'a> MoreMenuSubMenu<'a> {
|
||||
open = false;
|
||||
}
|
||||
}
|
||||
MoreMenuItem::Switch(switch) => {
|
||||
switch.show(app, ui);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -252,6 +257,65 @@ impl<'a> MoreMenuSubMenu<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::ui) struct MoreMenuSwitch<'a> {
|
||||
text: WidgetText,
|
||||
value: bool,
|
||||
action: Box<dyn FnOnce(&mut Ui, &mut GossipUi) + 'a>,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
impl<'a> MoreMenuSwitch<'a> {
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn new(
|
||||
text: impl Into<WidgetText>,
|
||||
value: bool,
|
||||
action: Box<dyn FnOnce(&mut Ui, &mut GossipUi) + 'a>,
|
||||
) -> Self {
|
||||
Self {
|
||||
text: text.into(),
|
||||
value,
|
||||
action,
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn enabled(mut self, enabled: bool) -> Self {
|
||||
self.enabled = enabled;
|
||||
self
|
||||
}
|
||||
|
||||
fn calc_min_width(&self, ui: &Ui) -> f32 {
|
||||
let galley = ui.fonts(|f| {
|
||||
f.layout_no_wrap(
|
||||
self.text.text().into(),
|
||||
egui::TextStyle::Body.resolve(ui.style()),
|
||||
egui::Color32::BLACK,
|
||||
)
|
||||
});
|
||||
galley.rect.width() + super::Switch::small_size().x
|
||||
}
|
||||
|
||||
pub fn show(self, app: &mut GossipUi, ui: &mut Ui) -> Response {
|
||||
if !self.enabled {
|
||||
ui.disable();
|
||||
}
|
||||
|
||||
let mut value = self.value;
|
||||
let response = super::Switch::small(&app.theme, &mut value)
|
||||
.with_label(self.text)
|
||||
.with_padding(vec2(10.0, 5.0))
|
||||
.show(ui);
|
||||
|
||||
// process action
|
||||
if response.clicked() {
|
||||
(self.action)(ui, app);
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::ui) struct MoreMenu {
|
||||
id: Id,
|
||||
min_size: Vec2,
|
||||
@ -276,14 +340,11 @@ impl MoreMenu {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bubble(id: Id) -> Self {
|
||||
pub fn bubble(id: Id, min_size: Vec2, max_size: Vec2) -> Self {
|
||||
Self {
|
||||
id,
|
||||
min_size: Vec2 { x: 0.0, y: 0.0 },
|
||||
max_size: Vec2 {
|
||||
x: f32::INFINITY,
|
||||
y: f32::INFINITY,
|
||||
},
|
||||
min_size,
|
||||
max_size,
|
||||
above_or_below: None,
|
||||
hover_text: None,
|
||||
style: MoreMenuStyle::Bubble,
|
||||
@ -517,6 +578,9 @@ impl MoreMenu {
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
MoreMenuItem::Switch(switch) => {
|
||||
switch.show(app, ui);
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -192,8 +192,7 @@ pub struct RelayEntry {
|
||||
accent: Color32,
|
||||
accent_hover: Color32,
|
||||
bg_fill: Color32,
|
||||
// highlight: Option<Color32>,
|
||||
option_symbol: TextureId,
|
||||
bg_hover: Color32,
|
||||
auth_require_permission: bool,
|
||||
conn_require_permission: bool,
|
||||
}
|
||||
@ -205,6 +204,16 @@ impl RelayEntry {
|
||||
let mut hsva: ecolor::HsvaGamma = accent.into();
|
||||
hsva.v *= 0.8;
|
||||
let accent_hover: Color32 = hsva.into();
|
||||
let bg_fill = if app.theme.dark_mode {
|
||||
app.theme.neutral_800()
|
||||
} else {
|
||||
app.theme.neutral_100()
|
||||
};
|
||||
let bg_hover = if app.theme.dark_mode {
|
||||
app.theme.neutral_950()
|
||||
} else {
|
||||
app.theme.neutral_50()
|
||||
};
|
||||
Self {
|
||||
relay,
|
||||
view: RelayEntryView::List,
|
||||
@ -216,9 +225,8 @@ impl RelayEntry {
|
||||
usage,
|
||||
accent,
|
||||
accent_hover,
|
||||
bg_fill: app.theme.main_content_bgcolor(),
|
||||
// highlight: None,
|
||||
option_symbol: (&app.assets.options_symbol).into(),
|
||||
bg_fill,
|
||||
bg_hover,
|
||||
auth_require_permission: false,
|
||||
conn_require_permission: false,
|
||||
}
|
||||
@ -332,29 +340,6 @@ impl RelayEntry {
|
||||
.on_hover_text(tooltip);
|
||||
}
|
||||
|
||||
fn paint_edit_btn(&mut self, ui: &mut Ui, rect: &Rect) -> Response {
|
||||
let id = self.make_id("edit_btn");
|
||||
let pos = rect.right_top() + vec2(-EDIT_BTN_SIZE - TEXT_RIGHT, TEXT_TOP);
|
||||
let btn_rect = Rect::from_min_size(pos, vec2(EDIT_BTN_SIZE, EDIT_BTN_SIZE));
|
||||
let response = ui
|
||||
.interact(btn_rect, id, Sense::click())
|
||||
.on_hover_cursor(CursorIcon::PointingHand)
|
||||
.on_hover_text("Configure Relay");
|
||||
let color = if response.hovered() {
|
||||
ui.visuals().text_color()
|
||||
} else {
|
||||
self.accent
|
||||
};
|
||||
let mut mesh = Mesh::with_texture(self.option_symbol);
|
||||
mesh.add_rect_with_uv(
|
||||
btn_rect.shrink(2.0),
|
||||
Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
|
||||
color,
|
||||
);
|
||||
ui.painter().add(Shape::mesh(mesh));
|
||||
response
|
||||
}
|
||||
|
||||
fn paint_close_btn(&mut self, ui: &mut Ui, rect: &Rect) -> Response {
|
||||
let id = self.make_id("close_btn");
|
||||
let button_padding = ui.spacing().button_padding;
|
||||
@ -580,8 +565,7 @@ impl RelayEntry {
|
||||
const SPACE: f32 = 23.0;
|
||||
|
||||
// match self.view { RelayEntryView::Detail => ... }
|
||||
let right = pos2(rect.max.x, rect.min.y)
|
||||
+ vec2(-TEXT_RIGHT - EDIT_BTN_SIZE - SPACE, TEXT_TOP + 4.0);
|
||||
let right = pos2(rect.max.x, rect.min.y) + vec2(-TEXT_RIGHT, TEXT_TOP + 4.0);
|
||||
|
||||
let align = Align::Center;
|
||||
|
||||
@ -1222,15 +1206,23 @@ impl RelayEntry {
|
||||
(self.relay.url.to_string() + str).into()
|
||||
}
|
||||
|
||||
fn interact_bg_color(&self, response: &Response) -> Option<Color32> {
|
||||
if response.hovered() {
|
||||
Some(self.bg_hover)
|
||||
} else {
|
||||
Some(self.bg_fill)
|
||||
}
|
||||
}
|
||||
|
||||
/// Do layout and position the galley in the ui, without painting it or adding widget info.
|
||||
fn update_list_view(mut self, ui: &mut Ui) -> Response {
|
||||
fn update_list_view(self, ui: &mut Ui) -> Response {
|
||||
let (rect, mut response) = list_entry::allocate_space(ui, LIST_VIEW_HEIGHT);
|
||||
response = response.on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||
|
||||
// all the heavy lifting is only done if it's actually visible
|
||||
if ui.is_rect_visible(rect) {
|
||||
list_entry::paint_frame(ui, &rect, Some(self.bg_fill));
|
||||
list_entry::paint_frame(ui, &rect, self.interact_bg_color(&response));
|
||||
self.paint_title(ui, &rect);
|
||||
response |= self.paint_edit_btn(ui, &rect);
|
||||
if self.relay.has_any_usage_bit() || self.relay.is_good_for_advertise() {
|
||||
self.paint_usage(ui, &rect);
|
||||
} else {
|
||||
@ -1242,14 +1234,14 @@ impl RelayEntry {
|
||||
response
|
||||
}
|
||||
|
||||
fn update_detail_view(mut self, ui: &mut Ui) -> Response {
|
||||
fn update_detail_view(self, ui: &mut Ui) -> Response {
|
||||
let (rect, mut response) = list_entry::allocate_space(ui, DETAIL_VIEW_HEIGHT);
|
||||
response = response.on_hover_cursor(egui::CursorIcon::PointingHand);
|
||||
|
||||
// all the heavy lifting is only done if it's actually visible
|
||||
if ui.is_rect_visible(rect) {
|
||||
list_entry::paint_frame(ui, &rect, Some(self.bg_fill));
|
||||
list_entry::paint_frame(ui, &rect, self.interact_bg_color(&response));
|
||||
self.paint_title(ui, &rect);
|
||||
response |= self.paint_edit_btn(ui, &rect);
|
||||
self.paint_stats(ui, &rect);
|
||||
if self.relay.has_any_usage_bit() || self.relay.is_good_for_advertise() {
|
||||
self.paint_usage(ui, &rect);
|
||||
|
@ -14,9 +14,20 @@ pub struct Switch<'a> {
|
||||
label: Option<WidgetText>,
|
||||
label_color: Option<Color32>,
|
||||
size: Vec2,
|
||||
padding: Vec2,
|
||||
theme: &'a Theme,
|
||||
}
|
||||
|
||||
impl Switch<'_> {
|
||||
pub const fn small_size() -> Vec2 {
|
||||
vec2(29.0, 16.0)
|
||||
}
|
||||
|
||||
pub const fn large_size() -> Vec2 {
|
||||
vec2(40.0, 22.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Switch<'a> {
|
||||
/// Create a small switch, similar to normal line height
|
||||
pub fn small(theme: &'a Theme, value: &'a mut bool) -> Self {
|
||||
@ -24,7 +35,8 @@ impl<'a> Switch<'a> {
|
||||
value,
|
||||
label: None,
|
||||
label_color: None,
|
||||
size: vec2(29.0, 16.0),
|
||||
size: Switch::small_size(),
|
||||
padding: Vec2::ZERO,
|
||||
theme,
|
||||
}
|
||||
}
|
||||
@ -35,7 +47,8 @@ impl<'a> Switch<'a> {
|
||||
value,
|
||||
label: None,
|
||||
label_color: None,
|
||||
size: vec2(40.0, 22.0),
|
||||
size: Switch::large_size(),
|
||||
padding: Vec2::ZERO,
|
||||
theme,
|
||||
}
|
||||
}
|
||||
@ -51,6 +64,11 @@ impl<'a> Switch<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_padding(mut self, padding: Vec2) -> Self {
|
||||
self.padding = padding;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn show(mut self, ui: &mut Ui) -> Response {
|
||||
let (response, galley) = self.allocate(ui);
|
||||
let (state, response) = interact(ui, response, self.value, self.label);
|
||||
@ -60,6 +78,7 @@ impl<'a> Switch<'a> {
|
||||
self.value,
|
||||
response,
|
||||
self.size,
|
||||
self.padding,
|
||||
galley,
|
||||
self.label_color,
|
||||
state,
|
||||
@ -94,7 +113,9 @@ impl<'a> Switch<'a> {
|
||||
egui::Sense::hover()
|
||||
};
|
||||
// allocate
|
||||
let (_, response) = ui.allocate_exact_size(self.size + vec2(extra_width, 0.0), sense);
|
||||
let size = self.size + vec2(extra_width, 0.0);
|
||||
let size = size + self.padding + self.padding;
|
||||
let (_, response) = ui.allocate_exact_size(size, sense);
|
||||
(response, galley)
|
||||
}
|
||||
|
||||
@ -229,6 +250,7 @@ fn draw_at(
|
||||
value: &bool,
|
||||
response: Response,
|
||||
size: Vec2,
|
||||
padding: Vec2,
|
||||
galley: Option<Arc<Galley>>,
|
||||
label_color: Option<Color32>,
|
||||
_state: WidgetState,
|
||||
@ -237,7 +259,7 @@ fn draw_at(
|
||||
if ui.is_rect_visible(rect) {
|
||||
let how_on = ui.ctx().animate_bool(response.id, *value);
|
||||
|
||||
let radius = 0.5 * rect.height();
|
||||
let radius = 0.5 * size.y;
|
||||
let stroke_width = 0.5;
|
||||
let (bg_fill, frame_stroke, knob_fill, knob_stroke, text_color) = if theme.dark_mode {
|
||||
if ui.is_enabled() {
|
||||
@ -304,7 +326,7 @@ fn draw_at(
|
||||
};
|
||||
|
||||
// switch
|
||||
let switch_rect = Rect::from_min_size(rect.min, size);
|
||||
let switch_rect = Rect::from_min_size(rect.min + padding, size);
|
||||
ui.painter()
|
||||
.rect(switch_rect, radius, bg_fill, frame_stroke);
|
||||
let circle_x = egui::lerp(
|
||||
|
@ -157,12 +157,12 @@ impl<'t> TextEdit<'t> {
|
||||
|
||||
// ---- show inner ----
|
||||
let output = inner.show(ui);
|
||||
let response = &output.response;
|
||||
let frame_rect = response.rect + margin;
|
||||
|
||||
// ---- draw frame ----
|
||||
{
|
||||
let theme = self.theme;
|
||||
let response = &output.response;
|
||||
let frame_rect = response.rect + margin;
|
||||
|
||||
// this is how egui chooses the visual style:
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
@ -200,8 +200,7 @@ impl<'t> TextEdit<'t> {
|
||||
if self.with_search {
|
||||
if let Some(symbol) = self.magnifyingglass_symbol {
|
||||
let rect = Rect::from_center_size(
|
||||
output.response.rect.left_center()
|
||||
+ vec2((MARGIN.left + pre_space) / 2.0, 0.0),
|
||||
frame_rect.left_center() + vec2((MARGIN.left + pre_space) / 2.0, 0.0),
|
||||
symbol.size_vec2() / (assets::SVG_OVERSAMPLE + ui.ctx().zoom_factor()),
|
||||
);
|
||||
egui::Image::from_texture(SizedTexture::new(symbol.id(), symbol.size_vec2()))
|
||||
@ -217,8 +216,8 @@ impl<'t> TextEdit<'t> {
|
||||
|
||||
if self.with_clear && !self.text.as_str().is_empty() {
|
||||
let rect = Rect::from_min_size(
|
||||
output.response.rect.right_top() - vec2(output.response.rect.height(), 0.0),
|
||||
vec2(output.response.rect.height(), output.response.rect.height()),
|
||||
frame_rect.right_top() - vec2(frame_rect.height(), 0.0),
|
||||
vec2(frame_rect.height(), frame_rect.height()),
|
||||
);
|
||||
|
||||
// clear button
|
||||
@ -266,9 +265,9 @@ impl<'t> TextEdit<'t> {
|
||||
}
|
||||
};
|
||||
|
||||
let action_size = vec2(45.0, output.response.rect.height());
|
||||
let action_size = vec2(45.0, frame_rect.height());
|
||||
let rect = Rect::from_min_size(
|
||||
output.response.rect.right_top() - vec2(action_size.x, 0.0),
|
||||
frame_rect.right_top() - vec2(action_size.x, 0.0),
|
||||
action_size,
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user