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
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::{
    component::{
        containers::paper::{paper, PaperProps},
        text_paper::{text_paper, TextPaperProps},
    },
    theme::ThemedWidgetProps,
};
use raui_core::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TextFieldPaperProps {
    #[serde(default)]
    pub hint: String,
    #[serde(default)]
    pub width: TextBoxSizeValue,
    #[serde(default)]
    pub height: TextBoxSizeValue,
    #[serde(default)]
    pub variant: String,
    #[serde(default)]
    pub use_main_color: bool,
    #[serde(default)]
    pub transform: Transform,
    #[serde(default)]
    pub paper_theme: ThemedWidgetProps,
    #[serde(default = "TextFieldPaperProps::default_padding")]
    pub padding: Rect,
}
implement_props_data!(TextFieldPaperProps, "TextFieldPaperProps");

impl TextFieldPaperProps {
    fn default_padding() -> Rect {
        Rect {
            left: 4.0,
            right: 4.0,
            top: 4.0,
            bottom: 4.0,
        }
    }
}

impl Default for TextFieldPaperProps {
    fn default() -> Self {
        Self {
            hint: Default::default(),
            width: Default::default(),
            height: Default::default(),
            variant: Default::default(),
            use_main_color: Default::default(),
            transform: Default::default(),
            paper_theme: Default::default(),
            padding: Self::default_padding(),
        }
    }
}

widget_component! {
    text_field_content(key, props) {
        let ButtonProps { selected, .. } = props.read_cloned_or_default();
        let TextFieldPaperProps {
            hint,
            width,
            height,
            variant,
            use_main_color,
            transform,
            paper_theme,
            padding,
        } = props.read_cloned_or_default();
        let InputFieldProps { text, cursor_position, .. } = props.read_cloned_or_default();
        let text = text.trim();
        let text = if text.is_empty() {
            hint
        } else if selected {
            if cursor_position < text.len() {
                format!("{}|{}", &text[..cursor_position], &text[cursor_position..])
            } else {
                format!("{}|", text)
            }
        } else {
            text.to_owned()
        };
        let paper_variant = props.map_or_default::<PaperProps, _, _>(|p| p.variant.clone());
        let paper_props = props.clone().with(PaperProps {
            variant: paper_variant,
            ..Default::default()
        }).with(paper_theme);
        let props = props.clone().with(TextPaperProps {
            text,
            width,
            height,
            variant,
            use_main_color,
            transform,
        }).with(ContentBoxItemLayout {
            margin: padding,
            ..Default::default()
        });

        widget! {
            (#{key} paper: {paper_props} [
                (#{key} text_paper: {props})
            ])
        }
    }
}

widget_component! {
    pub text_field_paper(key, props) {
        widget! {
            (#{key} input_field: {props.clone()} {
                content = (#{"text"} text_field_content: {props.clone()})
            })
        }
    }
}