Login Screen: Apply dtonon style.

widgets::TextEdit: Create new textedit widget overload to apply uniform styling.
This commit is contained in:
Bu5hm4nn 2023-12-22 19:52:33 -06:00
parent ffee452155
commit 446fb616cd
5 changed files with 253 additions and 30 deletions

View File

@ -1,6 +1,7 @@
macro_rules! text_edit_line {
($app:ident, $var:expr) => {
egui::widgets::TextEdit::singleline(&mut $var).text_color($app.theme.input_text_color())
crate::ui::widgets::TextEdit::singleline(&mut $var)
.text_color($app.theme.input_text_color())
};
}
@ -355,6 +356,9 @@ struct GossipUi {
current_scroll_offset: f32,
future_scroll_offset: f32,
// clipboard
clipboard: egui_winit::clipboard::Clipboard,
// Ui timers
popups: HashMap<egui::Id, HashMap<egui::Id, Box<dyn widgets::InformationPopup>>>,
@ -624,6 +628,7 @@ impl GossipUi {
original_dpi_value: override_dpi_value,
current_scroll_offset: 0.0,
future_scroll_offset: 0.0,
clipboard: egui_winit::clipboard::Clipboard::new(cctx),
popups: HashMap::new(),
qr_codes: HashMap::new(),
notes: Notes::new(),
@ -1956,15 +1961,26 @@ fn force_login(app: &mut GossipUi, ctx: &Context) {
top: 10.0,
bottom: 0.0,
})
.fill({
if ctx.style().visuals.dark_mode {
egui::Color32::from_rgb(0x28, 0x28, 0x28)
} else {
Color32::WHITE
}
})
})
.show(ctx, |ui| {
let size = egui::vec2( 600.0, 450.0 );
let response = widgets::modal_popup(
ui,
size,
size,
false,
|ui| {
let frame = egui::Frame::none();
let area = egui::Area::new(ui.auto_id_with("login_screen"))
.movable(false)
.interactable(true)
.constrain(true)
.order(egui::Order::Middle)
.anchor(egui::Align2::CENTER_CENTER, [0.0, -100.0]);
area.show(ui.ctx(), |ui| {
// frame.rounding = egui::Rounding::same(10.0);
// frame.inner_margin = egui::Margin::symmetric(MARGIN_X, MARGIN_Y);
frame.show(ui, |ui| {
ui.vertical_centered(|ui| {
ui.add_space(115.0);
@ -1984,12 +2000,12 @@ fn force_login(app: &mut GossipUi, ctx: &Context) {
ui.add_space(16.0);
}
let response = ui.add(
text_edit_line!(app, app.password).password(true)
.desired_width(400.0)
);
let output = widgets::TextEdit::singleline(&mut app.password)
.password(true)
.desired_width( 400.0)
.show_extended(ui, &mut app.clipboard);
if app.unlock_needs_focus {
response.request_focus();
output.response.request_focus();
app.unlock_needs_focus = false;
}
@ -1999,9 +2015,10 @@ fn force_login(app: &mut GossipUi, ctx: &Context) {
//response.lost_focus() &&
ui.input(|i| i.key_pressed(egui::Key::Enter));
app.theme.accent_button_1_style(ui.style_mut());
submitted |= ui.button(" Continue ").clicked();
ui.set_style(app.theme.get_style());
ui.scope(|ui| {
app.theme.accent_button_1_style(ui.style_mut());
submitted |= ui.button(" Continue ").clicked();
});
if submitted {
let _ = gossip_lib::Overlord::unlock_key(app.password.clone());
@ -2046,16 +2063,24 @@ fn force_login(app: &mut GossipUi, ctx: &Context) {
}
});
ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| {
ui.horizontal(|ui| {
});
});
let mut frame = egui::Frame::none();
let area = egui::Area::new(ui.auto_id_with("login_footer"))
.movable(false)
.interactable(true)
.constrain(true)
.order(egui::Order::Middle)
.anchor(egui::Align2::CENTER_BOTTOM, [0.0, 0.0]);
area.show(ctx, |ui| {
frame.inner_margin = egui::Margin::symmetric(10.0,40.0);
frame.show(ui, |ui| {
ui.with_layout(egui::Layout::left_to_right(egui::Align::BOTTOM).with_main_justify(true), |ui| {
ui.horizontal( |ui| {
// Change link color:
ui.style_mut().visuals.hyperlink_color = app.theme.navigation_text_color();
// egui does not center text that has multiple widgets.
// Luckily we know the size of the container and the widgets ahead of time,
// so in this case we can just add space.
ui.add_space(60.0);
ui.label(
RichText::new("Do you need help? Open an").weak()
);
@ -2073,10 +2098,7 @@ fn force_login(app: &mut GossipUi, ctx: &Context) {
});
});
});
if response.inner.clicked() {
cancel_login();
}
});
});
}

View File

@ -591,6 +591,14 @@ impl ThemeDef for DefaultTheme {
}
}
fn input_bg_color(dark_mode: bool) -> eframe::egui::Color32 {
if dark_mode {
Color32::from_gray(0x47)
} else {
Self::get_style(dark_mode).visuals.extreme_bg_color
}
}
// feed styling
fn feed_scroll_rounding(_feed: &FeedProperties) -> Rounding {
Rounding::ZERO

View File

@ -216,6 +216,12 @@ macro_rules! theme_dispatch {
}
}
pub fn input_bg_color(&self) -> Color32 {
match self.variant {
$( $variant => $class::input_bg_color(self.dark_mode), )+
}
}
pub fn feed_scroll_fill(&self, feed: &FeedProperties) -> Color32 {
match self.variant {
$( $variant => $class::feed_scroll_fill(self.dark_mode, feed), )+
@ -419,6 +425,7 @@ pub trait ThemeDef: Send + Sync {
// labels made clickable, and TextEdit text. We try to always override TextEdit
// text with this color instead.
fn input_text_color(dark_mode: bool) -> eframe::egui::Color32;
fn input_bg_color(dark_mode: bool) -> eframe::egui::Color32;
// feed styling
fn feed_scroll_rounding(feed: &FeedProperties) -> Rounding;

View File

@ -11,9 +11,7 @@ pub use copy_button::{CopyButton, COPY_SYMBOL_SIZE};
mod nav_item;
use egui_winit::egui::text::LayoutJob;
use egui_winit::egui::text_edit::TextEditOutput;
use egui_winit::egui::{
self, vec2, Align, FontSelection, Rect, RichText, Sense, TextEdit, Ui, WidgetText,
};
use egui_winit::egui::{self, vec2, Align, FontSelection, Rect, RichText, Sense, Ui, WidgetText};
pub use nav_item::NavItem;
mod relay_entry;
@ -33,6 +31,9 @@ mod switch;
pub use switch::Switch;
pub use switch::{switch_custom_at, switch_simple, switch_with_size, switch_with_size_at};
mod textedit;
pub use textedit::TextEdit;
use super::GossipUi;
pub const DROPDOWN_DISTANCE: f32 = 10.0;

View File

@ -0,0 +1,185 @@
use egui_winit::egui::{self, vec2, Color32, Rect, TextBuffer, Widget, WidgetText};
pub struct TextEdit<'t> {
text: &'t mut dyn TextBuffer,
multiline: bool,
desired_width: Option<f32>,
hint_text: WidgetText,
password: bool,
bg_color: Option<Color32>,
text_color: Option<Color32>,
with_paste: bool,
with_clear: bool,
}
impl<'t> TextEdit<'t> {
pub fn singleline(text: &'t mut dyn TextBuffer) -> Self {
Self {
text,
multiline: false,
desired_width: None,
hint_text: WidgetText::default(),
password: false,
bg_color: None,
text_color: None,
with_paste: false,
with_clear: false,
}
}
// pub fn mutliline(text: &'t mut dyn TextBuffer)-> Self {
// Self {
// text,
// multiline: true,
// desired_width: None,
// hint_text: WidgetText::default(),
// password: false,
// text_color: None,
// with_paste: false,
// with_clear: false,
// }
// }
// ---- builders ----
#[allow(unused)]
pub fn desired_width(mut self, desired_width: f32) -> Self {
self.desired_width = Some(desired_width);
self
}
#[allow(unused)]
pub fn hint_text(mut self, hint_text: impl Into<WidgetText>) -> Self {
self.hint_text = hint_text.into();
self
}
#[allow(unused)]
pub fn password(mut self, password: bool) -> Self {
self.password = password;
self
}
#[allow(unused)]
pub fn bg_color(mut self, bg_color: egui::Color32) -> Self {
self.bg_color = Some(bg_color);
self
}
#[allow(unused)]
pub fn text_color(mut self, text_color: egui::Color32) -> Self {
self.text_color = Some(text_color);
self
}
#[allow(unused)]
pub fn with_paste(mut self) -> Self {
self.with_paste = true;
self
}
#[allow(unused)]
pub fn with_clear(mut self) -> Self {
self.with_clear = true;
self
}
pub fn show(self, ui: &mut egui::Ui) -> egui::text_edit::TextEditOutput {
ui.scope(|ui| {
if ui.visuals().dark_mode {
ui.visuals_mut().extreme_bg_color = self.bg_color.unwrap_or(egui::Color32::from_gray(0x47));
} else {
ui.visuals_mut().extreme_bg_color = self.bg_color.unwrap_or(Color32::WHITE);
}
let mut inner = match self.multiline {
false => egui::widgets::TextEdit::singleline(self.text),
true => egui::widgets::TextEdit::multiline(self.text),
}
.password(self.password)
.hint_text(self.hint_text.clone());
if let Some(width) = self.desired_width {
inner = inner.desired_width(width);
}
if let Some(color) = self.text_color {
inner = inner.text_color(color);
}
// show inner
inner.show(ui)
})
.inner
}
pub fn show_extended(
self,
ui: &mut egui::Ui,
clipboard: &mut egui_winit::clipboard::Clipboard,
) -> egui::text_edit::TextEditOutput {
ui.scope(|ui| {
if ui.visuals().dark_mode {
ui.visuals_mut().extreme_bg_color = self.bg_color.unwrap_or(egui::Color32::from_gray(0x47));
} else {
ui.visuals_mut().extreme_bg_color = self.bg_color.unwrap_or(Color32::WHITE);
}
let mut inner = match self.multiline {
false => egui::widgets::TextEdit::singleline(self.text),
true => egui::widgets::TextEdit::multiline(self.text),
}
.password(self.password)
.hint_text(self.hint_text.clone());
if let Some(width) = self.desired_width {
inner = inner.desired_width(width);
}
if let Some(color) = self.text_color {
inner = inner.text_color(color);
}
// show inner
let output = inner.show(ui);
// paste button
if self.with_paste {
let action_size = vec2(45.0, output.response.rect.height());
let rect = Rect::from_min_size(
output.response.rect.right_top() - vec2(action_size.x, 0.0),
action_size,
);
if ui
.put(
rect,
super::NavItem::new("Paste", true)
.color(ui.visuals().widgets.inactive.fg_stroke.color)
.active_color(ui.visuals().widgets.active.fg_stroke.color)
.hover_color(ui.visuals().hyperlink_color)
.sense(egui::Sense::click()),
)
.clicked()
{
if let Some(paste) = clipboard.get() {
let index = if let Some(cursor) = output.cursor_range {
cursor.primary.ccursor.index
} else {
0
};
self.text.insert_text(paste.as_str(), index);
}
}
}
output
})
.inner
}
}
impl<'t> Widget for TextEdit<'t> {
fn ui(self, ui: &mut egui_winit::egui::Ui) -> egui_winit::egui::Response {
self.show(ui).response
}
}