notedeck

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

lib.rs (3906B)


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