Skip to main content

base_ui/widget/widgets/
text_view.rs

1use crate::animation::animation::{ Animation, Vec2Animation, FadeAnimation };
2use crate::style::color::Color;
3use crate::widget::Widget;
4use crate::graphics::Renderer;
5use log::{ debug, info };
6use std::sync::Arc;
7use std::cell::RefCell;
8
9pub struct TextView {
10    x: f32,
11    y: f32,
12    width: f32,
13    height: f32,
14    text: String,
15    font_size: f32,
16    background_color: Color,
17    text_color: Color,
18    is_hovered: bool,
19    hover_background_color: Color,
20    hover_text_color: Color,
21    on_hover: Option<Arc<RefCell<dyn FnMut(bool) + 'static>>>,
22    is_pressed: bool,
23    on_click: Option<Arc<RefCell<dyn FnMut() + 'static>>>,
24    position_animation: Option<Vec2Animation>,
25    fade_animation: Option<FadeAnimation>,
26    opacity: f32,
27}
28
29impl TextView {
30    pub fn new(text: &str, renderer: &Renderer) -> Self {
31        debug!("Creating new TextView with text: '{}'", text);
32        let background_color = Color::new(1.0, 1.0, 1.0, 0.5);
33        let text_color = Color::new(0.0, 0.0, 0.0, 1.0);
34
35        let mut tv = Self {
36            x: 0.0,
37            y: 0.0,
38            width: 0.0,
39            height: 0.0,
40            text: text.to_string(),
41            font_size: 32.0,
42            background_color,
43            text_color,
44            is_hovered: false,
45            hover_background_color: Color::new(0.9, 0.9, 0.9, 0.7),
46            hover_text_color: Color::new(0.0, 0.0, 0.0, 1.0),
47            on_hover: None,
48            is_pressed: false,
49            on_click: None,
50            position_animation: None,
51            fade_animation: None,
52            opacity: 1.0,
53        };
54        tv.update_size(renderer);
55        info!("TextView created with size: {}x{}", tv.width, tv.height);
56        tv
57    }
58
59    pub fn with_style(
60        text: String,
61        font_size: f32,
62        background_color: Color,
63        text_color: Color,
64        hover_background_color: Color,
65        hover_text_color: Color,
66        renderer: &Renderer
67    ) -> Self {
68        let mut tv = Self {
69            x: 0.0,
70            y: 0.0,
71            width: 0.0,
72            height: 0.0,
73            text,
74            font_size,
75            background_color,
76            text_color,
77            hover_background_color,
78            hover_text_color,
79            is_hovered: false,
80            opacity: 1.0,
81            on_hover: None,
82            is_pressed: false,
83            on_click: None,
84            position_animation: None,
85            fade_animation: None,
86        };
87        tv.update_size(renderer);
88        tv
89    }
90
91    fn update_size(&mut self, renderer: &Renderer) {
92        let (width, height) = renderer
93            .text_renderer()
94            .font_renderer()
95            .calculate_text_size(&self.text, self.font_size);
96        self.width = width + 20.0; // 여백 추가
97        self.height = height + 10.0;
98        debug!("TextView size updated: {}x{}", self.width, self.height);
99    }
100
101    pub fn set_text(&mut self, text: &str, renderer: &Renderer) {
102        debug!("TextView text changing from '{}' to '{}'", self.text, text);
103        self.text = text.to_string();
104        self.update_size(renderer);
105    }
106
107    pub fn set_font_size(&mut self, size: f32, renderer: &Renderer) {
108        debug!("TextView font size changing from {} to {}", self.font_size, size);
109        self.font_size = size;
110        self.update_size(renderer);
111    }
112
113    pub fn set_background_color(&mut self, color: Color) {
114        self.background_color = color;
115    }
116
117    pub fn set_text_color(&mut self, color: Color) {
118        self.text_color = color;
119    }
120
121    pub fn set_position(&mut self, x: f32, y: f32) {
122        self.x = x;
123        self.y = y;
124    }
125
126    pub fn set_hover_background_color(&mut self, color: Color) {
127        self.hover_background_color = color;
128    }
129
130    pub fn set_hover_text_color(&mut self, color: Color) {
131        self.hover_text_color = color;
132    }
133
134    pub fn update_hover(&mut self, x: f32, y: f32) {
135        let was_hovered = self.is_hovered;
136        self.is_hovered = self.contains_point(x, y);
137
138        if was_hovered != self.is_hovered {
139            if let Some(callback) = &self.on_hover {
140                callback.borrow_mut()(self.is_hovered);
141            }
142        }
143    }
144
145    pub fn has_fade_animation(&self) -> bool {
146        self.fade_animation.is_some()
147    }
148
149    pub fn has_position_animation(&self) -> bool {
150        self.position_animation.is_some()
151    }
152}
153
154impl Widget for TextView {
155    fn get_position(&self) -> (f32, f32) {
156        (self.x, self.y)
157    }
158
159    fn get_size(&self) -> (f32, f32) {
160        (self.width, self.height)
161    }
162
163    fn get_background_color(&self) -> Color {
164        self.background_color
165    }
166
167    fn get_text_color(&self) -> Color {
168        self.text_color
169    }
170
171    fn get_hover_background_color(&self) -> Color {
172        self.hover_background_color
173    }
174
175    fn get_hover_text_color(&self) -> Color {
176        self.hover_text_color
177    }
178
179    fn get_opacity(&self) -> f32 {
180        self.opacity
181    }
182
183    fn get_is_hovered(&self) -> bool {
184        self.is_hovered
185    }
186
187    fn get_is_pressed(&self) -> bool {
188        self.is_pressed
189    }
190
191    fn draw(&self, renderer: &mut Renderer, screen_width: f32, screen_height: f32) {
192        let current_background =
193            (if self.is_hovered { self.hover_background_color } else { self.background_color }) *
194            self.opacity;
195
196        let current_text =
197            (if self.is_hovered { self.hover_text_color } else { self.text_color }) * self.opacity;
198
199        renderer.draw_rect(self.x, self.y, self.width, self.height, current_background.to_array());
200
201        renderer
202            .text_renderer_mut()
203            .render_text(
204                &self.text,
205                self.x + 10.0,
206                self.y + 5.0,
207                self.font_size,
208                screen_width,
209                screen_height,
210                current_text.to_array()
211            );
212    }
213
214    fn set_size(&mut self, width: f32, height: f32) {
215        self.width = width;
216        self.height = height;
217    }
218
219    fn position(&self) -> (f32, f32) {
220        (self.x, self.y)
221    }
222
223    fn size(&self) -> (f32, f32) {
224        (self.width, self.height)
225    }
226
227    fn set_position(&mut self, x: f32, y: f32) {
228        self.x = x;
229        self.y = y;
230    }
231
232    fn on_mouse_press(&mut self, x: f32, y: f32) -> bool {
233        if self.contains_point(x, y) {
234            self.is_pressed = true;
235            true
236        } else {
237            false
238        }
239    }
240
241    fn on_mouse_release(&mut self, x: f32, y: f32) -> bool {
242        if self.is_pressed {
243            self.is_pressed = false;
244            if self.contains_point(x, y) {
245                if let Some(callback) = &self.on_click {
246                    callback.borrow_mut()();
247                }
248                return true;
249            }
250        }
251        false
252    }
253
254    fn set_on_click<F>(&mut self, callback: F) where F: FnMut() + 'static {
255        self.on_click = Some(Arc::new(RefCell::new(callback)));
256    }
257
258    fn set_on_hover<F>(&mut self, callback: F) where F: FnMut(bool) + 'static {
259        self.on_hover = Some(Arc::new(RefCell::new(callback)));
260    }
261
262    fn set_position_animation(&mut self, animation: Vec2Animation) {
263        self.position_animation = Some(animation);
264    }
265
266    fn animate_fade(&mut self, start: f32, end: f32, duration: f32) {
267        self.set_fade_animation(FadeAnimation::new(start, end, duration));
268    }
269
270    fn set_fade_animation(&mut self, animation: FadeAnimation) {
271        self.fade_animation = Some(animation);
272    }
273
274    fn update_animations(&mut self, delta_time: f32) {
275        if let Some(ref mut anim) = self.position_animation {
276            anim.update(delta_time);
277            let pos = anim.value();
278            self.x = pos.x;
279            self.y = pos.y;
280
281            if anim.is_finished() {
282                self.position_animation = None;
283            }
284        }
285
286        if let Some(ref mut anim) = self.fade_animation {
287            anim.update(delta_time);
288            self.opacity = anim.value();
289
290            if anim.is_finished() {
291                self.fade_animation = None;
292            }
293        }
294    }
295}