From 17d0c97c78d4bcc66585288395b143ea571bbba6 Mon Sep 17 00:00:00 2001 From: kernelkind Date: Fri, 17 May 2024 11:47:42 -0400 Subject: [PATCH] Create side panel & global popup Create a side panel UI element for desktop with three buttons for: adding a column, settings, and account management. The account management button is temporary pending a better design. It is the only one that is interactable at the moment. When the user clicks it, the global popup window will be shown and the AccountManagementView will be presented on the window. The user can click on the X on the top right of the window to close it. Signed-off-by: kernelkind Signed-off-by: William Casarin --- assets/icons/add_column_dark_4x.png | Bin 0 -> 1150 bytes assets/icons/settings_dark_4x.png | Bin 0 -> 3886 bytes src/ui/account_management.rs | 63 ++++++-------- src/ui/global_popup.rs | 127 ++++++++++++++++++++++++++++ src/ui/mod.rs | 5 ++ src/ui/persist_state.rs | 43 ++++++++++ src/ui/side_panel.rs | 93 ++++++++++++++++++++ src/ui_preview/main.rs | 6 +- 8 files changed, 299 insertions(+), 38 deletions(-) create mode 100644 assets/icons/add_column_dark_4x.png create mode 100644 assets/icons/settings_dark_4x.png create mode 100644 src/ui/global_popup.rs create mode 100644 src/ui/persist_state.rs create mode 100644 src/ui/side_panel.rs diff --git a/assets/icons/add_column_dark_4x.png b/assets/icons/add_column_dark_4x.png new file mode 100644 index 0000000000000000000000000000000000000000..5d8c370b2bd514e372b8c6e5c283528df81da3c0 GIT binary patch literal 1150 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 { account_manager: AccountManager<'a>, simple_preview_controller: SimpleProfilePreviewController<'a>, - edit_mode: &'a mut bool, } impl<'a> View for AccountManagementView<'a> { @@ -28,37 +27,17 @@ impl<'a> AccountManagementView<'a> { pub fn new( account_manager: AccountManager<'a>, simple_preview_controller: SimpleProfilePreviewController<'a>, - edit_mode: &'a mut bool, ) -> Self { AccountManagementView { account_manager, simple_preview_controller, - edit_mode, } } fn show(&mut self, ui: &mut egui::Ui) { - ui.add_space(24.0); - let screen_size = ui.ctx().screen_rect(); - let margin_amt = 128.0; - let window_size = Vec2::new( - screen_size.width() - margin_amt, - screen_size.height() - margin_amt, - ); - - Window::new("Account Management") - .frame(Frame::window(ui.style())) - .collapsible(false) - .anchor(Align2::CENTER_CENTER, [0.0, 0.0]) - .resizable(false) - .title_bar(false) - .default_size(window_size) - .show(ui.ctx(), |ui| { - ui.add(title()); - ui.add(self.buttons_widget()); - ui.add_space(8.0); - self.show_accounts(ui); - }); + ui.add(self.buttons_widget()); + ui.add_space(8.0); + self.show_accounts(ui); } fn show_accounts(&mut self, ui: &mut egui::Ui) { @@ -67,7 +46,7 @@ impl<'a> AccountManagementView<'a> { let maybe_remove = self.simple_preview_controller.set_profile_previews( &self.account_manager, ui, - *self.edit_mode, + PERSISTED_ACCOUNT_MANAGEMENT.get_state(ui.ctx()), |ui, preview, edit_mode| { let mut should_remove = false; @@ -103,7 +82,7 @@ impl<'a> AccountManagementView<'a> { let maybe_remove = self.simple_preview_controller.set_profile_previews( &self.account_manager, ui, - *self.edit_mode, + PERSISTED_ACCOUNT_MANAGEMENT.get_state(ui.ctx()), |ui, preview, edit_mode| { let mut should_remove = false; @@ -168,12 +147,12 @@ impl<'a> AccountManagementView<'a> { Vec2::new(ui.available_size_before_wrap().x, 32.0), Layout::left_to_right(egui::Align::Center), |ui| { - if *self.edit_mode { + if PERSISTED_ACCOUNT_MANAGEMENT.get_state(ui.ctx()) { if ui.add(done_account_button()).clicked() { - *self.edit_mode = false; + PERSISTED_ACCOUNT_MANAGEMENT.set_state(ui.ctx(), false); } } else if ui.add(edit_account_button()).clicked() { - *self.edit_mode = true; + PERSISTED_ACCOUNT_MANAGEMENT.set_state(ui.ctx(), true); } }, ); @@ -193,6 +172,20 @@ impl<'a> AccountManagementView<'a> { } } +impl<'a> FromApp<'a> for AccountManagementView<'a> { + fn from_app(app: &'a mut crate::Damus) -> Self { + // TODO: don't hard-code key store & relay generator + AccountManagementView::new( + AccountManager::new( + &mut app.accounts, + crate::key_storage::KeyStorage::None, + crate::relay_generation::RelayGenerator::Constant, + ), + SimpleProfilePreviewController::new(&app.ndb, &mut app.img_cache), + ) + } +} + fn simple_preview_frame(ui: &mut egui::Ui) -> Frame { Frame::none() .rounding(ui.visuals().window_rounding) @@ -318,7 +311,6 @@ mod preview { accounts: Vec, ndb: Ndb, img_cache: ImageCache, - edit_mode: bool, } fn get_accounts() -> Vec { @@ -359,7 +351,6 @@ mod preview { accounts, ndb, img_cache, - edit_mode: false, } } } @@ -372,10 +363,10 @@ mod preview { RelayGenerator::Constant, ); + ui.add_space(24.0); AccountManagementView::new( account_manager, SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache), - &mut self.edit_mode, ) .ui(ui); } diff --git a/src/ui/global_popup.rs b/src/ui/global_popup.rs new file mode 100644 index 0000000..e7753b1 --- /dev/null +++ b/src/ui/global_popup.rs @@ -0,0 +1,127 @@ +use egui::{Align2, CentralPanel, RichText, Vec2, Window}; + +use crate::Damus; + +use super::{ + persist_state::{PERSISTED_GLOBAL_POPUP, PERSISTED_SIDE_PANEL}, + AccountManagementView, View, +}; + +#[derive(Clone, Copy, Debug)] +pub enum GlobalPopupType { + AccountManagement, +} + +static ACCOUNT_MANAGEMENT_TITLE: &str = "Account Management"; + +impl GlobalPopupType { + pub fn title(&self) -> &'static str { + match self { + Self::AccountManagement => ACCOUNT_MANAGEMENT_TITLE, + } + } +} + +pub trait FromApp<'a> { + fn from_app(app: &'a mut crate::Damus) -> Self + where + Self: Sized; +} + +fn title(title_str: &'static str) -> RichText { + RichText::new(title_str).size(24.0) +} + +fn overlay_window<'a>( + open: &'a mut bool, + window_size: Vec2, + title_str: &'static str, +) -> Window<'a> { + egui::Window::new(title(title_str)) + .anchor(Align2::CENTER_CENTER, [0.0, 0.0]) + .collapsible(false) + .auto_sized() + .movable(false) + .open(open) + .default_size(window_size) +} + +static MARGIN: Vec2 = Vec2 { x: 100.0, y: 100.0 }; + +pub struct DesktopGlobalPopup<'a> { + app: &'a mut Damus, +} + +impl<'a> View for DesktopGlobalPopup<'a> { + fn ui(&mut self, ui: &mut egui::Ui) { + DesktopGlobalPopup::global_popup(self.app, ui.ctx()) + } +} + +impl<'a> DesktopGlobalPopup<'a> { + pub fn new(app: &'a mut Damus) -> Self { + DesktopGlobalPopup { app } + } + pub fn global_popup(app: &mut Damus, ctx: &egui::Context) { + CentralPanel::default().show(ctx, |ui| { + let available_size = ui.available_size(); + let window_size = available_size - MARGIN; + + if let Some(popup) = PERSISTED_SIDE_PANEL.get_state(ctx) { + let mut show_global_popup = PERSISTED_GLOBAL_POPUP.get_state(ctx); + if show_global_popup { + overlay_window(&mut show_global_popup, window_size, popup.title()).show( + ctx, + |ui| { + match popup { + GlobalPopupType::AccountManagement => { + AccountManagementView::from_app(app).ui(ui) + } + }; + }, + ); + + // user could have closed the window, set the new state in egui memory + PERSISTED_GLOBAL_POPUP.set_state(ctx, show_global_popup); + } + } + }); + } +} + +mod preview { + use crate::{ + ui::{DesktopSidePanel, Preview, View}, + Damus, + }; + + use super::DesktopGlobalPopup; + + pub struct GlobalPopupPreview { + app: Damus, + } + + impl<'a> Preview for DesktopGlobalPopup<'a> { + type Prev = GlobalPopupPreview; + + fn preview() -> Self::Prev { + GlobalPopupPreview::new() + } + } + + impl GlobalPopupPreview { + fn new() -> Self { + GlobalPopupPreview { + app: Damus::mock("."), + } + } + } + + impl View for GlobalPopupPreview { + fn ui(&mut self, ui: &mut egui::Ui) { + let mut panel = DesktopSidePanel::new(ui.ctx()); + DesktopSidePanel::panel().show(ui.ctx(), |ui| panel.ui(ui)); + DesktopGlobalPopup::new(&mut self.app).ui(ui); + } + } +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 2a04501..ce4caf5 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,19 +1,24 @@ pub mod account_login_view; pub mod account_management; pub mod anim; +pub mod global_popup; pub mod mention; pub mod note; +pub mod persist_state; pub mod preview; pub mod profile; pub mod relay; +pub mod side_panel; pub mod username; pub use account_management::{AccountManagementView, AccountSelectionWidget}; +pub use global_popup::DesktopGlobalPopup; pub use mention::Mention; pub use note::Note; pub use preview::{Preview, PreviewApp}; pub use profile::{ProfilePic, ProfilePreview}; pub use relay::RelayView; +pub use side_panel::DesktopSidePanel; pub use username::Username; use egui::Margin; diff --git a/src/ui/persist_state.rs b/src/ui/persist_state.rs new file mode 100644 index 0000000..8a63ac3 --- /dev/null +++ b/src/ui/persist_state.rs @@ -0,0 +1,43 @@ +use egui::util::id_type_map::SerializableAny; + +use super::global_popup::GlobalPopupType; + +/// PersistState is a helper struct for interacting with egui memory persisted data +#[derive(Clone)] +pub struct PersistState { + id: &'static str, + default_state: T, +} + +impl PersistState { + pub fn get_state(&self, ctx: &egui::Context) -> T { + ctx.data_mut(|d| { + d.get_persisted(egui::Id::new(self.id)) + .unwrap_or(self.default_state.clone()) + }) + } + + pub fn set_state(&self, ctx: &egui::Context, new_val: T) { + ctx.data_mut(|d| d.insert_persisted(egui::Id::new(self.id), new_val)); + } +} + +pub static PERSISTED_ACCOUNT_MANAGEMENT: PersistState = PersistState:: { + id: ACCOUNT_MANAGEMENT_VIEW_STATE_ID, + default_state: false, +}; + +pub static PERSISTED_SIDE_PANEL: PersistState> = + PersistState::> { + id: SIDE_PANEL_VIEW_STATE_ID, + default_state: None, + }; + +pub static PERSISTED_GLOBAL_POPUP: PersistState = PersistState:: { + id: GLOBAL_POPUP_VIEW_STATE_ID, + default_state: false, +}; + +static ACCOUNT_MANAGEMENT_VIEW_STATE_ID: &str = "account management view state"; +static SIDE_PANEL_VIEW_STATE_ID: &str = "side panel view state"; +static GLOBAL_POPUP_VIEW_STATE_ID: &str = "global popup view state"; diff --git a/src/ui/side_panel.rs b/src/ui/side_panel.rs new file mode 100644 index 0000000..0a70f99 --- /dev/null +++ b/src/ui/side_panel.rs @@ -0,0 +1,93 @@ +use egui::{Button, Layout, SidePanel, Vec2}; + +use crate::ui::global_popup::GlobalPopupType; + +use super::{ + persist_state::{PERSISTED_GLOBAL_POPUP, PERSISTED_SIDE_PANEL}, + View, +}; + +pub struct DesktopSidePanel<'a> { + ctx: &'a egui::Context, +} + +static ID: &str = "left panel"; + +impl<'a> View for DesktopSidePanel<'a> { + fn ui(&mut self, ui: &mut egui::Ui) { + DesktopSidePanel::inner(self.ctx, ui); + } +} + +impl<'a> DesktopSidePanel<'a> { + pub fn new(ctx: &'a egui::Context) -> Self { + DesktopSidePanel { ctx } + } + + pub fn inner(ctx: &egui::Context, ui: &mut egui::Ui) { + let dark_mode = ui.ctx().style().visuals.dark_mode; + let spacing_amt = 16.0; + ui.with_layout(Layout::bottom_up(egui::Align::Center), |ui| { + ui.add_space(spacing_amt); + if ui + .add_sized(Vec2::new(32.0, 32.0), Button::new("A")) + .clicked() + { + PERSISTED_SIDE_PANEL.set_state(ctx, Some(GlobalPopupType::AccountManagement)); + PERSISTED_GLOBAL_POPUP.set_state(ctx, true); + } + ui.add_space(spacing_amt); + ui.add(settings_button(dark_mode)); + ui.add_space(spacing_amt); + ui.add(add_column_button(dark_mode)); + ui.add_space(spacing_amt); + }); + } + + pub fn panel() -> SidePanel { + egui::SidePanel::left(ID).resizable(false).exact_width(40.0) + } +} + +fn settings_button(dark_mode: bool) -> egui::Button<'static> { + let _ = dark_mode; + let img_data = egui::include_image!("../../assets/icons/settings_dark_4x.png"); + + egui::Button::image(egui::Image::new(img_data).max_width(32.0)).frame(false) +} + +fn add_column_button(dark_mode: bool) -> egui::Button<'static> { + let _ = dark_mode; + let img_data = egui::include_image!("../../assets/icons/add_column_dark_4x.png"); + + egui::Button::image(egui::Image::new(img_data).max_width(32.0)).frame(false) +} + +mod preview { + use crate::ui::Preview; + + use super::*; + + pub struct DesktopSidePanelPreview {} + + impl DesktopSidePanelPreview { + fn new() -> Self { + DesktopSidePanelPreview {} + } + } + + impl View for DesktopSidePanelPreview { + fn ui(&mut self, ui: &mut egui::Ui) { + let mut panel = DesktopSidePanel::new(ui.ctx()); + DesktopSidePanel::panel().show(ui.ctx(), |ui| panel.ui(ui)); + } + } + + impl Preview for DesktopSidePanel<'_> { + type Prev = DesktopSidePanelPreview; + + fn preview() -> Self::Prev { + DesktopSidePanelPreview::new() + } + } +} diff --git a/src/ui_preview/main.rs b/src/ui_preview/main.rs index d2bf9a0..f7c8d06 100644 --- a/src/ui_preview/main.rs +++ b/src/ui_preview/main.rs @@ -3,8 +3,8 @@ use notedeck::app_creation::{ }; use notedeck::ui::account_login_view::AccountLoginView; use notedeck::ui::{ - AccountManagementView, AccountSelectionWidget, Preview, PreviewApp, ProfilePic, ProfilePreview, - RelayView, + AccountManagementView, AccountSelectionWidget, DesktopGlobalPopup, DesktopSidePanel, Preview, + PreviewApp, ProfilePic, ProfilePreview, RelayView, }; use std::env; @@ -88,5 +88,7 @@ async fn main() { ProfilePic, AccountManagementView, AccountSelectionWidget, + DesktopSidePanel, + DesktopGlobalPopup, ); }