mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
wallet: add chatview coloring
This commit is contained in:
@@ -569,6 +569,35 @@ impl App {
|
||||
node.set_property_f32("baseline", 10.).unwrap();
|
||||
node.set_property_u32("z_index", 1).unwrap();
|
||||
|
||||
let prop = node.get_property("timestamp_color").unwrap();
|
||||
prop.set_f32(0, 0.5).unwrap();
|
||||
prop.set_f32(1, 0.5).unwrap();
|
||||
prop.set_f32(2, 0.5).unwrap();
|
||||
prop.set_f32(3, 0.5).unwrap();
|
||||
let prop = node.get_property("text_color").unwrap();
|
||||
prop.set_f32(0, 1.).unwrap();
|
||||
prop.set_f32(1, 1.).unwrap();
|
||||
prop.set_f32(2, 1.).unwrap();
|
||||
prop.set_f32(3, 1.).unwrap();
|
||||
|
||||
let prop = node.get_property("nick_colors").unwrap();
|
||||
#[rustfmt::skip]
|
||||
let nick_colors = [
|
||||
0.00, 0.94, 1.00, 1.,
|
||||
0.36, 1.00, 0.69, 1.,
|
||||
0.29, 1.00, 0.45, 1.,
|
||||
0.00, 0.73, 0.38, 1.,
|
||||
0.21, 0.67, 0.67, 1.,
|
||||
0.56, 0.61, 1.00, 1.,
|
||||
0.84, 0.48, 1.00, 1.,
|
||||
1.00, 0.61, 0.94, 1.,
|
||||
1.00, 0.36, 0.48, 1.,
|
||||
1.00, 0.30, 0.00, 1.
|
||||
];
|
||||
for c in nick_colors {
|
||||
prop.push_f32(c).unwrap();
|
||||
}
|
||||
|
||||
drop(sg);
|
||||
let db = sled::open(CHATDB_PATH).expect("cannot open sleddb");
|
||||
let chat_tree = db.open_tree(b"chat").unwrap();
|
||||
@@ -793,6 +822,21 @@ fn create_chatview(sg: &mut SceneGraph, name: &str) -> SceneNodeId {
|
||||
let prop = Property::new("line_height", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("timestamp_color", PropertyType::Float32, PropertySubType::Color);
|
||||
prop.set_array_len(4);
|
||||
prop.set_range_f32(0., 1.);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("text_color", PropertyType::Float32, PropertySubType::Color);
|
||||
prop.set_array_len(4);
|
||||
prop.set_range_f32(0., 1.);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("nick_colors", PropertyType::Float32, PropertySubType::Pixel);
|
||||
prop.set_unbounded();
|
||||
prop.set_range_f32(0., 1.);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
|
||||
@@ -26,9 +26,12 @@ pub type Color = [f32; 4];
|
||||
|
||||
pub const COLOR_RED: Color = [1., 0., 0., 1.];
|
||||
pub const COLOR_DARKGREY: Color = [0.2, 0.2, 0.2, 1.];
|
||||
pub const COLOR_LIGHTGREY: Color = [0.7, 0.7, 0.7, 1.];
|
||||
pub const COLOR_GREEN: Color = [0., 1., 0., 1.];
|
||||
pub const COLOR_BLUE: Color = [0., 0., 1., 1.];
|
||||
pub const COLOR_WHITE: Color = [1., 1., 1., 1.];
|
||||
pub const COLOR_BLACK: Color = [1., 1., 1., 1.];
|
||||
pub const COLOR_GREY: Color = [0.5, 0.5, 0.5, 1.];
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MeshInfo {
|
||||
|
||||
@@ -21,6 +21,7 @@ use miniquad::TouchPhase;
|
||||
use rand::{rngs::OsRng, Rng};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
hash::{DefaultHasher, Hash, Hasher},
|
||||
sync::{Arc, Mutex as SyncMutex, Weak},
|
||||
};
|
||||
|
||||
@@ -30,7 +31,7 @@ use crate::{
|
||||
DrawCall, DrawInstruction, DrawMesh, GraphicsEventPublisherPtr, Point, Rectangle,
|
||||
RenderApi, RenderApiPtr, Vertex,
|
||||
},
|
||||
mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_WHITE},
|
||||
mesh::{Color, MeshBuilder, MeshInfo, COLOR_BLUE, COLOR_GREY, COLOR_WHITE},
|
||||
prop::{
|
||||
PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr, PropertyStr, PropertyUint32,
|
||||
},
|
||||
@@ -44,6 +45,10 @@ use super::{eval_rect, get_parent_rect, read_rect, DrawUpdate, OnModify, Stoppab
|
||||
|
||||
const DEBUG_RENDER: bool = false;
|
||||
|
||||
fn is_whitespace(s: &str) -> bool {
|
||||
s.chars().all(char::is_whitespace)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
|
||||
pub struct ChatMsg {
|
||||
pub nick: String,
|
||||
@@ -104,6 +109,9 @@ pub struct ChatView {
|
||||
font_size: PropertyFloat32,
|
||||
line_height: PropertyFloat32,
|
||||
baseline: PropertyFloat32,
|
||||
timestamp_color: PropertyColor,
|
||||
text_color: PropertyColor,
|
||||
nick_colors: PropertyPtr,
|
||||
z_index: PropertyUint32,
|
||||
}
|
||||
|
||||
@@ -126,7 +134,10 @@ impl ChatView {
|
||||
let scroll = PropertyFloat32::wrap(node, "scroll", 0).unwrap();
|
||||
let font_size = PropertyFloat32::wrap(node, "font_size", 0).unwrap();
|
||||
let line_height = PropertyFloat32::wrap(node, "line_height", 0).unwrap();
|
||||
let baseline = PropertyFloat32::wrap(node, "line_height", 0).unwrap();
|
||||
let baseline = PropertyFloat32::wrap(node, "baseline", 0).unwrap();
|
||||
let timestamp_color = PropertyColor::wrap(node, "timestamp_color").unwrap();
|
||||
let text_color = PropertyColor::wrap(node, "text_color").unwrap();
|
||||
let nick_colors = node.get_property("nick_colors").expect("ChatView::nick_colors");
|
||||
let z_index = PropertyUint32::wrap(node, "z_index", 0).unwrap();
|
||||
|
||||
drop(scene_graph);
|
||||
@@ -188,6 +199,9 @@ impl ChatView {
|
||||
font_size,
|
||||
line_height,
|
||||
baseline,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
nick_colors,
|
||||
z_index,
|
||||
}
|
||||
});
|
||||
@@ -252,7 +266,7 @@ impl ChatView {
|
||||
debug!(target: "ui::chatview", "inside rect");
|
||||
let scroll = self.scroll.get();
|
||||
self.scroll.set(scroll + wheel_y * 50.);
|
||||
// Render will auto update from on_modify hook
|
||||
self.scrollview().await;
|
||||
}
|
||||
|
||||
async fn handle_mouse_move(&self, mouse_x: f32, mouse_y: f32) {
|
||||
@@ -460,35 +474,63 @@ impl ChatView {
|
||||
let mut draws = vec![];
|
||||
let color = COLOR_WHITE;
|
||||
|
||||
let timestamp_color = self.timestamp_color.get();
|
||||
let text_color = self.text_color.get();
|
||||
let nick_colors = self.read_nick_colors();
|
||||
|
||||
// This is a little hack to nudge the bottom line up slightly, otherwise
|
||||
// chars like p will cross the bottom.
|
||||
let descent = line_height / 2.;
|
||||
let descent = baseline / 2.;
|
||||
|
||||
// Pages start at the bottom.
|
||||
let mut current_idx = 1;
|
||||
let mut current_idx = 0;
|
||||
'pageloop: for page in pages {
|
||||
let mut mesh = MeshBuilder::new();
|
||||
|
||||
for msg in page.msgs {
|
||||
let glyphs = msg.glyphs;
|
||||
|
||||
let nick_color = self.select_nick_color(&msg.chatmsg.nick, &nick_colors);
|
||||
|
||||
// Keep track of the 'section'
|
||||
// Section 0 is the timestamp
|
||||
// Section 1 is the nickname (colorized)
|
||||
// Finally is just the message itself
|
||||
let mut section = 2;
|
||||
|
||||
let mut lines = text2::wrap(clip.w, font_size, &glyphs);
|
||||
// We are drawing bottom up but line wrap gives us lines in normal order
|
||||
lines.reverse();
|
||||
for line in lines {
|
||||
let off_y = descent + current_idx as f32 * line_height;
|
||||
let last_idx = lines.len() - 1;
|
||||
for (i, line) in lines.into_iter().enumerate() {
|
||||
let off_y = descent + baseline + current_idx as f32 * line_height;
|
||||
|
||||
//if px_height > clip.h {
|
||||
// break 'pageloop;
|
||||
//}
|
||||
|
||||
if i == last_idx {
|
||||
section = 0;
|
||||
}
|
||||
|
||||
// Render line
|
||||
let mut glyph_pos_iter = GlyphPositionIter::new(font_size, &line, baseline);
|
||||
for (mut glyph_rect, glyph) in glyph_pos_iter.zip(line.iter()) {
|
||||
let uv_rect =
|
||||
page.atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
|
||||
glyph_rect.y -= off_y;
|
||||
|
||||
let color = match section {
|
||||
0 => timestamp_color,
|
||||
1 => nick_color,
|
||||
_ => text_color,
|
||||
};
|
||||
|
||||
mesh.draw_box(&glyph_rect, color, uv_rect);
|
||||
|
||||
if section < 2 && is_whitespace(&glyph.substr) {
|
||||
section += 1;
|
||||
}
|
||||
}
|
||||
|
||||
current_idx += 1;
|
||||
@@ -524,6 +566,28 @@ impl ChatView {
|
||||
draws
|
||||
}
|
||||
|
||||
fn read_nick_colors(&self) -> Vec<Color> {
|
||||
let mut colors = vec![];
|
||||
let mut color = [0f32; 4];
|
||||
for i in 0..self.nick_colors.get_len() {
|
||||
color[i % 4] = self.nick_colors.get_f32(i).expect("prop logic err");
|
||||
|
||||
if i > 0 && i % 4 == 0 {
|
||||
let color = std::mem::take(&mut color);
|
||||
colors.push(color);
|
||||
}
|
||||
}
|
||||
colors
|
||||
}
|
||||
|
||||
fn select_nick_color(&self, nick: &str, nick_colors: &[Color]) -> Color {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
nick.hash(&mut hasher);
|
||||
let i = hasher.finish() as usize;
|
||||
let color = nick_colors[i % nick_colors.len()];
|
||||
color
|
||||
}
|
||||
|
||||
pub async fn draw(&self, sg: &SceneGraph, parent_rect: &Rectangle) -> Option<DrawUpdate> {
|
||||
debug!(target: "ui::chatview", "ChatView::draw()");
|
||||
// Only used for debug messages
|
||||
|
||||
Reference in New Issue
Block a user