side_panel.rs (5207B)
1 use egui::{Button, Layout, SidePanel, Vec2, Widget}; 2 3 use crate::{ui::profile_preview_controller, Damus}; 4 5 use super::{ProfilePic, View}; 6 7 pub struct DesktopSidePanel<'a> { 8 app: &'a mut Damus, 9 } 10 11 impl<'a> View for DesktopSidePanel<'a> { 12 fn ui(&mut self, ui: &mut egui::Ui) { 13 self.show(ui); 14 } 15 } 16 17 #[derive(Debug, Eq, PartialEq, Clone, Copy)] 18 pub enum SidePanelAction { 19 Panel, 20 Account, 21 Settings, 22 Columns, 23 } 24 25 pub struct SidePanelResponse { 26 pub response: egui::Response, 27 pub action: SidePanelAction, 28 } 29 30 impl SidePanelResponse { 31 fn new(action: SidePanelAction, response: egui::Response) -> Self { 32 SidePanelResponse { action, response } 33 } 34 } 35 36 impl<'a> DesktopSidePanel<'a> { 37 pub fn new(app: &'a mut Damus) -> Self { 38 DesktopSidePanel { app } 39 } 40 41 pub fn panel() -> SidePanel { 42 egui::SidePanel::left("side_panel") 43 .resizable(false) 44 .exact_width(40.0) 45 } 46 47 pub fn show(&mut self, ui: &mut egui::Ui) -> SidePanelResponse { 48 let dark_mode = ui.ctx().style().visuals.dark_mode; 49 let spacing_amt = 16.0; 50 51 let inner = ui 52 .with_layout(Layout::bottom_up(egui::Align::Center), |ui| { 53 ui.spacing_mut().item_spacing.y = spacing_amt; 54 let pfp_resp = self.pfp_button(ui); 55 let settings_resp = ui.add(settings_button(dark_mode)); 56 let column_resp = ui.add(add_column_button(dark_mode)); 57 58 if pfp_resp.clicked() { 59 egui::InnerResponse::new(SidePanelAction::Account, pfp_resp) 60 } else if settings_resp.clicked() || settings_resp.hovered() { 61 egui::InnerResponse::new(SidePanelAction::Settings, settings_resp) 62 } else if column_resp.clicked() || column_resp.hovered() { 63 egui::InnerResponse::new(SidePanelAction::Columns, column_resp) 64 } else { 65 egui::InnerResponse::new(SidePanelAction::Panel, pfp_resp) 66 } 67 }) 68 .inner; 69 70 SidePanelResponse::new(inner.inner, inner.response) 71 } 72 73 fn pfp_button(&mut self, ui: &mut egui::Ui) -> egui::Response { 74 if let Some(resp) = 75 profile_preview_controller::show_with_selected_pfp(self.app, ui, show_pfp()) 76 { 77 resp 78 } else { 79 add_button_to_ui(ui, no_account_pfp()) 80 } 81 } 82 83 pub fn perform_action(app: &mut Damus, action: SidePanelAction) { 84 match action { 85 SidePanelAction::Panel => {} // TODO 86 SidePanelAction::Account => app.show_account_switcher = !app.show_account_switcher, 87 SidePanelAction::Settings => {} // TODO 88 SidePanelAction::Columns => (), // TODO 89 } 90 } 91 } 92 93 fn show_pfp() -> fn(ui: &mut egui::Ui, pfp: ProfilePic) -> egui::Response { 94 |ui, pfp| { 95 let response = pfp.ui(ui); 96 ui.allocate_rect(response.rect, egui::Sense::click()) 97 } 98 } 99 100 fn settings_button(dark_mode: bool) -> egui::Button<'static> { 101 let _ = dark_mode; 102 let img_data = egui::include_image!("../../assets/icons/settings_dark_4x.png"); 103 104 egui::Button::image(egui::Image::new(img_data).max_width(32.0)).frame(false) 105 } 106 107 fn add_button_to_ui(ui: &mut egui::Ui, button: Button) -> egui::Response { 108 ui.add_sized(Vec2::new(32.0, 32.0), button) 109 } 110 111 fn no_account_pfp() -> Button<'static> { 112 Button::new("A") 113 .rounding(20.0) 114 .min_size(Vec2::new(38.0, 38.0)) 115 } 116 117 fn add_column_button(dark_mode: bool) -> egui::Button<'static> { 118 let _ = dark_mode; 119 let img_data = egui::include_image!("../../assets/icons/add_column_dark_4x.png"); 120 121 egui::Button::image(egui::Image::new(img_data).max_width(32.0)).frame(false) 122 } 123 124 mod preview { 125 126 use egui_extras::{Size, StripBuilder}; 127 128 use crate::{ 129 test_data, 130 ui::{AccountSelectionWidget, DesktopGlobalPopup, Preview, PreviewConfig}, 131 }; 132 133 use super::*; 134 135 pub struct DesktopSidePanelPreview { 136 app: Damus, 137 } 138 139 impl DesktopSidePanelPreview { 140 fn new(is_mobile: bool) -> Self { 141 let app = test_data::test_app(is_mobile); 142 DesktopSidePanelPreview { app } 143 } 144 } 145 146 impl View for DesktopSidePanelPreview { 147 fn ui(&mut self, ui: &mut egui::Ui) { 148 StripBuilder::new(ui) 149 .size(Size::exact(40.0)) 150 .sizes(Size::remainder(), 0) 151 .clip(true) 152 .horizontal(|mut strip| { 153 strip.cell(|ui| { 154 let mut panel = DesktopSidePanel::new(&mut self.app); 155 let response = panel.show(ui); 156 DesktopSidePanel::perform_action(&mut self.app, response.action); 157 }); 158 }); 159 160 AccountSelectionWidget::ui(&mut self.app, ui); 161 DesktopGlobalPopup::show(self.app.global_nav.clone(), &mut self.app, ui); 162 } 163 } 164 165 impl<'a> Preview for DesktopSidePanel<'a> { 166 type Prev = DesktopSidePanelPreview; 167 168 fn preview(cfg: PreviewConfig) -> Self::Prev { 169 DesktopSidePanelPreview::new(cfg.is_mobile) 170 } 171 } 172 }