1use crate::event::TextEvents;
5use crate::event::{Event, EventType, WxEvtHandler};
6use crate::geometry::{Point, Size};
7use crate::id::Id;
8use crate::window::{WindowHandle, WxWidget};
9#[allow(unused_imports)]
11use crate::window::Window;
12use std::ffi::CString;
13use std::os::raw::c_char;
14use std::ptr::null_mut;
15use wxdragon_sys as ffi;
16
17widget_style_enum!(
19 name: TextCtrlStyle,
20 doc: "Style flags for TextCtrl widget.",
21 variants: {
22 Default: 0, "Default style (single line, editable, left-aligned).",
23 MultiLine: ffi::WXD_TE_MULTILINE, "Multi-line text control.",
24 Password: ffi::WXD_TE_PASSWORD, "Password entry control (displays characters as asterisks).",
25 ReadOnly: ffi::WXD_TE_READONLY, "Read-only text control.",
26 Rich: ffi::WXD_TE_RICH, "For rich text content (implies multiline). Use with care, may require specific handling.",
27 Rich2: ffi::WXD_TE_RICH2, "For more advanced rich text content (implies multiline). Use with care.",
28 AutoUrl: ffi::WXD_TE_AUTO_URL, "Automatically detect and make URLs clickable.",
29 ProcessEnter: ffi::WXD_TE_PROCESS_ENTER, "Generate an event when Enter key is pressed.",
30 ProcessTab: ffi::WXD_TE_PROCESS_TAB, "Process TAB key in the control instead of using it for navigation.",
31 NoHideSel: ffi::WXD_TE_NOHIDESEL, "Always show selection, even when control doesn't have focus (Windows only).",
32 Centre: ffi::WXD_TE_CENTRE, "Center-align text.",
33 Right: ffi::WXD_TE_RIGHT, "Right-align text.",
34 CharWrap: ffi::WXD_TE_CHARWRAP, "Wrap at any position, splitting words if necessary.",
35 WordWrap: ffi::WXD_TE_WORDWRAP, "Wrap at word boundaries.",
36 NoVScroll: ffi::WXD_TE_NO_VSCROLL, "No vertical scrollbar (multiline only).",
37 DontWrap: ffi::WXD_TE_DONTWRAP, "Don't wrap at all, show horizontal scrollbar instead."
38 },
39 default_variant: Default
40);
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum TextCtrlEvent {
45 TextChanged,
47 TextEnter,
49}
50
51#[derive(Debug)]
53pub struct TextCtrlEventData {
54 event: Event,
55}
56
57impl TextCtrlEventData {
58 pub fn new(event: Event) -> Self {
60 Self { event }
61 }
62
63 pub fn get_id(&self) -> i32 {
65 self.event.get_id()
66 }
67
68 pub fn skip(&self, skip: bool) {
70 self.event.skip(skip);
71 }
72
73 pub fn get_string(&self) -> Option<String> {
75 self.event.get_string()
76 }
77}
78
79#[derive(Clone, Copy)]
102pub struct TextCtrl {
103 handle: WindowHandle,
105}
106
107impl TextCtrl {
108 pub fn builder(parent: &dyn WxWidget) -> TextCtrlBuilder<'_> {
110 TextCtrlBuilder::new(parent)
111 }
112
113 pub(crate) unsafe fn from_ptr(ptr: *mut ffi::wxd_TextCtrl_t) -> Self {
117 TextCtrl {
118 handle: WindowHandle::new(ptr as *mut ffi::wxd_Window_t),
119 }
120 }
121
122 #[allow(dead_code)]
126 pub(crate) fn new_from_composition(_window: Window, _parent_ptr: *mut ffi::wxd_Window_t) -> Self {
127 Self {
129 handle: WindowHandle::new(_window.as_ptr()),
130 }
131 }
132
133 fn new_impl(parent_ptr: *mut ffi::wxd_Window_t, id: Id, value: &str, pos: Point, size: Size, style: i64) -> Self {
135 let c_value = CString::new(value).unwrap_or_default();
136
137 let ptr = unsafe {
138 ffi::wxd_TextCtrl_Create(
139 parent_ptr,
140 id,
141 c_value.as_ptr(),
142 pos.into(),
143 size.into(),
144 style as ffi::wxd_Style_t,
145 )
146 };
147
148 if ptr.is_null() {
149 panic!("Failed to create TextCtrl widget");
150 }
151
152 unsafe { TextCtrl::from_ptr(ptr) }
153 }
154
155 #[inline]
157 fn textctrl_ptr(&self) -> *mut ffi::wxd_TextCtrl_t {
158 self.handle
159 .get_ptr()
160 .map(|p| p as *mut ffi::wxd_TextCtrl_t)
161 .unwrap_or(null_mut())
162 }
163
164 fn read_string_with_retry(mut getter: impl FnMut(*mut c_char, i32) -> i32) -> String {
165 let mut buffer: Vec<c_char> = vec![0; 1024];
166 let mut len = getter(buffer.as_mut_ptr(), buffer.len() as i32);
167 if len < 0 {
168 return String::new();
169 }
170 if len as usize >= buffer.len() {
171 buffer = vec![0; len as usize + 1];
172 len = getter(buffer.as_mut_ptr(), buffer.len() as i32);
173 if len < 0 {
174 return String::new();
175 }
176 }
177 let byte_slice = unsafe { std::slice::from_raw_parts(buffer.as_ptr() as *const u8, len as usize) };
178 String::from_utf8_lossy(byte_slice).to_string()
179 }
180
181 pub fn set_value(&self, value: &str) {
184 let ptr = self.textctrl_ptr();
185 if ptr.is_null() {
186 return;
187 }
188 let c_value = CString::new(value).unwrap_or_default();
189 unsafe { ffi::wxd_TextCtrl_SetValue(ptr, c_value.as_ptr()) };
190 }
191
192 pub fn get_value(&self) -> String {
195 let ptr = self.textctrl_ptr();
196 if ptr.is_null() {
197 return String::new();
198 }
199 unsafe { Self::read_string_with_retry(|buf, len| ffi::wxd_TextCtrl_GetValue(ptr, buf, len)) }
200 }
201
202 pub fn append_text(&self, text: &str) {
205 let ptr = self.textctrl_ptr();
206 if ptr.is_null() {
207 return;
208 }
209 let c_text = CString::new(text).unwrap_or_default();
210 unsafe { ffi::wxd_TextCtrl_AppendText(ptr, c_text.as_ptr()) };
211 }
212
213 pub fn clear(&self) {
216 let ptr = self.textctrl_ptr();
217 if ptr.is_null() {
218 return;
219 }
220 unsafe {
221 ffi::wxd_TextCtrl_Clear(ptr);
222 }
223 }
224
225 pub fn write_text(&self, text: &str) {
228 let ptr = self.textctrl_ptr();
229 if ptr.is_null() {
230 return;
231 }
232 let c_text = CString::new(text).unwrap_or_default();
233 unsafe { ffi::wxd_TextCtrl_WriteText(ptr, c_text.as_ptr()) };
234 }
235
236 pub fn change_value(&self, value: &str) {
239 let ptr = self.textctrl_ptr();
240 if ptr.is_null() {
241 return;
242 }
243 let c_value = CString::new(value).unwrap_or_default();
244 unsafe { ffi::wxd_TextCtrl_ChangeValue(ptr, c_value.as_ptr()) };
245 }
246
247 pub fn remove(&self, from: i64, to: i64) {
250 let ptr = self.textctrl_ptr();
251 if ptr.is_null() {
252 return;
253 }
254 unsafe { ffi::wxd_TextCtrl_Remove(ptr, from, to) };
255 }
256
257 pub fn replace(&self, from: i64, to: i64, value: &str) {
260 let ptr = self.textctrl_ptr();
261 if ptr.is_null() {
262 return;
263 }
264 let c_value = CString::new(value).unwrap_or_default();
265 unsafe { ffi::wxd_TextCtrl_Replace(ptr, from, to, c_value.as_ptr()) };
266 }
267
268 pub fn position_to_xy(&self, pos: i64) -> Option<(i64, i64)> {
271 let ptr = self.textctrl_ptr();
272 if ptr.is_null() {
273 return None;
274 }
275 let mut x: i64 = 0;
276 let mut y: i64 = 0;
277 let result = unsafe { ffi::wxd_TextCtrl_PositionToXY(ptr, pos, &mut x, &mut y) };
278 if result { Some((x, y)) } else { None }
279 }
280
281 pub fn xy_to_position(&self, x: i64, y: i64) -> i64 {
284 let ptr = self.textctrl_ptr();
285 if ptr.is_null() {
286 return 0;
287 }
288 unsafe { ffi::wxd_TextCtrl_XYToPosition(ptr, x, y) }
289 }
290
291 pub fn get_number_of_lines(&self) -> i32 {
294 let ptr = self.textctrl_ptr();
295 if ptr.is_null() {
296 return 0;
297 }
298 unsafe { ffi::wxd_TextCtrl_GetNumberOfLines(ptr) }
299 }
300
301 pub fn get_line_length(&self, line_no: i64) -> i32 {
304 let ptr = self.textctrl_ptr();
305 if ptr.is_null() {
306 return 0;
307 }
308 unsafe { ffi::wxd_TextCtrl_GetLineLength(ptr, line_no) }
309 }
310
311 pub fn get_line_text(&self, line_no: i64) -> String {
314 let ptr = self.textctrl_ptr();
315 if ptr.is_null() {
316 return String::new();
317 }
318 unsafe { Self::read_string_with_retry(|buf, len| ffi::wxd_TextCtrl_GetLineText(ptr, line_no, buf, len)) }
319 }
320
321 pub fn is_modified(&self) -> bool {
325 let ptr = self.textctrl_ptr();
326 if ptr.is_null() {
327 return false;
328 }
329 unsafe { ffi::wxd_TextCtrl_IsModified(ptr) }
330 }
331
332 pub fn set_modified(&self, modified: bool) {
335 let ptr = self.textctrl_ptr();
336 if ptr.is_null() {
337 return;
338 }
339 unsafe { ffi::wxd_TextCtrl_SetModified(ptr, modified) };
340 }
341
342 pub fn set_editable(&self, editable: bool) {
345 let ptr = self.textctrl_ptr();
346 if ptr.is_null() {
347 return;
348 }
349 unsafe { ffi::wxd_TextCtrl_SetEditable(ptr, editable) };
350 }
351
352 pub fn is_editable(&self) -> bool {
355 let ptr = self.textctrl_ptr();
356 if ptr.is_null() {
357 return false;
358 }
359 unsafe { ffi::wxd_TextCtrl_IsEditable(ptr) }
360 }
361
362 pub fn get_insertion_point(&self) -> i64 {
366 let ptr = self.textctrl_ptr();
367 if ptr.is_null() {
368 return 0;
369 }
370 unsafe { ffi::wxd_TextCtrl_GetInsertionPoint(ptr) }
371 }
372
373 pub fn set_insertion_point(&self, pos: i64) {
376 let ptr = self.textctrl_ptr();
377 if ptr.is_null() {
378 return;
379 }
380 unsafe { ffi::wxd_TextCtrl_SetInsertionPoint(ptr, pos) };
381 }
382
383 pub fn set_max_length(&self, len: usize) {
388 let ptr = self.textctrl_ptr();
389 if ptr.is_null() {
390 return;
391 }
392 unsafe { ffi::wxd_TextCtrl_SetMaxLength(ptr, len as i64) };
393 }
394
395 pub fn get_last_position(&self) -> i64 {
398 let ptr = self.textctrl_ptr();
399 if ptr.is_null() {
400 return 0;
401 }
402 unsafe { ffi::wxd_TextCtrl_GetLastPosition(ptr) }
403 }
404
405 pub fn is_multiline(&self) -> bool {
408 let ptr = self.textctrl_ptr();
409 if ptr.is_null() {
410 return false;
411 }
412 unsafe { ffi::wxd_TextCtrl_IsMultiLine(ptr) }
413 }
414
415 pub fn is_single_line(&self) -> bool {
418 let ptr = self.textctrl_ptr();
419 if ptr.is_null() {
420 return false;
421 }
422 unsafe { ffi::wxd_TextCtrl_IsSingleLine(ptr) }
423 }
424
425 pub fn set_selection(&self, from: i64, to: i64) {
435 let ptr = self.textctrl_ptr();
436 if ptr.is_null() {
437 return;
438 }
439 unsafe { ffi::wxd_TextCtrl_SetSelection(ptr, from, to) };
440 }
441
442 pub fn get_selection(&self) -> (i64, i64) {
448 let ptr = self.textctrl_ptr();
449 if ptr.is_null() {
450 return (0, 0);
451 }
452 let mut from = 0i64;
453 let mut to = 0i64;
454 unsafe { ffi::wxd_TextCtrl_GetSelection(ptr, &mut from, &mut to) };
455 (from, to)
456 }
457
458 pub fn select_all(&self) {
461 let ptr = self.textctrl_ptr();
462 if ptr.is_null() {
463 return;
464 }
465 unsafe { ffi::wxd_TextCtrl_SelectAll(ptr) };
466 }
467
468 pub fn get_string_selection(&self) -> String {
472 let ptr = self.textctrl_ptr();
473 if ptr.is_null() {
474 return String::new();
475 }
476 unsafe { Self::read_string_with_retry(|buf, len| ffi::wxd_TextCtrl_GetStringSelection(ptr, buf, len)) }
477 }
478
479 pub fn set_insertion_point_end(&self) {
482 let ptr = self.textctrl_ptr();
483 if ptr.is_null() {
484 return;
485 }
486 unsafe { ffi::wxd_TextCtrl_SetInsertionPointEnd(ptr) };
487 }
488
489 pub fn set_style(&self, start: i64, end: i64, style: &TextAttr) {
492 let ptr = self.textctrl_ptr();
493 if ptr.is_null() {
494 return;
495 }
496 unsafe { ffi::wxd_TextCtrl_SetStyle(ptr, start, end, style.as_ptr()) };
497 }
498
499 pub fn get_default_style(&self) -> Option<TextAttr> {
502 let ptr = self.textctrl_ptr();
503 if ptr.is_null() {
504 return None;
505 }
506 let attr_ptr = unsafe { ffi::wxd_TextCtrl_GetDefaultStyle(ptr) };
507 if attr_ptr.is_null() {
508 return None;
509 }
510 Some(TextAttr { ptr: attr_ptr })
511 }
512
513 pub fn set_default_style(&self, style: &TextAttr) {
516 let ptr = self.textctrl_ptr();
517 if ptr.is_null() {
518 return;
519 }
520 unsafe { ffi::wxd_TextCtrl_SetDefaultStyle(ptr, style.as_ptr()) };
521 }
522
523 pub fn window_handle(&self) -> WindowHandle {
525 self.handle
526 }
527}
528
529pub struct TextAttr {
531 ptr: *mut ffi::wxd_TextAttr_t,
532}
533
534impl Default for TextAttr {
535 fn default() -> Self {
536 Self::new()
537 }
538}
539
540impl TextAttr {
541 pub fn new() -> Self {
543 Self {
544 ptr: unsafe { ffi::wxd_TextAttr_Create() },
545 }
546 }
547
548 pub fn set_text_colour(&mut self, color: crate::color::Colour) {
550 unsafe { ffi::wxd_TextAttr_SetTextColour(self.ptr, color.to_raw()) };
551 }
552
553 pub fn set_background_colour(&mut self, color: crate::color::Colour) {
555 unsafe { ffi::wxd_TextAttr_SetBackgroundColour(self.ptr, color.to_raw()) };
556 }
557
558 pub fn set_font(&mut self, font: &crate::font::Font) {
560 unsafe { ffi::wxd_TextAttr_SetFont(self.ptr, font.as_ptr()) };
561 }
562
563 pub fn set_alignment(&mut self, alignment: i32) {
565 unsafe { ffi::wxd_TextAttr_SetAlignment(self.ptr, alignment) };
566 }
567
568 pub fn set_left_indent(&mut self, indent: i32, sub_indent: i32) {
570 unsafe { ffi::wxd_TextAttr_SetLeftIndent(self.ptr, indent, sub_indent) };
571 }
572
573 pub fn set_right_indent(&mut self, indent: i32) {
575 unsafe { ffi::wxd_TextAttr_SetRightIndent(self.ptr, indent) };
576 }
577
578 pub fn set_line_spacing(&mut self, spacing: i32) {
580 unsafe { ffi::wxd_TextAttr_SetLineSpacing(self.ptr, spacing) };
581 }
582
583 pub fn set_paragraph_spacing_after(&mut self, spacing: i32) {
585 unsafe { ffi::wxd_TextAttr_SetParagraphSpacingAfter(self.ptr, spacing) };
586 }
587
588 pub fn set_paragraph_spacing_before(&mut self, spacing: i32) {
590 unsafe { ffi::wxd_TextAttr_SetParagraphSpacingBefore(self.ptr, spacing) };
591 }
592
593 pub fn set_bullet_style(&mut self, style: i32) {
595 unsafe { ffi::wxd_TextAttr_SetBulletStyle(self.ptr, style) };
596 }
597
598 pub fn set_flags(&mut self, flags: i64) {
599 unsafe { ffi::wxd_TextAttr_SetFlags(self.ptr, flags) };
600 }
601 pub fn get_flags(&self) -> i64 {
602 unsafe { ffi::wxd_TextAttr_GetFlags(self.ptr) }
603 }
604 pub fn has_flag(&self, flag: i64) -> bool {
605 unsafe { ffi::wxd_TextAttr_HasFlag(self.ptr, flag) }
606 }
607
608 pub fn set_font_size(&mut self, point_size: i32) {
609 unsafe { ffi::wxd_TextAttr_SetFontSize(self.ptr, point_size) };
610 }
611 pub fn get_font_size(&self) -> i32 {
612 unsafe { ffi::wxd_TextAttr_GetFontSize(self.ptr) }
613 }
614
615 pub fn set_font_style(&mut self, font_style: crate::font::FontStyle) {
616 unsafe { ffi::wxd_TextAttr_SetFontStyle(self.ptr, font_style as i32) };
617 }
618 pub fn get_font_style(&self) -> crate::font::FontStyle {
619 unsafe { std::mem::transmute(ffi::wxd_TextAttr_GetFontStyle(self.ptr)) }
620 }
621
622 pub fn set_font_weight(&mut self, font_weight: crate::font::FontWeight) {
623 unsafe { ffi::wxd_TextAttr_SetFontWeight(self.ptr, font_weight as i32) };
624 }
625 pub fn get_font_weight(&self) -> crate::font::FontWeight {
626 unsafe { std::mem::transmute(ffi::wxd_TextAttr_GetFontWeight(self.ptr)) }
627 }
628
629 pub fn set_font_face_name(&mut self, face_name: &str) {
630 let c_str = std::ffi::CString::new(face_name).unwrap();
631 unsafe { ffi::wxd_TextAttr_SetFontFaceName(self.ptr, c_str.as_ptr()) };
632 }
633 pub fn set_font_underlined(&mut self, underlined: bool) {
634 unsafe { ffi::wxd_TextAttr_SetFontUnderlined(self.ptr, underlined) };
635 }
636 pub fn set_font_strikethrough(&mut self, strikethrough: bool) {
637 unsafe { ffi::wxd_TextAttr_SetFontStrikethrough(self.ptr, strikethrough) };
638 }
639 pub fn set_font_encoding(&mut self, encoding: i32) {
640 unsafe { ffi::wxd_TextAttr_SetFontEncoding(self.ptr, encoding) };
641 }
642 pub fn set_font_family(&mut self, family: crate::font::FontFamily) {
643 unsafe { ffi::wxd_TextAttr_SetFontFamily(self.ptr, family as i32) };
644 }
645
646 pub fn set_character_style_name(&mut self, name: &str) {
647 let c_str = std::ffi::CString::new(name).unwrap();
648 unsafe { ffi::wxd_TextAttr_SetCharacterStyleName(self.ptr, c_str.as_ptr()) };
649 }
650 pub fn set_paragraph_style_name(&mut self, name: &str) {
651 let c_str = std::ffi::CString::new(name).unwrap();
652 unsafe { ffi::wxd_TextAttr_SetParagraphStyleName(self.ptr, c_str.as_ptr()) };
653 }
654 pub fn set_list_style_name(&mut self, name: &str) {
655 let c_str = std::ffi::CString::new(name).unwrap();
656 unsafe { ffi::wxd_TextAttr_SetListStyleName(self.ptr, c_str.as_ptr()) };
657 }
658
659 pub fn set_bullet_number(&mut self, n: i32) {
660 unsafe { ffi::wxd_TextAttr_SetBulletNumber(self.ptr, n) };
661 }
662 pub fn set_bullet_text(&mut self, text: &str) {
663 let c_str = std::ffi::CString::new(text).unwrap();
664 unsafe { ffi::wxd_TextAttr_SetBulletText(self.ptr, c_str.as_ptr()) };
665 }
666 pub fn set_bullet_font(&mut self, bullet_font: &str) {
667 let c_str = std::ffi::CString::new(bullet_font).unwrap();
668 unsafe { ffi::wxd_TextAttr_SetBulletFont(self.ptr, c_str.as_ptr()) };
669 }
670 pub fn set_bullet_name(&mut self, name: &str) {
671 let c_str = std::ffi::CString::new(name).unwrap();
672 unsafe { ffi::wxd_TextAttr_SetBulletName(self.ptr, c_str.as_ptr()) };
673 }
674 pub fn set_url(&mut self, url: &str) {
675 let c_str = std::ffi::CString::new(url).unwrap();
676 unsafe { ffi::wxd_TextAttr_SetURL(self.ptr, c_str.as_ptr()) };
677 }
678 pub fn set_page_break(&mut self, page_break: bool) {
679 unsafe { ffi::wxd_TextAttr_SetPageBreak(self.ptr, page_break) };
680 }
681 pub fn set_text_effects(&mut self, effects: i32) {
682 unsafe { ffi::wxd_TextAttr_SetTextEffects(self.ptr, effects) };
683 }
684 pub fn set_text_effect_flags(&mut self, effects: i32) {
685 unsafe { ffi::wxd_TextAttr_SetTextEffectFlags(self.ptr, effects) };
686 }
687 pub fn set_outline_level(&mut self, level: i32) {
688 unsafe { ffi::wxd_TextAttr_SetOutlineLevel(self.ptr, level) };
689 }
690
691 pub fn get_text_colour(&self) -> crate::color::Colour {
692 crate::color::Colour::from(unsafe { ffi::wxd_TextAttr_GetTextColour(self.ptr) })
693 }
694 pub fn get_background_colour(&self) -> crate::color::Colour {
695 crate::color::Colour::from(unsafe { ffi::wxd_TextAttr_GetBackgroundColour(self.ptr) })
696 }
697 pub fn get_alignment(&self) -> i32 {
698 unsafe { ffi::wxd_TextAttr_GetAlignment(self.ptr) }
699 }
700 pub fn get_left_indent(&self) -> i32 {
701 unsafe { ffi::wxd_TextAttr_GetLeftIndent(self.ptr) }
702 }
703 pub fn get_left_sub_indent(&self) -> i32 {
704 unsafe { ffi::wxd_TextAttr_GetLeftSubIndent(self.ptr) }
705 }
706 pub fn get_right_indent(&self) -> i32 {
707 unsafe { ffi::wxd_TextAttr_GetRightIndent(self.ptr) }
708 }
709 pub fn get_line_spacing(&self) -> i32 {
710 unsafe { ffi::wxd_TextAttr_GetLineSpacing(self.ptr) }
711 }
712 pub fn get_paragraph_spacing_after(&self) -> i32 {
713 unsafe { ffi::wxd_TextAttr_GetParagraphSpacingAfter(self.ptr) }
714 }
715 pub fn get_paragraph_spacing_before(&self) -> i32 {
716 unsafe { ffi::wxd_TextAttr_GetParagraphSpacingBefore(self.ptr) }
717 }
718 pub fn get_bullet_style(&self) -> i32 {
719 unsafe { ffi::wxd_TextAttr_GetBulletStyle(self.ptr) }
720 }
721
722 pub(crate) fn as_ptr(&self) -> *mut ffi::wxd_TextAttr_t {
723 self.ptr
724 }
725}
726
727impl Drop for TextAttr {
728 fn drop(&mut self) {
729 if !self.ptr.is_null() {
730 unsafe { ffi::wxd_TextAttr_Delete(self.ptr) };
731 self.ptr = null_mut();
732 }
733 }
734}
735
736impl TextEvents for TextCtrl {}
738
739impl WxWidget for TextCtrl {
741 fn handle_ptr(&self) -> *mut ffi::wxd_Window_t {
742 self.handle.get_ptr().unwrap_or(null_mut())
743 }
744
745 fn is_valid(&self) -> bool {
746 self.handle.is_valid()
747 }
748}
749
750impl WxEvtHandler for TextCtrl {
752 unsafe fn get_event_handler_ptr(&self) -> *mut ffi::wxd_EvtHandler_t {
753 self.handle.get_ptr().unwrap_or(null_mut()) as *mut ffi::wxd_EvtHandler_t
754 }
755}
756
757impl crate::event::WindowEvents for TextCtrl {}
759
760impl crate::scrollable::WxScrollable for TextCtrl {}
762
763widget_builder!(
765 name: TextCtrl,
766 parent_type: &'a dyn WxWidget,
767 style_type: TextCtrlStyle,
768 fields: {
769 value: String = String::new()
770 },
771 build_impl: |slf| {
772 TextCtrl::new_impl(
773 slf.parent.handle_ptr(),
774 slf.id,
775 &slf.value,
776 slf.pos,
777 slf.size,
778 slf.style.bits()
779 )
780 }
781);
782
783crate::implement_widget_local_event_handlers!(
785 TextCtrl,
786 TextCtrlEvent,
787 TextCtrlEventData,
788 TextChanged => text_changed, EventType::TEXT,
789 TextEnter => text_enter, EventType::TEXT_ENTER
790);
791
792#[cfg(feature = "xrc")]
794impl crate::xrc::XrcSupport for TextCtrl {
795 unsafe fn from_xrc_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
796 TextCtrl {
797 handle: WindowHandle::new(ptr),
798 }
799 }
800}
801
802impl crate::window::FromWindowWithClassName for TextCtrl {
804 fn class_name() -> &'static str {
805 "wxTextCtrl"
806 }
807
808 unsafe fn from_ptr(ptr: *mut ffi::wxd_Window_t) -> Self {
809 TextCtrl {
810 handle: WindowHandle::new(ptr),
811 }
812 }
813}