notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

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 }