mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-07 22:04:03 -05:00
app/chatview: migrate DateMessage to text2 API
This commit is contained in:
@@ -22,7 +22,7 @@ DEBUG_FEATURES = --features=enable-filelog,enable-plugins
|
||||
|
||||
#DEV_FEATURES = --features=enable-filelog,enable-netdebug,emulate-android
|
||||
#DEV_FEATURES = --features=enable-filelog,enable-netdebug,enable-plugins
|
||||
DEV_FEATURES = --features=enable-plugins
|
||||
DEV_FEATURES = --features=schema-test
|
||||
|
||||
default: build-release
|
||||
./darkfi-app
|
||||
@@ -82,7 +82,7 @@ assets/forest_720x1280.mp4:
|
||||
# Developer targets
|
||||
|
||||
dev: $(SRC) fonts assets/forest_1920x1080.ivf
|
||||
$(CARGO) lbuild $(DEV_FEATURES)
|
||||
$(CARGO) lbuild --no-default-features $(DEV_FEATURES)
|
||||
-mv target/debug/darkfi-app .
|
||||
./darkfi-app
|
||||
|
||||
|
||||
@@ -260,37 +260,3 @@ impl App {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Just for testing
|
||||
#[allow(dead_code)]
|
||||
fn populate_tree(tree: &sled::Tree) {
|
||||
let chat_txt = include_str!("../../data/chat.txt");
|
||||
for line in chat_txt.lines() {
|
||||
let parts: Vec<&str> = line.splitn(3, ' ').collect();
|
||||
assert_eq!(parts.len(), 3);
|
||||
let time_parts: Vec<&str> = parts[0].splitn(2, ':').collect();
|
||||
let (hour, min) = (time_parts[0], time_parts[1]);
|
||||
let hour = hour.parse::<u32>().unwrap();
|
||||
let min = min.parse::<u32>().unwrap();
|
||||
let dt: NaiveDateTime =
|
||||
NaiveDate::from_ymd_opt(2024, 8, 6).unwrap().and_hms_opt(hour, min, 0).unwrap();
|
||||
let timest = dt.and_utc().timestamp_millis() as u64;
|
||||
|
||||
let nick = parts[1].to_string();
|
||||
let text = parts[2].to_string();
|
||||
|
||||
// serial order is important here
|
||||
let timest = timest.to_be_bytes();
|
||||
assert_eq!(timest.len(), 8);
|
||||
let mut key = [0u8; 8 + 32];
|
||||
key[..8].clone_from_slice(×t);
|
||||
|
||||
let msg = chatview::ChatMsg { nick, text };
|
||||
let mut val = vec![];
|
||||
msg.encode(&mut val).unwrap();
|
||||
|
||||
tree.insert(&key, val).unwrap();
|
||||
}
|
||||
// O(n)
|
||||
d!("populated db with {} lines", tree.len());
|
||||
}
|
||||
|
||||
@@ -1604,3 +1604,38 @@ pub async fn make(
|
||||
});
|
||||
app.tasks.lock().unwrap().push(editz_text_task);
|
||||
}
|
||||
|
||||
// Just for testing
|
||||
#[allow(dead_code)]
|
||||
pub(super) fn populate_tree(tree: &sled::Tree) {
|
||||
use chrono::{NaiveDate, NaiveDateTime};
|
||||
let chat_txt = include_str!("../../../data/chat.txt");
|
||||
for line in chat_txt.lines() {
|
||||
let parts: Vec<&str> = line.splitn(3, ' ').collect();
|
||||
assert_eq!(parts.len(), 3);
|
||||
let time_parts: Vec<&str> = parts[0].splitn(2, ':').collect();
|
||||
let (hour, min) = (time_parts[0], time_parts[1]);
|
||||
let hour = hour.parse::<u32>().unwrap();
|
||||
let min = min.parse::<u32>().unwrap();
|
||||
let dt: NaiveDateTime =
|
||||
NaiveDate::from_ymd_opt(2024, 8, 6).unwrap().and_hms_opt(hour, min, 0).unwrap();
|
||||
let timest = dt.and_utc().timestamp_millis() as u64;
|
||||
|
||||
let nick = parts[1].to_string();
|
||||
let text = parts[2].to_string();
|
||||
|
||||
// serial order is important here
|
||||
let timest = timest.to_be_bytes();
|
||||
assert_eq!(timest.len(), 8);
|
||||
let mut key = [0u8; 8 + 32];
|
||||
key[..8].clone_from_slice(×t);
|
||||
|
||||
let msg = chatview::ChatMsg { nick, text };
|
||||
let mut val = vec![];
|
||||
msg.encode(&mut val).unwrap();
|
||||
|
||||
tree.insert(&key, val).unwrap();
|
||||
}
|
||||
// O(n)
|
||||
debug!(target: "app::schema", "populated db with {} lines", tree.len());
|
||||
}
|
||||
|
||||
@@ -16,33 +16,37 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use sled_overlay::sled;
|
||||
|
||||
use crate::{
|
||||
app::{
|
||||
node::{
|
||||
create_layer, create_singleline_edit, create_text, create_vector_art, create_video,
|
||||
create_chatview, create_layer, create_singleline_edit, create_text, create_vector_art,
|
||||
create_video,
|
||||
},
|
||||
App,
|
||||
},
|
||||
expr,
|
||||
expr::{self, Compiler},
|
||||
mesh::COLOR_PURPLE,
|
||||
prop::{PropertyAtomicGuard, PropertyFloat32, Role},
|
||||
scene::SceneNodePtr,
|
||||
ui::{BaseEdit, BaseEditType, Layer, Text, VectorArt, VectorShape, Video},
|
||||
ui::{BaseEdit, BaseEditType, ChatView, Layer, Text, VectorArt, VectorShape, Video},
|
||||
util::i18n::I18nBabelFish,
|
||||
};
|
||||
use super::chat::populate_tree;
|
||||
|
||||
const LIGHTMODE: bool = false;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
mod ui_consts {
|
||||
//pub const CHATDB_PATH: &str = "/data/data/darkfi.app/chatdb/";
|
||||
pub const CHATDB_PATH: &str = "/data/data/darkfi.app/chatdb/";
|
||||
//pub const KING_PATH: &str = "king.png";
|
||||
pub const VID_PATH: &str = "forest_720x1280.mp4";
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
mod ui_consts {
|
||||
//pub const CHATDB_PATH: &str = "chatdb";
|
||||
pub const CHATDB_PATH: &str = "chatdb";
|
||||
//pub const KING_PATH: &str = "assets/king.png";
|
||||
pub const VID_PATH: &str = "assets/forest_1920x1080.ivf";
|
||||
}
|
||||
@@ -61,6 +65,8 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut cc = Compiler::new();
|
||||
|
||||
// Create a layer called view
|
||||
let layer_node = create_layer("view");
|
||||
let prop = layer_node.get_property("rect").unwrap();
|
||||
@@ -226,6 +232,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
*/
|
||||
|
||||
// Create KING GNU!
|
||||
/*
|
||||
let node = create_video("king");
|
||||
let prop = node.get_property("rect").unwrap();
|
||||
prop.set_f32(atom, Role::App, 0, 80.).unwrap();
|
||||
@@ -236,6 +243,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
|
||||
let node = node.setup(|me| Video::new(me, app.render_api.clone(), app.ex.clone())).await;
|
||||
layer_node.link(node);
|
||||
*/
|
||||
|
||||
// Create some text
|
||||
let node = create_text("label");
|
||||
@@ -261,13 +269,13 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
prop.set_f32(atom, Role::App, 2, 0.).unwrap();
|
||||
prop.set_f32(atom, Role::App, 3, 1.).unwrap();
|
||||
node.set_property_u32(atom, Role::App, "z_index", 1).unwrap();
|
||||
node.set_property_bool(atom, Role::App, "debug", true).unwrap();
|
||||
|
||||
let node = node
|
||||
.setup(|me| Text::new(me, window_scale.clone(), app.render_api.clone(), i18n_fish.clone()))
|
||||
.await;
|
||||
layer_node.link(node);
|
||||
|
||||
/*
|
||||
// ChatView
|
||||
let node = create_chatview("chatty");
|
||||
let prop = node.get_property("rect").unwrap();
|
||||
@@ -318,7 +326,7 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
1.00, 0.30, 0.00, 1.
|
||||
];
|
||||
for c in nick_colors {
|
||||
prop.push_f32(Role::App, c).unwrap();
|
||||
prop.push_f32(atom, Role::App, c).unwrap();
|
||||
}
|
||||
|
||||
let prop = node.get_property("hi_bg_color").unwrap();
|
||||
@@ -348,13 +356,13 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
window_scale.clone(),
|
||||
app.render_api.clone(),
|
||||
app.text_shaper.clone(),
|
||||
app.ex.clone(),
|
||||
app.sg_root.clone(),
|
||||
)
|
||||
})
|
||||
.await;
|
||||
layer_node.link(node);
|
||||
*/
|
||||
|
||||
/*
|
||||
// Text edit
|
||||
let node = create_singleline_edit("editz");
|
||||
//let node = create_multiline_edit("editz");
|
||||
@@ -449,4 +457,5 @@ pub async fn make(app: &App, window: SceneNodePtr, i18n_fish: &I18nBabelFish) {
|
||||
node.call_method("focus", vec![]).await.unwrap();
|
||||
});
|
||||
app.tasks.lock().unwrap().push(focus_task);
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ pub fn setup_logging() -> Option<WorkerGuard> {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
let terminal_layer = tracing_subscriber::fmt::Layer::new()
|
||||
.with_span_events(FmtSpan::ENTER | FmtSpan::CLOSE)
|
||||
//.with_span_events(FmtSpan::ENTER | FmtSpan::CLOSE)
|
||||
.event_format(EventFormatter::new(true, true))
|
||||
.fmt_fields(tracing_subscriber::fmt::format::debug_fn(
|
||||
darkfi::util::logger::terminal_field_formatter,
|
||||
|
||||
@@ -78,6 +78,7 @@ pub fn render_layout_with_opts(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render the atlas
|
||||
let atlas = atlas.make();
|
||||
|
||||
|
||||
@@ -460,22 +460,24 @@ impl ChatView {
|
||||
return
|
||||
}
|
||||
|
||||
#[cfg(feature = "enable-plugins")]
|
||||
if let Some(url) = get_file_url(&text) {
|
||||
if let Some(fud) = self.sg_root.lookup_node("/plugin/fud") {
|
||||
msgbuf.insert_filemsg(
|
||||
timest,
|
||||
msg_id,
|
||||
FileMessageStatus::Initializing,
|
||||
nick,
|
||||
url.clone(),
|
||||
);
|
||||
// This is incorrect. Scenegraph paths should not be hardcoded in widgets
|
||||
// nor should there be dependencies on other widgets.
|
||||
// Instead use signals and slots through app layer. See how focus is done with
|
||||
// the edit widgets.
|
||||
let fud = self.sg_root.lookup_node("/plugin/fud").unwrap();
|
||||
msgbuf.insert_filemsg(
|
||||
timest,
|
||||
msg_id,
|
||||
FileMessageStatus::Initializing,
|
||||
nick,
|
||||
url.clone(),
|
||||
);
|
||||
|
||||
let mut data = vec![];
|
||||
url.encode(&mut data).unwrap();
|
||||
fud.call_method("get", data).await.unwrap();
|
||||
}
|
||||
} else {
|
||||
error!(target: "ui::chatview", "Fud plugin has not been loaded");
|
||||
let mut data = vec![];
|
||||
url.encode(&mut data).unwrap();
|
||||
fud.call_method("get", data).await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,11 +589,6 @@ impl ChatView {
|
||||
}
|
||||
};
|
||||
|
||||
let Some(fud) = self.sg_root.lookup_node("/plugin/fud") else {
|
||||
error!(target: "ui::chatview", "Fud plugin has not been loaded");
|
||||
return
|
||||
};
|
||||
|
||||
let mut do_redraw = false;
|
||||
for entry in iter {
|
||||
let Ok((k, v)) = entry else { break };
|
||||
@@ -609,7 +606,10 @@ impl ChatView {
|
||||
chatmsg.text.clone(),
|
||||
);
|
||||
|
||||
// See comment in handle_insert_line()
|
||||
#[cfg(feature = "enable-plugins")]
|
||||
if let Some(url) = get_file_url(&chatmsg.text) {
|
||||
let fud = self.sg_root.lookup_node("/plugin/fud").unwrap();
|
||||
msgbuf.insert_filemsg(
|
||||
timest,
|
||||
msg_id,
|
||||
@@ -634,7 +634,6 @@ impl ChatView {
|
||||
}
|
||||
remaining_visible -= msg_height;
|
||||
}
|
||||
//t!("do_redraw = {do_redraw} [trace_id={trace_id}]");
|
||||
if do_redraw {
|
||||
let atom = self.render_api.make_guard(gfxtag!("ChatView::handle_bgload"));
|
||||
self.redraw_cached(atom.batch_id, &mut msgbuf).await;
|
||||
@@ -710,7 +709,7 @@ impl ChatView {
|
||||
|
||||
let meshes = msgbuf.gen_meshes(rect, scroll).await;
|
||||
|
||||
for (y_pos, mesh) in meshes {
|
||||
for (y_pos, mut minstrs) in meshes {
|
||||
// Apply scroll and scissor
|
||||
// We use the scissor for scrolling
|
||||
// Because we use the scissor, our actual rect is now rect instead of parent_rect
|
||||
@@ -720,7 +719,7 @@ impl ChatView {
|
||||
let pos = Point::from([off_x, off_y]);
|
||||
|
||||
instrs.push(DrawInstruction::SetPos(pos));
|
||||
instrs.push(DrawInstruction::Draw(mesh));
|
||||
instrs.append(&mut minstrs);
|
||||
}
|
||||
|
||||
instrs
|
||||
|
||||
@@ -35,12 +35,13 @@ use url::Url;
|
||||
|
||||
use super::{max, MessageId, Timestamp};
|
||||
use crate::{
|
||||
gfx::{gfxtag, DrawMesh, ManagedTexturePtr, Rectangle, RenderApi},
|
||||
gfx::{gfxtag, DrawInstruction, DrawMesh, ManagedTexturePtr, Point, Rectangle, RenderApi},
|
||||
mesh::{
|
||||
Color, MeshBuilder, COLOR_BLUE, COLOR_CYAN, COLOR_GREEN, COLOR_PINK, COLOR_RED, COLOR_WHITE,
|
||||
},
|
||||
prop::{PropertyBool, PropertyColor, PropertyFloat32, PropertyPtr},
|
||||
text::{self, Glyph, GlyphPositionIter, TextShaper, TextShaperPtr},
|
||||
text2,
|
||||
util::enumerate_mut,
|
||||
};
|
||||
|
||||
@@ -379,34 +380,19 @@ impl std::fmt::Debug for PrivMessage {
|
||||
pub struct DateMessage {
|
||||
font_size: f32,
|
||||
window_scale: f32,
|
||||
|
||||
timestamp: Timestamp,
|
||||
glyphs: Vec<Glyph>,
|
||||
|
||||
atlas: text::RenderedAtlas,
|
||||
mesh_cache: Option<DrawMesh>,
|
||||
mesh_cache: Option<Vec<DrawInstruction>>,
|
||||
}
|
||||
|
||||
impl DateMessage {
|
||||
pub fn new(
|
||||
font_size: f32,
|
||||
window_scale: f32,
|
||||
|
||||
timestamp: Timestamp,
|
||||
|
||||
text_shaper: &TextShaper,
|
||||
render_api: &RenderApi,
|
||||
_render_api: &RenderApi,
|
||||
) -> Message {
|
||||
let datestr = Self::datestr(timestamp);
|
||||
let timestamp = Self::timest_to_midnight(timestamp);
|
||||
|
||||
let glyphs = text_shaper.shape(datestr, font_size, window_scale);
|
||||
|
||||
let mut atlas = text::Atlas::new(render_api, gfxtag!("chatview_datemsg"));
|
||||
atlas.push(&glyphs);
|
||||
let atlas = atlas.make();
|
||||
|
||||
Message::Date(Self { font_size, window_scale, timestamp, glyphs, atlas, mesh_cache: None })
|
||||
Message::Date(Self { font_size, window_scale, timestamp, mesh_cache: None })
|
||||
}
|
||||
|
||||
fn datestr(timestamp: Timestamp) -> String {
|
||||
@@ -423,66 +409,60 @@ impl DateMessage {
|
||||
timestamp
|
||||
}
|
||||
|
||||
/// clear_mesh() must be called after this.
|
||||
fn adjust_params(
|
||||
&mut self,
|
||||
font_size: f32,
|
||||
window_scale: f32,
|
||||
text_shaper: &TextShaper,
|
||||
render_api: &RenderApi,
|
||||
_text_shaper: &TextShaper,
|
||||
_render_api: &RenderApi,
|
||||
) {
|
||||
self.font_size = font_size;
|
||||
self.window_scale = window_scale;
|
||||
|
||||
let datestr = Self::datestr(self.timestamp);
|
||||
self.glyphs = text_shaper.shape(datestr, font_size, window_scale);
|
||||
|
||||
let mut atlas = text::Atlas::new(render_api, gfxtag!("chatview_datemsg"));
|
||||
atlas.push(&self.glyphs);
|
||||
self.atlas = atlas.make();
|
||||
}
|
||||
|
||||
//fn adjust_width(&mut self, line_width: f32) { }
|
||||
|
||||
fn clear_mesh(&mut self) {
|
||||
// Auto-deletes when refs are dropped
|
||||
self.mesh_cache = None;
|
||||
}
|
||||
|
||||
fn gen_mesh(
|
||||
fn clear_mesh(&mut self) {
|
||||
self.mesh_cache = None;
|
||||
}
|
||||
|
||||
async fn gen_mesh(
|
||||
&mut self,
|
||||
clip: &Rectangle,
|
||||
_clip: &Rectangle,
|
||||
line_height: f32,
|
||||
baseline: f32,
|
||||
_baseline: f32,
|
||||
_nick_colors: &[Color],
|
||||
timestamp_color: Color,
|
||||
_text_color: Color,
|
||||
debug_render: bool,
|
||||
_debug_render: bool,
|
||||
render_api: &RenderApi,
|
||||
) -> DrawMesh {
|
||||
let mut mesh = MeshBuilder::new(gfxtag!("chatview_datemsg"));
|
||||
|
||||
let glyph_pos_iter =
|
||||
GlyphPositionIter::new(self.font_size, self.window_scale, &self.glyphs, baseline);
|
||||
for (mut glyph_rect, glyph) in glyph_pos_iter.zip(self.glyphs.iter()) {
|
||||
let uv_rect = self.atlas.fetch_uv(glyph.glyph_id).expect("missing glyph UV rect");
|
||||
glyph_rect.y -= line_height;
|
||||
mesh.draw_box(&glyph_rect, timestamp_color, uv_rect);
|
||||
) -> Vec<DrawInstruction> {
|
||||
// Return cached mesh if available
|
||||
if let Some(cache) = &self.mesh_cache {
|
||||
return cache.clone()
|
||||
}
|
||||
|
||||
if debug_render {
|
||||
mesh.draw_outline(
|
||||
&Rectangle { x: 0., y: -line_height, w: clip.w, h: line_height },
|
||||
COLOR_PINK,
|
||||
1.,
|
||||
);
|
||||
}
|
||||
let datestr = Self::datestr(self.timestamp);
|
||||
|
||||
let mesh = mesh.alloc(render_api);
|
||||
let mesh = mesh.draw_with_textures(vec![self.atlas.texture.clone()]);
|
||||
self.mesh_cache = Some(mesh.clone());
|
||||
let mut txt_ctx = text2::TEXT_CTX.get().await;
|
||||
let layout = txt_ctx.make_layout(
|
||||
&datestr,
|
||||
timestamp_color,
|
||||
self.font_size,
|
||||
line_height / self.font_size,
|
||||
self.window_scale,
|
||||
None,
|
||||
&[],
|
||||
);
|
||||
drop(txt_ctx);
|
||||
|
||||
mesh
|
||||
let mut txt_instrs = text2::render_layout(&layout, render_api, gfxtag!("chatview_datemsg"));
|
||||
let mut instrs = Vec::with_capacity(1 + txt_instrs.len());
|
||||
instrs.push(DrawInstruction::Move(Point::new(0., -line_height)));
|
||||
instrs.append(&mut txt_instrs);
|
||||
|
||||
// Cache the instructions
|
||||
self.mesh_cache = Some(instrs.clone());
|
||||
instrs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,7 +834,7 @@ impl Message {
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_mesh(
|
||||
async fn gen_mesh(
|
||||
&mut self,
|
||||
clip: &Rectangle,
|
||||
line_height: f32,
|
||||
@@ -867,44 +847,51 @@ impl Message {
|
||||
hi_bg_color: Color,
|
||||
debug_render: bool,
|
||||
render_api: &RenderApi,
|
||||
) -> Vec<DrawMesh> {
|
||||
) -> Vec<DrawInstruction> {
|
||||
match self {
|
||||
Self::Priv(m) => vec![m.gen_mesh(
|
||||
clip,
|
||||
line_height,
|
||||
msg_spacing,
|
||||
baseline,
|
||||
timestamp_width,
|
||||
nick_colors,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
hi_bg_color,
|
||||
debug_render,
|
||||
render_api,
|
||||
)],
|
||||
Self::Date(m) => vec![m.gen_mesh(
|
||||
clip,
|
||||
line_height,
|
||||
baseline,
|
||||
// No timestamp_width
|
||||
nick_colors,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
// No hi_bg_color since dates can't be highlighted
|
||||
debug_render,
|
||||
render_api,
|
||||
)],
|
||||
Self::File(m) => m.gen_mesh(
|
||||
clip,
|
||||
line_height,
|
||||
baseline,
|
||||
timestamp_width,
|
||||
nick_colors,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
debug_render,
|
||||
render_api,
|
||||
),
|
||||
Self::Priv(m) => {
|
||||
let mesh = m.gen_mesh(
|
||||
clip,
|
||||
line_height,
|
||||
msg_spacing,
|
||||
baseline,
|
||||
timestamp_width,
|
||||
nick_colors,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
hi_bg_color,
|
||||
debug_render,
|
||||
render_api,
|
||||
);
|
||||
vec![DrawInstruction::Draw(mesh)]
|
||||
}
|
||||
Self::Date(m) => {
|
||||
m.gen_mesh(
|
||||
clip,
|
||||
line_height,
|
||||
baseline,
|
||||
nick_colors,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
debug_render,
|
||||
render_api,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Self::File(m) => {
|
||||
let meshes = m.gen_mesh(
|
||||
clip,
|
||||
line_height,
|
||||
baseline,
|
||||
timestamp_width,
|
||||
nick_colors,
|
||||
timestamp_color,
|
||||
text_color,
|
||||
debug_render,
|
||||
render_api,
|
||||
);
|
||||
meshes.into_iter().map(DrawInstruction::Draw).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1221,8 +1208,12 @@ impl MessageBuffer {
|
||||
msg_height
|
||||
}
|
||||
|
||||
/// Generate caches and return meshes
|
||||
pub async fn gen_meshes(&mut self, rect: &Rectangle, scroll: f32) -> Vec<(f32, DrawMesh)> {
|
||||
/// Generate caches and return draw instructions
|
||||
pub async fn gen_meshes(
|
||||
&mut self,
|
||||
rect: &Rectangle,
|
||||
scroll: f32,
|
||||
) -> Vec<(f32, Vec<DrawInstruction>)> {
|
||||
let line_height = self.line_height.get();
|
||||
let msg_spacing = self.msg_spacing.get();
|
||||
let baseline = self.baseline.get();
|
||||
@@ -1255,27 +1246,27 @@ impl MessageBuffer {
|
||||
continue
|
||||
}
|
||||
|
||||
for mesh in msg.gen_mesh(
|
||||
rect,
|
||||
line_height,
|
||||
msg_spacing,
|
||||
baseline,
|
||||
timestamp_width,
|
||||
&nick_colors,
|
||||
timest_color,
|
||||
text_color,
|
||||
hi_bg_color,
|
||||
debug_render,
|
||||
&render_api,
|
||||
) {
|
||||
meshes.push((current_pos, mesh));
|
||||
}
|
||||
let instrs = msg
|
||||
.gen_mesh(
|
||||
rect,
|
||||
line_height,
|
||||
msg_spacing,
|
||||
baseline,
|
||||
timestamp_width,
|
||||
&nick_colors,
|
||||
timest_color,
|
||||
text_color,
|
||||
hi_bg_color,
|
||||
debug_render,
|
||||
&render_api,
|
||||
)
|
||||
.await;
|
||||
|
||||
meshes.push((current_pos, instrs));
|
||||
|
||||
current_pos += msg_spacing;
|
||||
current_pos += mesh_height;
|
||||
}
|
||||
|
||||
//t!("gen_meshes() returning {} meshes", meshes.len());
|
||||
meshes
|
||||
}
|
||||
|
||||
@@ -1364,13 +1355,7 @@ impl MessageBuffer {
|
||||
let timest = Local.from_local_datetime(&dt).unwrap().timestamp_millis() as u64;
|
||||
|
||||
if !self.date_msgs.contains_key(&date) {
|
||||
let datemsg = DateMessage::new(
|
||||
font_size,
|
||||
window_scale,
|
||||
timest,
|
||||
&self.text_shaper,
|
||||
&self.render_api,
|
||||
);
|
||||
let datemsg = DateMessage::new(font_size, window_scale, timest, &self.render_api);
|
||||
self.date_msgs.insert(date, datemsg);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ use tracing::instrument;
|
||||
|
||||
use crate::{
|
||||
gfx::{gfxtag, DrawCall, DrawInstruction, Rectangle, RenderApi},
|
||||
mesh::MeshBuilder,
|
||||
prop::{
|
||||
BatchGuardPtr, PropertyAtomicGuard, PropertyBool, PropertyColor, PropertyFloat32,
|
||||
PropertyRect, PropertyStr, PropertyUint32, Role,
|
||||
@@ -158,6 +159,14 @@ impl Text {
|
||||
let mut instrs = vec![DrawInstruction::Move(rect.pos())];
|
||||
instrs.append(&mut self.regen_mesh().await);
|
||||
|
||||
if self.debug.get() {
|
||||
let rect = self.rect.get().with_zero_pos();
|
||||
let mut mesh = MeshBuilder::new(gfxtag!("text_debug-rect"));
|
||||
mesh.draw_outline(&rect, [0., 1., 0., 0.7], 1.);
|
||||
let mesh = mesh.alloc(&self.render_api).draw_untextured();
|
||||
instrs.push(DrawInstruction::Draw(mesh));
|
||||
}
|
||||
|
||||
Some(DrawUpdate {
|
||||
key: self.dc_key,
|
||||
draw_calls: vec![(
|
||||
|
||||
Reference in New Issue
Block a user