add input context menu helper
We are going to want this in more places Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -3300,6 +3300,7 @@ dependencies = [
|
|||||||
"bitflags 2.9.0",
|
"bitflags 2.9.0",
|
||||||
"blurhash",
|
"blurhash",
|
||||||
"egui",
|
"egui",
|
||||||
|
"egui-winit",
|
||||||
"egui_extras",
|
"egui_extras",
|
||||||
"ehttp",
|
"ehttp",
|
||||||
"enostr",
|
"enostr",
|
||||||
@@ -3309,6 +3310,8 @@ dependencies = [
|
|||||||
"notedeck",
|
"notedeck",
|
||||||
"poll-promise",
|
"poll-promise",
|
||||||
"profiling",
|
"profiling",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use crate::{
|
|||||||
accounts::{AccountsView, AccountsViewResponse},
|
accounts::{AccountsView, AccountsViewResponse},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use egui_winit::clipboard::Clipboard;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
mod route;
|
mod route;
|
||||||
@@ -31,6 +32,7 @@ pub fn render_accounts_route(
|
|||||||
accounts: &mut Accounts,
|
accounts: &mut Accounts,
|
||||||
decks: &mut DecksCache,
|
decks: &mut DecksCache,
|
||||||
login_state: &mut AcquireKeyState,
|
login_state: &mut AcquireKeyState,
|
||||||
|
clipboard: &mut Clipboard,
|
||||||
route: AccountsRoute,
|
route: AccountsRoute,
|
||||||
) -> AddAccountAction {
|
) -> AddAccountAction {
|
||||||
let resp = match route {
|
let resp = match route {
|
||||||
@@ -39,7 +41,7 @@ pub fn render_accounts_route(
|
|||||||
.inner
|
.inner
|
||||||
.map(AccountsRouteResponse::Accounts),
|
.map(AccountsRouteResponse::Accounts),
|
||||||
|
|
||||||
AccountsRoute::AddAccount => AccountLoginView::new(login_state)
|
AccountsRoute::AddAccount => AccountLoginView::new(login_state, clipboard)
|
||||||
.ui(ui)
|
.ui(ui)
|
||||||
.inner
|
.inner
|
||||||
.map(AccountsRouteResponse::AddAccount),
|
.map(AccountsRouteResponse::AddAccount),
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ impl<'a> AcquireKeyState {
|
|||||||
textedit_closure(&mut self.desired_key)
|
textedit_closure(&mut self.desired_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn input_buffer(&mut self) -> &mut String {
|
||||||
|
&mut self.desired_key
|
||||||
|
}
|
||||||
|
|
||||||
/// User pressed the 'acquire' button
|
/// User pressed the 'acquire' button
|
||||||
pub fn apply_acquire(&'a mut self) {
|
pub fn apply_acquire(&'a mut self) {
|
||||||
let new_promise = match &self.promise_query {
|
let new_promise = match &self.promise_query {
|
||||||
|
|||||||
@@ -423,6 +423,7 @@ fn render_nav_body(
|
|||||||
ctx.accounts,
|
ctx.accounts,
|
||||||
&mut app.decks_cache,
|
&mut app.decks_cache,
|
||||||
&mut app.view_state.login,
|
&mut app.view_state.login,
|
||||||
|
ctx.clipboard,
|
||||||
*amr,
|
*amr,
|
||||||
);
|
);
|
||||||
let txn = Transaction::new(ctx.ndb).expect("txn");
|
let txn = Transaction::new(ctx.ndb).expect("txn");
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ use egui::{
|
|||||||
Align, Button, Color32, Frame, Image, InnerResponse, Margin, RichText, TextBuffer, Vec2,
|
Align, Button, Color32, Frame, Image, InnerResponse, Margin, RichText, TextBuffer, Vec2,
|
||||||
};
|
};
|
||||||
use egui::{Layout, TextEdit};
|
use egui::{Layout, TextEdit};
|
||||||
|
use egui_winit::clipboard::Clipboard;
|
||||||
use enostr::Keypair;
|
use enostr::Keypair;
|
||||||
use notedeck::{fonts::get_font_size, AppAction, NotedeckTextStyle};
|
use notedeck::{fonts::get_font_size, AppAction, NotedeckTextStyle};
|
||||||
|
use notedeck_ui::context_menu::{input_context, PasteBehavior};
|
||||||
|
|
||||||
pub struct AccountLoginView<'a> {
|
pub struct AccountLoginView<'a> {
|
||||||
manager: &'a mut AcquireKeyState,
|
manager: &'a mut AcquireKeyState,
|
||||||
|
clipboard: &'a mut Clipboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum AccountLoginResponse {
|
pub enum AccountLoginResponse {
|
||||||
@@ -17,8 +20,8 @@ pub enum AccountLoginResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AccountLoginView<'a> {
|
impl<'a> AccountLoginView<'a> {
|
||||||
pub fn new(state: &'a mut AcquireKeyState) -> Self {
|
pub fn new(manager: &'a mut AcquireKeyState, clipboard: &'a mut Clipboard) -> Self {
|
||||||
AccountLoginView { manager: state }
|
AccountLoginView { manager, clipboard }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ui(&mut self, ui: &mut egui::Ui) -> InnerResponse<Option<AccountLoginResponse>> {
|
pub fn ui(&mut self, ui: &mut egui::Ui) -> InnerResponse<Option<AccountLoginResponse>> {
|
||||||
@@ -42,7 +45,9 @@ impl<'a> AccountLoginView<'a> {
|
|||||||
let button_width = 32.0;
|
let button_width = 32.0;
|
||||||
let text_edit_width = available_width - button_width;
|
let text_edit_width = available_width - button_width;
|
||||||
|
|
||||||
ui.add_sized([text_edit_width, 40.0], login_textedit(self.manager));
|
let textedit_resp = ui.add_sized([text_edit_width, 40.0], login_textedit(self.manager));
|
||||||
|
input_context(&textedit_resp, self.clipboard, self.manager.input_buffer(), PasteBehavior::Clear);
|
||||||
|
|
||||||
if eye_button(ui, self.manager.password_visible()).clicked() {
|
if eye_button(ui, self.manager.password_visible()).clicked() {
|
||||||
self.manager.toggle_password_visibility();
|
self.manager.toggle_password_visibility();
|
||||||
}
|
}
|
||||||
@@ -154,12 +159,8 @@ mod preview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl App for AccountLoginPreview {
|
impl App for AccountLoginPreview {
|
||||||
fn update(
|
fn update(&mut self, ctx: &mut AppContext<'_>, ui: &mut egui::Ui) -> Option<AppAction> {
|
||||||
&mut self,
|
AccountLoginView::new(&mut self.manager, ctx.clipboard).ui(ui);
|
||||||
_app_ctx: &mut AppContext<'_>,
|
|
||||||
ui: &mut egui::Ui,
|
|
||||||
) -> Option<AppAction> {
|
|
||||||
AccountLoginView::new(&mut self.manager).ui(ui);
|
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ use crate::{timeline::TimelineTab, ui::timeline::TimelineTabView};
|
|||||||
use egui_winit::clipboard::Clipboard;
|
use egui_winit::clipboard::Clipboard;
|
||||||
use nostrdb::{Filter, Ndb, Transaction};
|
use nostrdb::{Filter, Ndb, Transaction};
|
||||||
use notedeck::{MuteFun, NoteAction, NoteContext, NoteRef};
|
use notedeck::{MuteFun, NoteAction, NoteContext, NoteRef};
|
||||||
use notedeck_ui::{icons::search_icon, jobs::JobsCache, padding, NoteOptions};
|
use notedeck_ui::{
|
||||||
|
context_menu::{input_context, PasteBehavior},
|
||||||
|
icons::search_icon,
|
||||||
|
jobs::JobsCache,
|
||||||
|
padding, NoteOptions,
|
||||||
|
};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
@@ -296,21 +301,7 @@ fn search_box(
|
|||||||
.frame(false),
|
.frame(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
response.context_menu(|ui| {
|
input_context(&response, clipboard, input, PasteBehavior::Append);
|
||||||
if ui.button("paste").clicked() {
|
|
||||||
if let Some(text) = clipboard.get() {
|
|
||||||
input.clear();
|
|
||||||
input.push_str(&text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if response.middle_clicked() {
|
|
||||||
if let Some(text) = clipboard.get() {
|
|
||||||
input.clear();
|
|
||||||
input.push_str(&text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut requested_focus = false;
|
let mut requested_focus = false;
|
||||||
if focus_state == FocusState::ShouldRequestFocus {
|
if focus_state == FocusState::ShouldRequestFocus {
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ version.workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
egui = { workspace = true }
|
egui = { workspace = true }
|
||||||
egui_extras = { workspace = true }
|
egui_extras = { workspace = true }
|
||||||
|
egui-winit = { workspace = true }
|
||||||
|
strum_macros = { workspace = true }
|
||||||
|
strum = { workspace = true }
|
||||||
ehttp = { workspace = true }
|
ehttp = { workspace = true }
|
||||||
nostrdb = { workspace = true }
|
nostrdb = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
@@ -18,4 +21,4 @@ bitflags = { workspace = true }
|
|||||||
enostr = { workspace = true }
|
enostr = { workspace = true }
|
||||||
hashbrown = { workspace = true }
|
hashbrown = { workspace = true }
|
||||||
|
|
||||||
blurhash = "0.2.3"
|
blurhash = "0.2.3"
|
||||||
|
|||||||
49
crates/notedeck_ui/src/context_menu.rs
Normal file
49
crates/notedeck_ui/src/context_menu.rs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/// Context menu helpers (paste, etc)
|
||||||
|
use egui_winit::clipboard::Clipboard;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub enum PasteBehavior {
|
||||||
|
Clear,
|
||||||
|
Append,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_paste(clipboard: &mut Clipboard, input: &mut String, paste_behavior: PasteBehavior) {
|
||||||
|
if let Some(text) = clipboard.get() {
|
||||||
|
// if called with clearing_input_context, then we clear before
|
||||||
|
// we paste. Useful for certain fields like passwords, etc
|
||||||
|
match paste_behavior {
|
||||||
|
PasteBehavior::Clear => input.clear(),
|
||||||
|
PasteBehavior::Append => {}
|
||||||
|
}
|
||||||
|
input.push_str(&text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input_context(
|
||||||
|
response: &egui::Response,
|
||||||
|
clipboard: &mut Clipboard,
|
||||||
|
input: &mut String,
|
||||||
|
paste_behavior: PasteBehavior,
|
||||||
|
) {
|
||||||
|
response.context_menu(|ui| {
|
||||||
|
if ui.button("Paste").clicked() {
|
||||||
|
handle_paste(clipboard, input, paste_behavior);
|
||||||
|
ui.close_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.button("Copy").clicked() {
|
||||||
|
clipboard.set_text(input.to_owned());
|
||||||
|
ui.close_menu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.button("Cut").clicked() {
|
||||||
|
clipboard.set_text(input.to_owned());
|
||||||
|
input.clear();
|
||||||
|
ui.close_menu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if response.middle_clicked() {
|
||||||
|
handle_paste(clipboard, input, paste_behavior)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ pub mod blur;
|
|||||||
pub mod colors;
|
pub mod colors;
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod contacts;
|
pub mod contacts;
|
||||||
|
pub mod context_menu;
|
||||||
pub mod gif;
|
pub mod gif;
|
||||||
pub mod icons;
|
pub mod icons;
|
||||||
pub mod images;
|
pub mod images;
|
||||||
|
|||||||
Reference in New Issue
Block a user