mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
wallet/chatedit: resize with wrapped text
This commit is contained in:
@@ -268,6 +268,9 @@ pub fn create_chatedit(name: &str) -> SceneNode {
|
||||
let prop = Property::new("baseline", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let prop = Property::new("descent", PropertyType::Float32, PropertySubType::Pixel);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
let mut prop = Property::new("scroll", PropertyType::Float32, PropertySubType::Pixel);
|
||||
prop.set_range_f32(0., f32::MAX);
|
||||
node.add_property(prop).unwrap();
|
||||
|
||||
@@ -47,12 +47,13 @@ const LIGHTMODE: bool = false;
|
||||
|
||||
mod android_ui_consts {
|
||||
pub const EDITCHAT_HEIGHT: f32 = 163.;
|
||||
pub const EDITCHAT_BOTTOM_PAD: f32 = 70.;
|
||||
pub const EDITCHAT_BOTTOM_PAD: f32 = 50.;
|
||||
pub const EDITCHAT_CURSOR_ASCENT: f32 = 50.;
|
||||
pub const EDITCHAT_CURSOR_DESCENT: f32 = 20.;
|
||||
pub const EDITCHAT_SELECT_ASCENT: f32 = 40.;
|
||||
pub const EDITCHAT_SELECT_DESCENT: f32 = 8.;
|
||||
pub const TEXTBAR_BASELINE: f32 = 93.;
|
||||
pub const TEXT_DESCENT: f32 = 20.;
|
||||
pub const EDITCHAT_LHS_PAD: f32 = 30.;
|
||||
pub const SENDLABEL_WIDTH: f32 = 200.;
|
||||
pub const SENDLABEL_LHS_PAD: f32 = 40.;
|
||||
@@ -89,12 +90,13 @@ mod ui_consts {
|
||||
pub const KING_PATH: &str = "assets/king.png";
|
||||
pub const BG_PATH: &str = "assets/bg.png";
|
||||
pub const EDITCHAT_HEIGHT: f32 = 50.;
|
||||
pub const EDITCHAT_BOTTOM_PAD: f32 = 16.;
|
||||
pub const EDITCHAT_BOTTOM_PAD: f32 = 6.;
|
||||
pub const EDITCHAT_CURSOR_ASCENT: f32 = 25.;
|
||||
pub const EDITCHAT_CURSOR_DESCENT: f32 = 8.;
|
||||
pub const EDITCHAT_SELECT_ASCENT: f32 = 30.;
|
||||
pub const EDITCHAT_SELECT_DESCENT: f32 = 10.;
|
||||
pub const TEXTBAR_BASELINE: f32 = 34.;
|
||||
pub const TEXT_DESCENT: f32 = 10.;
|
||||
pub const EDITCHAT_LHS_PAD: f32 = 20.;
|
||||
pub const SENDLABEL_WIDTH: f32 = 120.;
|
||||
pub const SENDLABEL_LHS_PAD: f32 = 30.;
|
||||
@@ -730,12 +732,15 @@ pub(super) async fn make(app: &App, window: SceneNodePtr) {
|
||||
let node = create_vector_art("editbox_bg");
|
||||
let prop = node.get_property("rect").unwrap();
|
||||
prop.set_f32(Role::App, 0, 0.).unwrap();
|
||||
let code = cc.compile("h - EDITCHAT_HEIGHT").unwrap();
|
||||
let code = cc.compile("h - editz_h").unwrap();
|
||||
prop.set_expr(Role::App, 1, code).unwrap();
|
||||
prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
|
||||
prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
|
||||
let code = cc.compile("editz_h").unwrap();
|
||||
prop.set_expr(Role::App, 3, code).unwrap();
|
||||
node.set_property_u32(Role::App, "z_index", 2).unwrap();
|
||||
|
||||
let editbox_bg_rect_prop = prop.clone();
|
||||
|
||||
let mut shape = VectorShape::new();
|
||||
shape.add_filled_box(
|
||||
expr::const_f32(0.),
|
||||
@@ -818,8 +823,10 @@ pub(super) async fn make(app: &App, window: SceneNodePtr) {
|
||||
prop.set_f32(Role::App, 3, EDITCHAT_HEIGHT).unwrap();
|
||||
|
||||
chatview_rect_prop.add_depend(&prop, 3, "editz_h");
|
||||
editbox_bg_rect_prop.add_depend(&prop, 3, "editz_h");
|
||||
|
||||
node.set_property_f32(Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
|
||||
node.set_property_f32(Role::App, "descent", TEXT_DESCENT).unwrap();
|
||||
node.set_property_f32(Role::App, "font_size", FONTSIZE).unwrap();
|
||||
//node.set_property_str(Role::App, "text", "hello king!😁🍆jelly 🍆1234").unwrap();
|
||||
let prop = node.get_property("text_color").unwrap();
|
||||
@@ -912,72 +919,4 @@ pub(super) async fn make(app: &App, window: SceneNodePtr) {
|
||||
|
||||
let node = node.setup(|me| Button::new(me, app.ex.clone())).await;
|
||||
layer_node.clone().link(node);
|
||||
|
||||
// Create a popup layer to show upgrade msg
|
||||
let node = create_layer("upgrade_popup");
|
||||
let prop = node.get_property("rect").unwrap();
|
||||
prop.set_f32(Role::App, 0, 0.).unwrap();
|
||||
prop.set_f32(Role::App, 1, 0.).unwrap();
|
||||
prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
|
||||
let code = cc.compile("h / 2").unwrap();
|
||||
prop.set_expr(Role::App, 3, code).unwrap();
|
||||
node.set_property_bool(Role::App, "is_visible", false).unwrap();
|
||||
node.set_property_u32(Role::App, "z_index", 10).unwrap();
|
||||
let popup_layer_node =
|
||||
node.setup(|me| Layer::new(me, app.render_api.clone(), app.ex.clone())).await;
|
||||
layer_node.clone().link(popup_layer_node.clone());
|
||||
|
||||
// Background for popup
|
||||
let node = create_vector_art("upgradebg");
|
||||
let prop = node.get_property("rect").unwrap();
|
||||
prop.set_f32(Role::App, 0, 0.).unwrap();
|
||||
prop.set_f32(Role::App, 1, 0.).unwrap();
|
||||
prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
|
||||
prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
|
||||
node.set_property_u32(Role::App, "z_index", 0).unwrap();
|
||||
|
||||
// Setup the pimpl
|
||||
let verts = vec![
|
||||
ShapeVertex::from_xy(0., 0., [1., 0., 0., 1.]),
|
||||
ShapeVertex::new(expr::load_var("w"), expr::const_f32(0.), [1., 0., 1., 1.]),
|
||||
ShapeVertex::new(expr::const_f32(0.), expr::load_var("h"), [0., 0., 1., 1.]),
|
||||
ShapeVertex::new(expr::load_var("w"), expr::load_var("h"), [1., 1., 0., 1.]),
|
||||
];
|
||||
let indices = vec![0, 2, 1, 1, 2, 3];
|
||||
let shape = VectorShape { verts, indices };
|
||||
let node =
|
||||
node.setup(|me| VectorArt::new(me, shape, app.render_api.clone(), app.ex.clone())).await;
|
||||
popup_layer_node.clone().link(node);
|
||||
|
||||
// Create some text
|
||||
let node = create_text("send_label");
|
||||
let prop = node.get_property("rect").unwrap();
|
||||
prop.set_f32(Role::App, 0, 10.).unwrap();
|
||||
prop.set_f32(Role::App, 1, 10.).unwrap();
|
||||
prop.set_expr(Role::App, 2, expr::load_var("w")).unwrap();
|
||||
prop.set_expr(Role::App, 3, expr::load_var("h")).unwrap();
|
||||
node.set_property_f32(Role::App, "baseline", TEXTBAR_BASELINE).unwrap();
|
||||
node.set_property_f32(Role::App, "font_size", 2. * FONTSIZE).unwrap();
|
||||
node.set_property_str(Role::App, "text", "YO THERE'S A NEW VERSION!!! UPGRADE TIEM!!!")
|
||||
.unwrap();
|
||||
//node.set_property_str(Role::App, "text", "anon1").unwrap();
|
||||
let prop = node.get_property("text_color").unwrap();
|
||||
prop.set_f32(Role::App, 0, 0.).unwrap();
|
||||
prop.set_f32(Role::App, 1, 1.).unwrap();
|
||||
prop.set_f32(Role::App, 2, 0.94).unwrap();
|
||||
prop.set_f32(Role::App, 3, 1.).unwrap();
|
||||
node.set_property_u32(Role::App, "z_index", 1).unwrap();
|
||||
|
||||
let node = node
|
||||
.setup(|me| {
|
||||
Text::new(
|
||||
me,
|
||||
window_scale.clone(),
|
||||
app.render_api.clone(),
|
||||
app.text_shaper.clone(),
|
||||
app.ex.clone(),
|
||||
)
|
||||
})
|
||||
.await;
|
||||
popup_layer_node.clone().link(node);
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ pub struct ChatEdit {
|
||||
max_height: PropertyFloat32,
|
||||
rect: PropertyRect,
|
||||
baseline: PropertyFloat32,
|
||||
descent: PropertyFloat32,
|
||||
scroll: PropertyFloat32,
|
||||
scroll_speed: PropertyFloat32,
|
||||
cursor_pos: PropertyUint32,
|
||||
@@ -201,6 +202,7 @@ impl ChatEdit {
|
||||
let max_height = PropertyFloat32::wrap(node_ref, Role::Internal, "max_height", 0).unwrap();
|
||||
let rect = PropertyRect::wrap(node_ref, Role::Internal, "rect").unwrap();
|
||||
let baseline = PropertyFloat32::wrap(node_ref, Role::Internal, "baseline", 0).unwrap();
|
||||
let descent = PropertyFloat32::wrap(node_ref, Role::Internal, "descent", 0).unwrap();
|
||||
let scroll = PropertyFloat32::wrap(node_ref, Role::Internal, "scroll", 0).unwrap();
|
||||
let scroll_speed =
|
||||
PropertyFloat32::wrap(node_ref, Role::Internal, "scroll_speed", 0).unwrap();
|
||||
@@ -252,6 +254,7 @@ impl ChatEdit {
|
||||
max_height,
|
||||
rect,
|
||||
baseline: baseline.clone(),
|
||||
descent,
|
||||
scroll: scroll.clone(),
|
||||
scroll_speed,
|
||||
cursor_pos,
|
||||
@@ -326,8 +329,7 @@ impl ChatEdit {
|
||||
|
||||
let total_height = wrapped_lines_len as f32 * baseline;
|
||||
//let height = std::cmp::min(total_height, self.max_height.get());
|
||||
let height = total_height;
|
||||
debug!("height = {height}");
|
||||
let height = total_height + self.descent.get();
|
||||
|
||||
self.rect.prop().set_f32(Role::Internal, 3, height);
|
||||
|
||||
@@ -341,7 +343,6 @@ impl ChatEdit {
|
||||
("rect_h".to_string(), height),
|
||||
],
|
||||
);
|
||||
debug!("rect = {:?}", self.rect.get());
|
||||
|
||||
let mut clip = self.rect.get();
|
||||
clip.x = 0.;
|
||||
@@ -416,43 +417,60 @@ impl ChatEdit {
|
||||
mesh.alloc(&self.render_api).draw_untextured()
|
||||
}
|
||||
|
||||
fn cursor_px_offset(&self) -> f32 {
|
||||
fn get_cursor_pos(&self) -> Point {
|
||||
assert!(self.is_focused.get());
|
||||
|
||||
let (cursor_pos, glyphs) = {
|
||||
let editable = self.editable.lock().unwrap();
|
||||
let rendered = editable.render();
|
||||
let cursor_pos = editable.get_cursor_pos(&rendered);
|
||||
(cursor_pos, rendered.glyphs)
|
||||
};
|
||||
|
||||
let font_size = self.font_size.get();
|
||||
let window_scale = self.window_scale.get();
|
||||
let baseline = self.baseline.get();
|
||||
let scroll = self.scroll.get();
|
||||
// Add composer glyphs too
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, window_scale, &glyphs, baseline);
|
||||
|
||||
let width = self.rect.prop().get_f32(2).unwrap();
|
||||
|
||||
let (cursor_pos, wrap_glyphs) = {
|
||||
let editable = self.editable.lock().unwrap();
|
||||
let rendered = editable.render();
|
||||
let cursor_pos = editable.get_cursor_pos(&rendered);
|
||||
let glyphs = text::wrap(width, font_size, window_scale, &rendered.glyphs);
|
||||
(cursor_pos, glyphs)
|
||||
};
|
||||
|
||||
// Convert cursor glyph pos to a coord (x, y)
|
||||
let mut glyph_idx = 0;
|
||||
// Used for drawing the cursor when it's at the end of the line.
|
||||
let mut rhs = 0.;
|
||||
let mut y_pos = 0.;
|
||||
|
||||
if cursor_pos == 0 {
|
||||
return 0.;
|
||||
return Point::zero();
|
||||
}
|
||||
|
||||
for (glyph_idx, (mut glyph_rect, glyph)) in glyph_pos_iter.zip(glyphs.iter()).enumerate() {
|
||||
glyph_rect.x -= scroll;
|
||||
for (line_idx, glyphs) in wrap_glyphs.iter().enumerate() {
|
||||
debug!("glyph_idx = {glyph_idx}, y_pos = {y_pos}, rhs = {rhs}");
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, window_scale, glyphs, baseline);
|
||||
|
||||
if cursor_pos == glyph_idx {
|
||||
return glyph_rect.x;
|
||||
if line_idx > 0 {
|
||||
// +1 for the EOL whitespace
|
||||
glyph_idx += 1;
|
||||
y_pos += baseline;
|
||||
}
|
||||
|
||||
rhs = glyph_rect.rhs();
|
||||
for (mut glyph_rect, glyph) in glyph_pos_iter.zip(glyphs.iter()) {
|
||||
if cursor_pos == glyph_idx {
|
||||
let rhs = glyph_rect.rhs();
|
||||
debug!("retvrn {rhs}, {y_pos}");
|
||||
return Point::new(rhs, y_pos)
|
||||
}
|
||||
|
||||
rhs = glyph_rect.rhs();
|
||||
|
||||
glyph_idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
assert!(cursor_pos == glyphs.len());
|
||||
|
||||
rhs += eol_nudge(font_size, &glyphs);
|
||||
rhs
|
||||
if !wrap_glyphs.is_empty() {
|
||||
rhs += eol_nudge(font_size, &wrap_glyphs.last().unwrap());
|
||||
}
|
||||
Point::new(rhs, y_pos)
|
||||
}
|
||||
|
||||
fn mark_selected_glyphs(&self, glyphs: &Vec<Glyph>, selections: Vec<Selection>) -> Vec<bool> {
|
||||
@@ -1209,11 +1227,7 @@ impl ChatEdit {
|
||||
|
||||
let rect_w = self.rect.get().w;
|
||||
|
||||
let mut cursor_pos = Point::zero();
|
||||
cursor_pos.x += self.cursor_px_offset();
|
||||
if cursor_pos.x > rect_w {
|
||||
return vec![]
|
||||
}
|
||||
let cursor_pos = self.get_cursor_pos();
|
||||
cursor_instrs.push(GfxDrawInstruction::Move(cursor_pos));
|
||||
|
||||
let cursor_mesh = {
|
||||
@@ -1439,10 +1453,23 @@ impl UIObject for ChatEdit {
|
||||
let window_scale = self.window_scale.get();
|
||||
let baseline = self.baseline.get();
|
||||
|
||||
// Convert y offset within rect to an x off based off line wrapping
|
||||
let y_off = mouse_pos.y - rect.y;
|
||||
let mut x_off = 0.;
|
||||
|
||||
let width = self.rect.prop().get_f32(2).unwrap();
|
||||
let rendered = self.editable.lock().unwrap().render();
|
||||
let wrapped_glyphs = text::wrap(width, font_size, window_scale, &rendered.glyphs);
|
||||
for glyphs in wrapped_glyphs {
|
||||
let glyph_pos_iter = GlyphPositionIter::new(font_size, window_scale, &glyphs, baseline);
|
||||
let last_rect = glyph_pos_iter.last().unwrap();
|
||||
x_off += last_rect.rhs();
|
||||
}
|
||||
|
||||
{
|
||||
let mut editable = self.editable.lock().unwrap();
|
||||
let rendered = editable.render();
|
||||
let x = mouse_pos.x - rect.x + self.scroll.get();
|
||||
let x = x_off + mouse_pos.x - rect.x + self.scroll.get();
|
||||
|
||||
let cpos = rendered.x_to_pos(x, font_size, window_scale, baseline);
|
||||
let cidx = rendered.pos_to_idx(cpos);
|
||||
|
||||
@@ -106,7 +106,6 @@ impl VectorArt {
|
||||
|
||||
//debug!(target: "ui::vector_art", "=> {verts:#?}");
|
||||
let vertex_buffer = self.render_api.new_vertex_buffer(verts);
|
||||
// You are one lazy motherfucker
|
||||
let index_buffer = self.render_api.new_index_buffer(self.shape.indices.clone());
|
||||
let mesh = GfxDrawMesh {
|
||||
vertex_buffer,
|
||||
|
||||
Reference in New Issue
Block a user