notedeck

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

lib.rs (3672B)


      1 pub mod anim;
      2 pub mod app_images;
      3 pub mod colors;
      4 pub mod constants;
      5 pub mod contacts_list;
      6 pub mod context_menu;
      7 pub mod debug;
      8 pub mod header;
      9 pub mod icons;
     10 pub mod images;
     11 pub mod media;
     12 pub mod mention;
     13 pub mod nip51_set;
     14 pub mod note;
     15 pub mod profile;
     16 mod username;
     17 pub mod widgets;
     18 
     19 pub use anim::{rolling_number, AnimationHelper, PulseAlpha};
     20 pub use contacts_list::{ContactsListAction, ContactsListView};
     21 pub use debug::debug_slider;
     22 pub use icons::{expanding_button, ICON_EXPANSION_MULTIPLE, ICON_WIDTH};
     23 pub use mention::Mention;
     24 pub use note::{NoteContents, NoteOptions, NoteView};
     25 pub use profile::{ProfilePic, ProfilePreview};
     26 pub use username::Username;
     27 
     28 use egui::{Label, Margin, Pos2, RichText};
     29 
     30 /// This is kind of like the Widget trait but is meant for larger top-level
     31 /// views that are typically stateful.
     32 ///
     33 /// The Widget trait forces us to add mutable
     34 /// implementations at the type level, which screws us when generating Previews
     35 /// for a Widget. I would have just Widget instead of making this Trait otherwise.
     36 ///
     37 /// There is some precendent for this, it looks like there's a similar trait
     38 /// in the egui demo library.
     39 pub trait View {
     40     fn ui(&mut self, ui: &mut egui::Ui);
     41 }
     42 
     43 pub fn padding<R>(
     44     amount: impl Into<Margin>,
     45     ui: &mut egui::Ui,
     46     add_contents: impl FnOnce(&mut egui::Ui) -> R,
     47 ) -> egui::InnerResponse<R> {
     48     egui::Frame::new()
     49         .inner_margin(amount)
     50         .show(ui, add_contents)
     51 }
     52 
     53 pub fn hline(ui: &egui::Ui) {
     54     hline_with_width(ui, ui.available_rect_before_wrap().x_range());
     55 }
     56 
     57 pub fn hline_with_width(ui: &egui::Ui, range: egui::Rangef) {
     58     // pixel perfect horizontal line
     59     let rect = ui.available_rect_before_wrap();
     60     #[allow(deprecated)]
     61     let resize_y = ui.painter().round_to_pixel(rect.top()) - 0.5;
     62     let stroke = ui.style().visuals.widgets.noninteractive.bg_stroke;
     63     ui.painter().hline(range, resize_y, stroke);
     64 }
     65 
     66 pub fn secondary_label(ui: &mut egui::Ui, s: impl Into<String>) -> egui::Response {
     67     let color = ui.style().visuals.noninteractive().fg_stroke.color;
     68     ui.add(Label::new(RichText::new(s).size(10.0).color(color)).selectable(false))
     69 }
     70 
     71 const INPUT_RECT_KEY: &str = "notedeck_input_rect";
     72 
     73 /// Includes an input rect for keyboard visibility purposes. We use this to move the screen up if
     74 /// a soft keyboard intersects with the input box
     75 pub fn include_input(ui: &mut egui::Ui, resp: &egui::Response) {
     76     // only include input if we have focus
     77     if !resp.has_focus() {
     78         return;
     79     }
     80 
     81     ui.data_mut(|d| {
     82         let id = egui::Id::new(INPUT_RECT_KEY);
     83         match d.get_temp::<egui::Rect>(id) {
     84             Some(r) => d.insert_temp(id, resp.rect.union(r)),
     85             None => d.insert_temp(id, resp.rect),
     86         }
     87     })
     88 }
     89 
     90 /// Set the last input rect for keyboard visibility purposes. We use this to move the screen up if
     91 /// a soft keyboard intersects with the input box
     92 pub fn input_rect(ui: &mut egui::Ui) -> Option<egui::Rect> {
     93     ui.data(|d| d.get_temp(egui::Id::new(INPUT_RECT_KEY)))
     94 }
     95 
     96 /// Set the last input rect for keyboard visibility purposes. We use this to move the screen up if
     97 /// a soft keyboard intersects with the input box
     98 pub fn clear_input_rect(ui: &mut egui::Ui) {
     99     ui.data_mut(|d| d.remove::<egui::Rect>(egui::Id::new(INPUT_RECT_KEY)))
    100 }
    101 
    102 /// Center the galley on the center pos, returning the position of the top left position of the galley,
    103 /// for the `painter.galley(..)`
    104 pub fn galley_centered_pos(galley: &std::sync::Arc<egui::Galley>, center: Pos2) -> Pos2 {
    105     let mut top_left = center;
    106     top_left.x -= galley.rect.width() / 2.0;
    107     top_left.y -= galley.rect.height() / 2.0;
    108 
    109     top_left
    110 }