1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use freya_native_core::real_dom::NodeImmutable;

use freya_common::{CachedParagraph, CursorLayoutResponse};
use freya_node_state::{CursorReference, CursorSettings};
use std::ops::Mul;

use torin::prelude::*;

use crate::dom::DioxusNode;

pub fn measure_paragraph(node: &DioxusNode, layout_node: &LayoutNode, scale_factor: f32) {
    let paragraph = &layout_node
        .data
        .as_ref()
        .unwrap()
        .get::<CachedParagraph>()
        .unwrap()
        .0;

    let scale_factors = scale_factor as f64;

    if let Some((cursor_ref, id, cursor_position, cursor_selections)) = get_cursor_reference(node) {
        if let Some(cursor_position) = cursor_position {
            // Calculate the new cursor position
            let char_position = paragraph.get_glyph_position_at_coordinate(
                cursor_position.mul(scale_factors).to_i32().to_tuple(),
            );

            // Notify the cursor reference listener
            cursor_ref
                .cursor_sender
                .send(CursorLayoutResponse::CursorPosition {
                    position: char_position.position as usize,
                    id,
                })
                .ok();
        }

        if let Some((origin, dist)) = cursor_selections {
            // Calculate the start of the highlighting
            let origin_char = paragraph
                .get_glyph_position_at_coordinate(origin.mul(scale_factors).to_i32().to_tuple());
            // Calculate the end of the highlighting
            let dist_char = paragraph
                .get_glyph_position_at_coordinate(dist.mul(scale_factors).to_i32().to_tuple());

            cursor_ref
                .cursor_sender
                .send(CursorLayoutResponse::TextSelection {
                    from: origin_char.position as usize,
                    to: dist_char.position as usize,
                    id,
                })
                .ok();
        }
    }
}

/// Get the info related to a cursor reference
#[allow(clippy::type_complexity)]
fn get_cursor_reference(
    node: &DioxusNode,
) -> Option<(
    CursorReference,
    usize,
    Option<CursorPoint>,
    Option<(CursorPoint, CursorPoint)>,
)> {
    let cursor_settings = node.get::<CursorSettings>().unwrap();

    let cursor_ref = cursor_settings.cursor_ref.clone()?;
    let cursor_id = cursor_settings.cursor_id?;

    let current_cursor_id = { *cursor_ref.cursor_id.lock().unwrap().as_ref()? };
    let cursor_selections = cursor_ref.cursor_selections.lock().unwrap().take();
    let cursor_position = cursor_ref.cursor_position.lock().unwrap().take();

    if current_cursor_id == cursor_id {
        Some((cursor_ref, cursor_id, cursor_position, cursor_selections))
    } else {
        None
    }
}