mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-19 19:46:50 +00:00
DPI work
This commit is contained in:
parent
c3e9f8b51f
commit
8703bbbf19
@ -10,7 +10,7 @@ use crate::signer::Signer;
|
|||||||
use nostr_types::{Event, Id, PublicKeyHex, Url};
|
use nostr_types::{Event, Id, PublicKeyHex, Url};
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::{AtomicBool, AtomicU32};
|
||||||
use tokio::sync::{broadcast, mpsc, Mutex, RwLock};
|
use tokio::sync::{broadcast, mpsc, Mutex, RwLock};
|
||||||
|
|
||||||
/// Only one of these is ever created, via lazy_static!, and represents
|
/// Only one of these is ever created, via lazy_static!, and represents
|
||||||
@ -73,6 +73,8 @@ pub struct Globals {
|
|||||||
/// Failed Avatar Fetches
|
/// Failed Avatar Fetches
|
||||||
pub failed_avatars: RwLock<HashSet<PublicKeyHex>>,
|
pub failed_avatars: RwLock<HashSet<PublicKeyHex>>,
|
||||||
|
|
||||||
|
pub pixels_per_point_times_100: AtomicU32,
|
||||||
|
|
||||||
/// UI status message
|
/// UI status message
|
||||||
pub status_message: RwLock<String>,
|
pub status_message: RwLock<String>,
|
||||||
|
|
||||||
@ -106,6 +108,7 @@ lazy_static! {
|
|||||||
feed: Feed::new(),
|
feed: Feed::new(),
|
||||||
fetcher: Fetcher::new(),
|
fetcher: Fetcher::new(),
|
||||||
failed_avatars: RwLock::new(HashSet::new()),
|
failed_avatars: RwLock::new(HashSet::new()),
|
||||||
|
pixels_per_point_times_100: AtomicU32::new(139), // 100 dpi, 1/72th inch => 1.38888
|
||||||
status_message: RwLock::new("Welcome to Gossip. Status messages will appear here. Click them to dismiss them.".to_owned()),
|
status_message: RwLock::new("Welcome to Gossip. Status messages will appear here. Click them to dismiss them.".to_owned()),
|
||||||
pull_following_merge: AtomicBool::new(true),
|
pull_following_merge: AtomicBool::new(true),
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ use std::ops::DerefMut;
|
|||||||
use std::{env, mem, thread};
|
use std::{env, mem, thread};
|
||||||
use tracing_subscriber::filter::EnvFilter;
|
use tracing_subscriber::filter::EnvFilter;
|
||||||
|
|
||||||
pub const AVATAR_SIZE: u32 = 48;
|
pub const AVATAR_SIZE: u32 = 64; // points, not pixels
|
||||||
pub const AVATAR_SIZE_F32: f32 = 48.0;
|
pub const AVATAR_SIZE_F32: f32 = 64.0; // points, not pixels
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
if env::var("RUST_LOG").is_err() {
|
if env::var("RUST_LOG").is_err() {
|
||||||
|
@ -310,12 +310,13 @@ impl People {
|
|||||||
// Finish this later (spawn)
|
// Finish this later (spawn)
|
||||||
let apubkeyhex = pubkeyhex.to_owned();
|
let apubkeyhex = pubkeyhex.to_owned();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let size = AVATAR_SIZE * GLOBALS.pixels_per_point_times_100.load(std::sync::atomic::Ordering::Relaxed) / 100;
|
||||||
if let Ok(image) = image::load_from_memory(&bytes) {
|
if let Ok(image) = image::load_from_memory(&bytes) {
|
||||||
// Note: we can't use egui_extras::image::load_image_bytes because we
|
// Note: we can't use egui_extras::image::load_image_bytes because we
|
||||||
// need to force a resize
|
// need to force a resize
|
||||||
let image = image.resize(
|
let image = image.resize(
|
||||||
AVATAR_SIZE,
|
size,
|
||||||
AVATAR_SIZE,
|
size,
|
||||||
image::imageops::FilterType::Nearest,
|
image::imageops::FilterType::Nearest,
|
||||||
); // DynamicImage
|
); // DynamicImage
|
||||||
let image_buffer = image.into_rgba8(); // RgbaImage (ImageBuffer)
|
let image_buffer = image.into_rgba8(); // RgbaImage (ImageBuffer)
|
||||||
@ -326,7 +327,7 @@ impl People {
|
|||||||
GLOBALS.people.avatars_temp.insert(apubkeyhex, color_image);
|
GLOBALS.people.avatars_temp.insert(apubkeyhex, color_image);
|
||||||
} else if let Ok(color_image) = egui_extras::image::load_svg_bytes_with_size(
|
} else if let Ok(color_image) = egui_extras::image::load_svg_bytes_with_size(
|
||||||
&bytes,
|
&bytes,
|
||||||
FitTo::Size(AVATAR_SIZE, AVATAR_SIZE),
|
FitTo::Size(size, size),
|
||||||
) {
|
) {
|
||||||
GLOBALS.people.avatars_temp.insert(apubkeyhex, color_image);
|
GLOBALS.people.avatars_temp.insert(apubkeyhex, color_image);
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,6 +15,7 @@ pub const DEFAULT_POW: u8 = 0;
|
|||||||
pub const DEFAULT_OFFLINE: bool = false;
|
pub const DEFAULT_OFFLINE: bool = false;
|
||||||
pub const DEFAULT_LIGHT_MODE: bool = true; // true = light false = dark
|
pub const DEFAULT_LIGHT_MODE: bool = true; // true = light false = dark
|
||||||
pub const DEFAULT_SET_CLIENT_TAG: bool = false;
|
pub const DEFAULT_SET_CLIENT_TAG: bool = false;
|
||||||
|
pub const DEFAULT_OVERRIDE_DPI: Option<u32> = None;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
@ -32,6 +33,7 @@ pub struct Settings {
|
|||||||
pub offline: bool,
|
pub offline: bool,
|
||||||
pub light_mode: bool,
|
pub light_mode: bool,
|
||||||
pub set_client_tag: bool,
|
pub set_client_tag: bool,
|
||||||
|
pub override_dpi: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
@ -51,6 +53,7 @@ impl Default for Settings {
|
|||||||
offline: DEFAULT_OFFLINE,
|
offline: DEFAULT_OFFLINE,
|
||||||
light_mode: DEFAULT_LIGHT_MODE,
|
light_mode: DEFAULT_LIGHT_MODE,
|
||||||
set_client_tag: DEFAULT_SET_CLIENT_TAG,
|
set_client_tag: DEFAULT_SET_CLIENT_TAG,
|
||||||
|
override_dpi: DEFAULT_OVERRIDE_DPI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,6 +110,16 @@ impl Settings {
|
|||||||
"offline" => settings.offline = numstr_to_bool(row.1),
|
"offline" => settings.offline = numstr_to_bool(row.1),
|
||||||
"light_mode" => settings.light_mode = numstr_to_bool(row.1),
|
"light_mode" => settings.light_mode = numstr_to_bool(row.1),
|
||||||
"set_client_tag" => settings.set_client_tag = numstr_to_bool(row.1),
|
"set_client_tag" => settings.set_client_tag = numstr_to_bool(row.1),
|
||||||
|
"override_dpi" => {
|
||||||
|
if row.1=="" {
|
||||||
|
settings.override_dpi = DEFAULT_OVERRIDE_DPI;
|
||||||
|
} else {
|
||||||
|
settings.override_dpi = match row.1.parse::<u32>() {
|
||||||
|
Ok(number) => Some(number),
|
||||||
|
_ => DEFAULT_OVERRIDE_DPI
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +152,8 @@ impl Settings {
|
|||||||
('pow', ?),\
|
('pow', ?),\
|
||||||
('offline', ?),\
|
('offline', ?),\
|
||||||
('light_mode', ?),\
|
('light_mode', ?),\
|
||||||
('set_client_tag', ?)",
|
('set_client_tag', ?),\
|
||||||
|
('override_dpi', ?)",
|
||||||
)?;
|
)?;
|
||||||
stmt.execute((
|
stmt.execute((
|
||||||
self.feed_chunk,
|
self.feed_chunk,
|
||||||
@ -154,6 +168,7 @@ impl Settings {
|
|||||||
bool_to_numstr(self.offline),
|
bool_to_numstr(self.offline),
|
||||||
bool_to_numstr(self.light_mode),
|
bool_to_numstr(self.light_mode),
|
||||||
bool_to_numstr(self.set_client_tag),
|
bool_to_numstr(self.set_client_tag),
|
||||||
|
self.override_dpi,
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
// Save private key identity
|
// Save private key identity
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::{GossipUi, Page};
|
use super::{GossipUi, Page};
|
||||||
|
use crate::AVATAR_SIZE_F32;
|
||||||
use crate::comms::ToOverlordMessage;
|
use crate::comms::ToOverlordMessage;
|
||||||
use crate::feed::FeedKind;
|
use crate::feed::FeedKind;
|
||||||
use crate::globals::{Globals, GLOBALS};
|
use crate::globals::{Globals, GLOBALS};
|
||||||
@ -10,6 +11,7 @@ use egui::{
|
|||||||
};
|
};
|
||||||
use linkify::{LinkFinder, LinkKind};
|
use linkify::{LinkFinder, LinkKind};
|
||||||
use nostr_types::{Event, EventKind, Id, IdHex, Tag};
|
use nostr_types::{Event, EventKind, Id, IdHex, Tag};
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
struct FeedPostParams {
|
struct FeedPostParams {
|
||||||
id: Id,
|
id: Id,
|
||||||
@ -442,13 +444,14 @@ fn render_post_actual(
|
|||||||
} else {
|
} else {
|
||||||
app.placeholder_avatar.clone()
|
app.placeholder_avatar.clone()
|
||||||
};
|
};
|
||||||
|
let size = AVATAR_SIZE_F32 * GLOBALS.pixels_per_point_times_100.load(Ordering::Relaxed) as f32 / 100.0;
|
||||||
if ui
|
if ui
|
||||||
.add(
|
.add(
|
||||||
Image::new(
|
Image::new(
|
||||||
&avatar,
|
&avatar,
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: crate::AVATAR_SIZE_F32,
|
x: size,
|
||||||
y: crate::AVATAR_SIZE_F32,
|
y: size,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.sense(Sense::click()),
|
.sense(Sense::click()),
|
||||||
|
@ -21,6 +21,7 @@ use egui::{
|
|||||||
};
|
};
|
||||||
use nostr_types::{Id, IdHex, PublicKey, PublicKeyHex, Tag};
|
use nostr_types::{Id, IdHex, PublicKey, PublicKeyHex, Tag};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
@ -90,6 +91,8 @@ struct GossipUi {
|
|||||||
avatars: HashMap<PublicKeyHex, TextureHandle>,
|
avatars: HashMap<PublicKeyHex, TextureHandle>,
|
||||||
new_relay_url: String,
|
new_relay_url: String,
|
||||||
tag_re: regex::Regex,
|
tag_re: regex::Regex,
|
||||||
|
override_dpi: bool,
|
||||||
|
override_dpi_value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for GossipUi {
|
impl Drop for GossipUi {
|
||||||
@ -100,9 +103,24 @@ impl Drop for GossipUi {
|
|||||||
|
|
||||||
impl GossipUi {
|
impl GossipUi {
|
||||||
fn new(cctx: &eframe::CreationContext<'_>) -> Self {
|
fn new(cctx: &eframe::CreationContext<'_>) -> Self {
|
||||||
// grab settings to determine whether to render dark_mode or light_mode
|
|
||||||
let settings = GLOBALS.settings.blocking_read().clone();
|
let settings = GLOBALS.settings.blocking_read().clone();
|
||||||
|
|
||||||
|
if let Some(dpi) = settings.override_dpi {
|
||||||
|
let ppt: f32 = dpi as f32 / 72.0;
|
||||||
|
cctx.egui_ctx.set_pixels_per_point(ppt);
|
||||||
|
} else if let Some(ppt) = cctx.integration_info.native_pixels_per_point {
|
||||||
|
cctx.egui_ctx.set_pixels_per_point(ppt);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::debug!("Pixels per point: {}", cctx.egui_ctx.pixels_per_point());
|
||||||
|
|
||||||
|
// Set global pixels_per_point_times_100, used for image scaling.
|
||||||
|
GLOBALS.pixels_per_point_times_100.store(
|
||||||
|
(cctx.egui_ctx.pixels_per_point() * 100.0) as u32,
|
||||||
|
Ordering::Relaxed
|
||||||
|
);
|
||||||
|
|
||||||
if !settings.light_mode {
|
if !settings.light_mode {
|
||||||
cctx.egui_ctx.set_visuals(style::dark_mode_visuals());
|
cctx.egui_ctx.set_visuals(style::dark_mode_visuals());
|
||||||
} else {
|
} else {
|
||||||
@ -141,6 +159,12 @@ impl GossipUi {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let current_dpi = (cctx.egui_ctx.pixels_per_point() * 72.0) as u32;
|
||||||
|
let (override_dpi, override_dpi_value): (bool, u32) = match settings.override_dpi {
|
||||||
|
Some(v) => (true, v),
|
||||||
|
None => (false, current_dpi)
|
||||||
|
};
|
||||||
|
|
||||||
GossipUi {
|
GossipUi {
|
||||||
next_frame: Instant::now(),
|
next_frame: Instant::now(),
|
||||||
page: Page::Feed(FeedKind::General),
|
page: Page::Feed(FeedKind::General),
|
||||||
@ -164,6 +188,8 @@ impl GossipUi {
|
|||||||
avatars: HashMap::new(),
|
avatars: HashMap::new(),
|
||||||
new_relay_url: "".to_owned(),
|
new_relay_url: "".to_owned(),
|
||||||
tag_re: regex::Regex::new(r"(\#\[\d+\])").unwrap(),
|
tag_re: regex::Regex::new(r"(\#\[\d+\])").unwrap(),
|
||||||
|
override_dpi,
|
||||||
|
override_dpi_value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
use super::{GossipUi, Page};
|
use super::{GossipUi, Page};
|
||||||
|
use crate::AVATAR_SIZE_F32;
|
||||||
use crate::comms::ToOverlordMessage;
|
use crate::comms::ToOverlordMessage;
|
||||||
use crate::db::DbPerson;
|
use crate::db::DbPerson;
|
||||||
use crate::globals::GLOBALS;
|
use crate::globals::GLOBALS;
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use egui::{Context, Image, RichText, ScrollArea, Sense, Ui, Vec2};
|
use egui::{Context, Image, RichText, ScrollArea, Sense, Ui, Vec2};
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
mod follow;
|
mod follow;
|
||||||
mod person;
|
mod person;
|
||||||
@ -71,13 +73,14 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, _frame: &mut eframe::Fra
|
|||||||
} else {
|
} else {
|
||||||
app.placeholder_avatar.clone()
|
app.placeholder_avatar.clone()
|
||||||
};
|
};
|
||||||
|
let size = AVATAR_SIZE_F32 * GLOBALS.pixels_per_point_times_100.load(Ordering::Relaxed) as f32 / 100.0;
|
||||||
if ui
|
if ui
|
||||||
.add(
|
.add(
|
||||||
Image::new(
|
Image::new(
|
||||||
&avatar,
|
&avatar,
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: crate::AVATAR_SIZE_F32,
|
x: size,
|
||||||
y: crate::AVATAR_SIZE_F32,
|
y: size,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.sense(Sense::click()),
|
.sense(Sense::click()),
|
||||||
|
@ -134,6 +134,25 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Override DPI: ")
|
||||||
|
.on_hover_text(
|
||||||
|
"On some systems, DPI is not reported properly. In other cases, people like to zoom in or out. This lets you.",
|
||||||
|
);
|
||||||
|
ui.checkbox(
|
||||||
|
&mut app.override_dpi,
|
||||||
|
"Override to ");
|
||||||
|
ui.add(Slider::new(&mut app.override_dpi_value, 72..=250).text("DPI"));
|
||||||
|
|
||||||
|
// set real setting if changed
|
||||||
|
app.settings.override_dpi = if app.override_dpi {
|
||||||
|
Some(app.override_dpi_value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
ui.add_space(12.0);
|
ui.add_space(12.0);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Maximum FPS: ")
|
ui.label("Maximum FPS: ")
|
||||||
|
Loading…
Reference in New Issue
Block a user