commit 36405cf7a6d4e64ee58e66e3047e672c912e9b15
parent 5904d4dc539b5d3d3ae94531e372a3868de3716b
Author: William Casarin <jb55@jb55.com>
Date: Thu, 21 Dec 2023 10:13:05 -0800
new background, drop shadow, larger text
Diffstat:
4 files changed, 104 insertions(+), 19 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -4,5 +4,6 @@ data.mdb
lock.mdb
.build-result
.buildcmd
+/fonts
tags
perf.data
diff --git a/src/gradient.rs b/src/gradient.rs
@@ -19,6 +19,31 @@ impl Gradient {
)
}
+ pub fn linear_many(colors: Vec<Color32>) -> Self {
+ if colors.is_empty() {
+ return Self(Vec::new());
+ }
+ if colors.len() == 1 {
+ return Self(vec![colors[0]; 256]);
+ }
+
+ let n = 255;
+ let mut result = Vec::new();
+ let segments = colors.len() - 1;
+
+ for i in 0..segments {
+ let left = Rgba::from(colors[i]);
+ let right = Rgba::from(colors[i + 1]);
+
+ for j in 0..=n {
+ let t = j as f32 / n as f32;
+ result.push(Color32::from(lerp(left..=right, t)));
+ }
+ }
+
+ Self(result)
+ }
+
pub fn radial_alpha_gradient(
center: Pos2,
radius: f32,
diff --git a/src/main.rs b/src/main.rs
@@ -36,6 +36,7 @@ pub struct Notecrumbs {
font_data: egui::FontData,
img_cache: Arc<ImageCache>,
default_pfp: egui::ImageData,
+ background: egui::ImageData,
/// How long do we wait for remote note requests
timeout: Duration,
@@ -265,15 +266,25 @@ fn get_gradient() -> egui::ColorImage {
let size = pfp::PFP_SIZE as usize;
let radius = (pfp::PFP_SIZE as f32) / 2.0;
let center = pos2(radius, radius);
- let start_color = Color32::from_rgb(0x1E, 0x55, 0xFF);
- let end_color = Color32::from_rgb(0xFA, 0x0D, 0xD4);
- let gradient = Gradient::radial_alpha_gradient(center, radius, start_color, end_color);
+ let scol = [0x1C, 0x55, 0xFF];
+ //let ecol = [0xFA, 0x0D, 0xD4];
+ let mcol = [0x7F, 0x35, 0xAB];
+ //let ecol = [0xFF, 0x0B, 0xD6];
+ let ecol = [0xC0, 0x2A, 0xBE];
+
+ // TODO: skia has r/b colors swapped for some reason, fix this
+ let start_color = Color32::from_rgb(scol[2], scol[1], scol[0]);
+ let mid_color = Color32::from_rgb(mcol[2], mcol[1], mcol[0]);
+ let end_color = Color32::from_rgb(ecol[2], ecol[1], ecol[0]);
+
+ let gradient = Gradient::linear_many(vec![start_color, mid_color, end_color]);
let pixels = gradient.to_pixel_row();
+ let width = pixels.len();
+ let height = 1;
- assert_eq!(pixels.len(), size * size);
ColorImage {
- size: [size, size],
+ size: [width, height],
pixels,
}
}
@@ -302,7 +313,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let timeout = get_env_timeout();
let img_cache = Arc::new(LruCache::new(std::num::NonZeroUsize::new(64).unwrap()));
let default_pfp = egui::ImageData::Color(Arc::new(get_default_pfp()));
- //let default_pfp = egui::ImageData::Color(get_gradient());
+ let background = egui::ImageData::Color(Arc::new(get_gradient()));
let font_data = egui::FontData::from_static(include_bytes!("../fonts/NotoSans-Regular.ttf"));
let app = Notecrumbs {
@@ -310,6 +321,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
keys,
timeout,
img_cache,
+ background,
font_data,
default_pfp,
};
diff --git a/src/render.rs b/src/render.rs
@@ -1,9 +1,14 @@
use crate::{fonts, Error, Notecrumbs};
-use egui::{Color32, FontId, RichText, Rounding, Vec2, Visuals};
+use egui::emath::Rot2;
+use egui::epaint::Shadow;
+use egui::{
+ pos2, Color32, FontId, Mesh, Rect, RichText, Rounding, Shape, TextureHandle, Vec2, Visuals,
+};
use log::{debug, info, warn};
use nostr_sdk::nips::nip19::Nip19;
use nostr_sdk::prelude::*;
use nostrdb::{Note, Transaction};
+use std::f32::consts::PI;
impl ProfileRenderData {
pub fn default(pfp: egui::ImageData) -> Self {
@@ -274,7 +279,7 @@ fn render_username(ui: &mut egui::Ui, profile: &ProfileRenderData) {
#[cfg(feature = "profiling")]
puffin::profile_function!();
let name = format!("@{}", profile.name);
- ui.label(RichText::new(&name).size(30.0).color(Color32::DARK_GRAY));
+ ui.label(RichText::new(&name).size(40.0).color(Color32::LIGHT_GRAY));
}
fn setup_visuals(font_data: &egui::FontData, ctx: &egui::Context) {
@@ -288,10 +293,10 @@ fn wrapped_body(ui: &mut egui::Ui, text: &str) {
use egui::text::{LayoutJob, TextFormat};
let format = TextFormat {
- font_id: FontId::proportional(40.0),
+ font_id: FontId::proportional(52.0),
color: Color32::WHITE,
- extra_letter_spacing: -1.0,
- line_height: Some(40.0),
+ extra_letter_spacing: -3.0,
+ line_height: Some(50.0),
..Default::default()
};
@@ -300,7 +305,7 @@ fn wrapped_body(ui: &mut egui::Ui, text: &str) {
job.justify = false;
job.halign = egui::Align::LEFT;
job.wrap = egui::text::TextWrapping {
- max_rows: 5,
+ max_rows: 4,
break_anywhere: false,
overflow_character: Some('…'),
..Default::default()
@@ -338,14 +343,15 @@ fn note_frame_align() -> egui::Layout {
fn note_ui(app: &Notecrumbs, ctx: &egui::Context, note: &NoteRenderData) {
setup_visuals(&app.font_data, ctx);
- let outer_margin = 40.0;
- let inner_margin = 60.0;
+ let outer_margin = 60.0;
+ let inner_margin = 40.0;
let canvas_width = 1200.0;
let canvas_height = 600.0;
//let canvas_size = Vec2::new(canvas_width, canvas_height);
let total_margin = outer_margin + inner_margin;
let pfp = ctx.load_texture("pfp", note.profile.pfp.clone(), Default::default());
+ let bg = ctx.load_texture("background", app.background.clone(), Default::default());
/*
let desired_height = canvas_height - total_margin * 2.0;
@@ -356,10 +362,19 @@ fn note_ui(app: &Notecrumbs, ctx: &egui::Context, note: &NoteRenderData) {
*/
egui::CentralPanel::default()
- .frame(egui::Frame::default().fill(Color32::from_rgb(0x43, 0x20, 0x62)))
+ .frame(
+ egui::Frame::default()
+ //.fill(Color32::from_rgb(0x43, 0x20, 0x62)
+ .fill(Color32::from_rgb(0x00, 0x00, 0x00)),
+ )
.show(&ctx, |ui| {
+ background_texture(ui, &bg);
egui::Frame::none()
.fill(Color32::from_rgb(0x0F, 0x0F, 0x0F))
+ .shadow(Shadow {
+ extrusion: 50.0,
+ color: Color32::from_black_alpha(60),
+ })
.rounding(Rounding::same(20.0))
.outer_margin(outer_margin)
.inner_margin(inner_margin)
@@ -375,12 +390,12 @@ fn note_ui(app: &Notecrumbs, ctx: &egui::Context, note: &NoteRenderData) {
ui.horizontal(|ui| {
ui.with_layout(right_aligned(), |ui| {
- ui.label(RichText::new("damus.io").size(20.0));
+ ui.label(RichText::new("damus.io").size(40.0));
});
});
ui.vertical(|ui| {
- ui.set_max_size(Vec2::new(desired_width, desired_height / 1.8));
+ ui.set_max_size(Vec2::new(desired_width, desired_height / 2.2));
ui.centered_and_justified(|ui| {
// only one widget is allowed in here
wrapped_body(ui, ¬e.note.content);
@@ -397,14 +412,46 @@ fn note_ui(app: &Notecrumbs, ctx: &egui::Context, note: &NoteRenderData) {
});
}
+fn background_texture(ui: &mut egui::Ui, texture: &TextureHandle) {
+ // Get the size of the panel
+ let size = ui.available_size();
+
+ // Create a rectangle for the texture
+ let rect = Rect::from_min_size(ui.min_rect().min, size);
+
+ // Get the current layer ID
+ let layer_id = ui.layer_id();
+
+ let uv = Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0));
+ //let uv_skewed = Rect::from_min_max(uv.min, pos2(uv.max.x, uv.max.y * 0.5));
+
+ // Get the painter and draw the texture
+ let painter = ui.ctx().layer_painter(layer_id);
+ let tint = Color32::WHITE;
+
+ let mut mesh = Mesh::with_texture(texture.into());
+
+ // Define vertices for a rectangle
+ mesh.add_rect_with_uv(rect, uv, Color32::WHITE);
+
+ //let origin = pos2(600.0, 300.0);
+ //let angle = Rot2::from_angle(45.0);
+ //mesh.rotate(angle, origin);
+
+ // Draw the mesh
+ painter.add(Shape::mesh(mesh));
+
+ //painter.image(texture.into(), rect, uv_skewed, tint);
+}
+
fn discuss_on_damus(ui: &mut egui::Ui) {
let button = egui::Button::new(
RichText::new("Discuss on Damus ➡")
- .size(20.0)
+ .size(30.0)
.color(Color32::BLACK),
)
.rounding(50.0)
- .min_size(Vec2::new(305.0, 64.0))
+ .min_size(Vec2::new(330.0, 75.0))
.fill(Color32::WHITE);
ui.add(button);