1use crate::enums::{Color, Font, Key};
2use crate::prelude::*;
3use crate::utils::FlString;
4use fltk_sys::text::*;
5use std::{
6 ffi::{CStr, CString},
7 os::raw,
8};
9
10type BufWrapper = std::rc::Rc<*mut Fl_Text_Buffer>;
11
12#[repr(i32)]
14#[derive(Debug, Copy, Clone, PartialEq, Eq)]
15pub enum Cursor {
16 Normal,
18 Caret,
20 Dim,
22 Block,
24 Heavy,
26 Simple,
28}
29
30#[derive(Debug)]
32pub struct TextBuffer {
33 inner: BufWrapper,
34}
35
36impl std::default::Default for TextBuffer {
37 fn default() -> TextBuffer {
39 unsafe {
40 let text_buffer = Fl_Text_Buffer_new();
41 assert!(!text_buffer.is_null());
42 TextBuffer {
43 inner: BufWrapper::new(text_buffer),
44 }
45 }
46 }
47}
48
49impl TextBuffer {
50 pub unsafe fn delete(buf: Self) {
54 drop(buf);
56 }
57
58 pub unsafe fn delete_buffer(buf: Self) {
62 unsafe { Self::delete(buf) }
63 }
64
65 pub unsafe fn from_ptr(ptr: *mut Fl_Text_Buffer) -> Self {
69 assert!(!ptr.is_null());
70 TextBuffer {
71 inner: BufWrapper::new(ptr),
72 }
73 }
74
75 pub fn as_ptr(&self) -> *mut Fl_Text_Buffer {
79 *self.inner
80 }
81
82 pub fn set_text(&mut self, txt: &str) {
84 unsafe {
85 let txt = CString::safe_new(txt);
86 Fl_Text_Buffer_set_text(*self.inner, txt.as_ptr())
87 }
88 }
89
90 pub fn text(&self) -> String {
92 unsafe {
93 let text = Fl_Text_Buffer_text(*self.inner);
94 assert!(!text.is_null());
95 CStr::from_ptr(text as *mut raw::c_char)
96 .to_string_lossy()
97 .to_string()
98 }
99 }
100
101 pub fn append(&mut self, text: &str) {
119 let text = CString::safe_new(text);
120 unsafe { Fl_Text_Buffer_append(*self.inner, text.as_ptr()) }
121 }
122
123 pub fn append_bytes(&mut self, text: &[u8]) {
125 unsafe { Fl_Text_Buffer_append_bytes(*self.inner, text.as_ptr() as _, text.len() as _) }
126 }
127
128 pub fn length(&self) -> i32 {
130 unsafe { Fl_Text_Buffer_length(*self.inner) }
131 }
132
133 pub fn remove(&mut self, start: i32, end: i32) {
135 unsafe {
136 Fl_Text_Buffer_remove(*self.inner, start, end);
137 }
138 }
139
140 pub fn text_range(&self, start: i32, end: i32) -> Option<String> {
142 unsafe {
143 let x = Fl_Text_Buffer_text_range(*self.inner, start, end);
144 if x.is_null() {
145 None
146 } else {
147 Some(
148 CStr::from_ptr(x as *mut raw::c_char)
149 .to_string_lossy()
150 .to_string(),
151 )
152 }
153 }
154 }
155
156 pub fn insert(&mut self, pos: i32, text: &str) {
158 let text = CString::safe_new(text);
159 unsafe { Fl_Text_Buffer_insert(*self.inner, pos, text.as_ptr()) }
160 }
161
162 pub fn replace(&mut self, start: i32, end: i32, text: &str) {
164 assert!(end >= start);
165 let text = CString::safe_new(text);
166 unsafe { Fl_Text_Buffer_replace(*self.inner, start, end, text.as_ptr()) }
167 }
168
169 pub fn copy_from(&mut self, source_buf: &TextBuffer, start: i32, end: i32, to: i32) {
171 unsafe { Fl_Text_Buffer_copy(*self.inner, *source_buf.inner, start, end, to) }
172 }
173
174 pub fn copy(&self) -> TextBuffer {
176 let mut temp = TextBuffer::default();
177 temp.copy_from(self, 0, 0, self.length());
178 temp
179 }
180
181 pub fn undo(&mut self) -> Result<(), FltkError> {
185 unsafe {
186 match Fl_Text_Buffer_undo(*self.inner, std::ptr::null_mut()) {
187 0 => Err(FltkError::Unknown(String::from("Failed to undo"))),
188 _ => Ok(()),
189 }
190 }
191 }
192
193 pub fn redo(&mut self) -> Result<i32, FltkError> {
198 unsafe {
199 let mut i = 0;
200 match Fl_Text_Buffer_redo(*self.inner, &mut i) {
201 0 => Err(FltkError::Unknown(String::from("Failed to redo"))),
202 _ => Ok(i),
203 }
204 }
205 }
206
207 pub fn can_undo(&mut self, flag: bool) {
209 unsafe { Fl_Text_Buffer_canUndo(*self.inner, flag as raw::c_char) }
210 }
211
212 pub fn get_can_undo(&mut self) -> bool {
214 unsafe { Fl_Text_Buffer_can_undo(*self.inner) != 0 }
215 }
216
217 pub fn can_redo(&mut self) -> bool {
219 unsafe { Fl_Text_Buffer_can_redo(*self.inner) != 0 }
220 }
221
222 pub fn load_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), FltkError> {
226 if !path.as_ref().exists() {
227 return Err(FltkError::Internal(FltkErrorKind::ResourceNotFound));
228 }
229 let path = path
230 .as_ref()
231 .to_str()
232 .ok_or_else(|| FltkError::Unknown(String::from("Failed to convert path to string")))?;
233 let path = CString::new(path)?;
234 unsafe {
235 match Fl_Text_Buffer_load_file(*self.inner, path.as_ptr()) {
236 0 => Ok(()),
237 _ => Err(FltkError::Internal(FltkErrorKind::ResourceNotFound)),
238 }
239 }
240 }
241
242 pub fn save_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), FltkError> {
246 let path = path
247 .as_ref()
248 .to_str()
249 .ok_or_else(|| FltkError::Unknown(String::from("Failed to convert path to string")))?;
250 let path = CString::new(path)?;
251 unsafe {
252 match Fl_Text_Buffer_save_file(*self.inner, path.as_ptr()) {
253 0 => Ok(()),
254 _ => Err(FltkError::Internal(FltkErrorKind::ResourceNotFound)),
255 }
256 }
257 }
258
259 pub fn tab_distance(&self) -> i32 {
261 unsafe { Fl_Text_Buffer_tab_distance(*self.inner) }
262 }
263
264 pub fn set_tab_distance(&mut self, tab_dist: i32) {
266 unsafe { Fl_Text_Buffer_set_tab_distance(*self.inner, tab_dist) }
267 }
268
269 pub fn select(&mut self, start: i32, end: i32) {
271 unsafe { Fl_Text_Buffer_select(*self.inner, start, end) }
272 }
273
274 pub fn selected(&self) -> bool {
276 unsafe { Fl_Text_Buffer_selected(*self.inner) != 0 }
277 }
278
279 pub fn unselect(&mut self) {
281 unsafe { Fl_Text_Buffer_unselect(*self.inner) }
282 }
283
284 pub fn selection_position(&self) -> Option<(i32, i32)> {
286 unsafe {
287 let mut start = 0;
288 let mut end = 0;
289 let ret =
290 Fl_Text_Buffer_selection_position(*self.inner, &mut start as _, &mut end as _);
291 if ret == 0 {
292 None
293 } else {
294 let x = (start, end);
295 Some(x)
296 }
297 }
298 }
299
300 pub fn selection_text(&self) -> String {
302 unsafe {
303 let x = Fl_Text_Buffer_selection_text(*self.inner);
304 assert!(!x.is_null());
305 CStr::from_ptr(x as *mut raw::c_char)
306 .to_string_lossy()
307 .to_string()
308 }
309 }
310
311 pub fn remove_selection(&mut self) {
313 unsafe { Fl_Text_Buffer_remove_selection(*self.inner) }
314 }
315
316 pub fn replace_selection(&mut self, text: &str) {
318 let text = CString::safe_new(text);
319 unsafe { Fl_Text_Buffer_replace_selection(*self.inner, text.as_ptr()) }
320 }
321
322 pub fn secondary_select(&mut self, start: i32, end: i32) {
324 unsafe { Fl_Text_Buffer_secondary_select(*self.inner, start, end) }
325 }
326
327 pub fn secondary_selected(&self) -> bool {
329 unsafe { Fl_Text_Buffer_secondary_selected(*self.inner) != 0 }
330 }
331
332 pub fn secondary_unselect(&mut self) {
334 unsafe { Fl_Text_Buffer_secondary_unselect(*self.inner) }
335 }
336
337 pub fn secondary_selection_position(&self) -> Option<(i32, i32)> {
339 unsafe {
340 let mut start = 0;
341 let mut end = 0;
342 let ret = Fl_Text_Buffer_secondary_selection_position(
343 *self.inner,
344 &mut start as _,
345 &mut end as _,
346 );
347 if ret == 0 {
348 None
349 } else {
350 let x = (start, end);
351 Some(x)
352 }
353 }
354 }
355
356 pub fn secondary_selection_text(&self) -> String {
358 unsafe {
359 let x = Fl_Text_Buffer_secondary_selection_text(*self.inner);
360 assert!(!x.is_null());
361 CStr::from_ptr(x as *mut raw::c_char)
362 .to_string_lossy()
363 .to_string()
364 }
365 }
366
367 pub fn remove_secondary_selection(&mut self) {
369 unsafe { Fl_Text_Buffer_remove_secondary_selection(*self.inner) }
370 }
371
372 pub fn replace_secondary_selection(&mut self, text: &str) {
374 let text = CString::safe_new(text);
375 unsafe { Fl_Text_Buffer_replace_secondary_selection(*self.inner, text.as_ptr()) }
376 }
377
378 pub fn highlight(&mut self, start: i32, end: i32) {
380 unsafe { Fl_Text_Buffer_highlight(*self.inner, start, end) }
381 }
382
383 pub fn is_highlighted(&self) -> bool {
385 unsafe { Fl_Text_Buffer_is_highlighted(*self.inner) != 0 }
386 }
387
388 pub fn unhighlight(&mut self) {
390 unsafe { Fl_Text_Buffer_unhighlight(*self.inner) }
391 }
392
393 pub fn highlight_position(&self) -> Option<(i32, i32)> {
395 unsafe {
396 let mut start = 0;
397 let mut end = 0;
398 let ret =
399 Fl_Text_Buffer_highlight_position(*self.inner, &mut start as _, &mut end as _);
400 if ret == 0 {
401 None
402 } else {
403 let x = (start, end);
404 Some(x)
405 }
406 }
407 }
408
409 pub fn highlight_text(&self) -> String {
411 unsafe {
412 let x = Fl_Text_Buffer_highlight_text(*self.inner);
413 assert!(!x.is_null());
414 CStr::from_ptr(x as *mut raw::c_char)
415 .to_string_lossy()
416 .to_string()
417 }
418 }
419
420 pub fn line_text(&self, pos: i32) -> String {
422 unsafe {
423 let x = Fl_Text_Buffer_line_text(*self.inner, pos);
424 assert!(!x.is_null());
425 CStr::from_ptr(x as *mut raw::c_char)
426 .to_string_lossy()
427 .to_string()
428 }
429 }
430
431 pub fn line_start(&self, pos: i32) -> i32 {
433 unsafe { Fl_Text_Buffer_line_start(*self.inner, pos) }
434 }
435
436 pub fn word_start(&self, pos: i32) -> i32 {
438 unsafe { Fl_Text_Buffer_word_start(*self.inner, pos) }
439 }
440
441 pub fn word_end(&self, pos: i32) -> i32 {
443 unsafe { Fl_Text_Buffer_word_end(*self.inner, pos) }
444 }
445
446 pub fn count_lines(&self, start: i32, end: i32) -> i32 {
448 unsafe { Fl_Text_Buffer_count_lines(*self.inner, start, end) }
449 }
450
451 pub fn call_modify_callbacks(&mut self) {
453 unsafe { Fl_Text_Buffer_call_modify_callbacks(*self.inner) }
454 }
455
456 pub fn add_modify_callback<F: FnMut(i32, i32, i32, i32, &str) + 'static>(&mut self, cb: F) {
460 unsafe {
461 unsafe extern "C" fn shim(
462 pos: raw::c_int,
463 inserted: raw::c_int,
464 deleted: raw::c_int,
465 restyled: raw::c_int,
466 deleted_text: *const raw::c_char,
467 data: *mut raw::c_void,
468 ) {
469 let temp = if deleted_text.is_null() {
470 String::from("")
471 } else {
472 unsafe { CStr::from_ptr(deleted_text).to_string_lossy().to_string() }
473 };
474 let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
475 data as *mut Box<dyn for<'r> FnMut(i32, i32, i32, i32, &'r str)>;
476 let f: &mut (dyn FnMut(i32, i32, i32, i32, &str)) = unsafe { &mut **a };
477 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
478 f(pos, inserted, deleted, restyled, &temp)
479 }));
480 }
481 let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
482 Box::into_raw(Box::new(Box::new(cb)));
483 let data: *mut raw::c_void = a as *mut std::ffi::c_void;
484 let callback: Fl_Text_Modify_Cb = Some(shim);
485 Fl_Text_Buffer_add_modify_callback(*self.inner, callback, data);
486 }
487 }
488
489 pub fn remove_modify_callback<F: FnMut(i32, i32, i32, i32, &str) + 'static>(&mut self, cb: F) {
493 unsafe {
494 unsafe extern "C" fn shim(
495 pos: raw::c_int,
496 inserted: raw::c_int,
497 deleted: raw::c_int,
498 restyled: raw::c_int,
499 deleted_text: *const raw::c_char,
500 data: *mut raw::c_void,
501 ) {
502 let temp = if deleted_text.is_null() {
503 String::from("")
504 } else {
505 unsafe { CStr::from_ptr(deleted_text).to_string_lossy().to_string() }
506 };
507 let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
508 data as *mut Box<dyn for<'r> FnMut(i32, i32, i32, i32, &'r str)>;
509 let f: &mut (dyn FnMut(i32, i32, i32, i32, &str)) = unsafe { &mut **a };
510 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
511 f(pos, inserted, deleted, restyled, &temp)
512 }));
513 }
514 let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
515 Box::into_raw(Box::new(Box::new(cb)));
516 let data: *mut raw::c_void = a as *mut std::ffi::c_void;
517 let callback: Fl_Text_Modify_Cb = Some(shim);
518 Fl_Text_Buffer_remove_modify_callback(*self.inner, callback, data);
519 }
520 }
521
522 pub fn search_forward(
524 &self,
525 start_pos: i32,
526 search_string: &str,
527 match_case: bool,
528 ) -> Option<i32> {
529 unsafe {
530 let search_string = CString::safe_new(search_string);
531 let mut found_pos = 0;
532 let ret = Fl_Text_Buffer_search_forward(
533 *self.inner,
534 start_pos,
535 search_string.as_ptr() as _,
536 &mut found_pos as _,
537 match_case as _,
538 );
539 if ret == 0 { None } else { Some(found_pos) }
540 }
541 }
542
543 pub fn search_backward(
545 &self,
546 start_pos: i32,
547 search_string: &str,
548 match_case: bool,
549 ) -> Option<i32> {
550 unsafe {
551 let search_string = CString::safe_new(search_string);
552 let mut found_pos = 0;
553 let ret = Fl_Text_Buffer_search_backward(
554 *self.inner,
555 start_pos,
556 search_string.as_ptr() as _,
557 &mut found_pos as _,
558 match_case as _,
559 );
560 if ret == 0 { None } else { Some(found_pos) }
561 }
562 }
563
564 pub fn find_char_forward(&self, start_pos: i32, search_char: char) -> Option<i32> {
566 unsafe {
567 let mut found_pos = 0;
568 let ret = Fl_Text_Buffer_findchar_forward(
569 *self.inner,
570 start_pos,
571 search_char as _,
572 &mut found_pos as _,
573 );
574 if ret == 0 { None } else { Some(found_pos) }
575 }
576 }
577
578 pub fn find_char_backward(&self, start_pos: i32, search_char: char) -> Option<i32> {
580 unsafe {
581 let mut found_pos = 0;
582 let ret = Fl_Text_Buffer_findchar_backward(
583 *self.inner,
584 start_pos,
585 search_char as _,
586 &mut found_pos as _,
587 );
588 if ret == 0 { None } else { Some(found_pos) }
589 }
590 }
591}
592
593#[cfg(not(feature = "single-threaded"))]
594unsafe impl Sync for TextBuffer {}
595
596#[cfg(not(feature = "single-threaded"))]
597unsafe impl Send for TextBuffer {}
598
599impl PartialEq for TextBuffer {
600 fn eq(&self, other: &Self) -> bool {
601 self.inner == other.inner
602 }
603}
604
605impl Eq for TextBuffer {}
606
607impl Clone for TextBuffer {
608 fn clone(&self) -> TextBuffer {
609 TextBuffer {
610 inner: self.inner.clone(),
611 }
612 }
613}
614
615impl Drop for TextBuffer {
616 fn drop(&mut self) {
617 if BufWrapper::strong_count(&self.inner) == 1 {
619 unsafe {
620 Fl_Text_Buffer_delete(*self.inner);
621 }
622 }
623 }
624}
625
626#[repr(i32)]
628#[derive(Debug, Copy, Clone, PartialEq, Eq)]
629pub enum WrapMode {
630 None,
632 AtColumn,
634 AtPixel,
636 AtBounds,
638}
639
640#[repr(i32)]
642#[derive(Debug, Copy, Clone, PartialEq, Eq)]
643pub enum DragType {
644 None = -2,
646 StartDnd = -1,
648 Char = 0,
650 Word = 1,
652 Line = 2,
654}
655
656#[derive(Debug)]
658pub struct TextDisplay {
659 inner: crate::widget::WidgetTracker,
660 is_derived: bool,
661}
662
663crate::macros::widget::impl_widget_ext!(TextDisplay, Fl_Text_Display);
664crate::macros::widget::impl_widget_base!(TextDisplay, Fl_Text_Display);
665crate::macros::widget::impl_widget_default!(TextDisplay, Fl_Text_Display);
666crate::macros::display::impl_display_ext!(TextDisplay, Fl_Text_Display);
667
668#[derive(Debug)]
670pub struct TextEditor {
671 inner: crate::widget::WidgetTracker,
672 is_derived: bool,
673}
674
675crate::macros::widget::impl_widget_ext!(TextEditor, Fl_Text_Editor);
676crate::macros::widget::impl_widget_base!(TextEditor, Fl_Text_Editor);
677crate::macros::widget::impl_widget_default!(TextEditor, Fl_Text_Editor);
678crate::macros::display::impl_display_ext!(TextEditor, Fl_Text_Editor);
679
680pub type TextEditorPtr = *mut Fl_Text_Editor;
682
683#[derive(Debug, Clone, Copy, PartialEq, Eq)]
685#[repr(u32)]
686#[non_exhaustive]
687pub enum TextAttr {
688 None = 0x0000,
690 BgColor = 0x0001,
692 BgColorExt = 0x0003,
694 Underline = 0x0004,
696 Grammar = 0x0008,
698 Spelling = 0x000C,
700 StrikeThrough = 0x0010,
702}
703
704#[derive(Debug, Clone, Copy, PartialEq, Eq)]
706pub struct StyleTableEntry {
707 pub color: Color,
709 pub font: Font,
711 pub size: i32,
713 pub attr: TextAttr,
715 pub bgcolor: Color,
717}
718
719impl Default for StyleTableEntry {
720 fn default() -> Self {
721 Self {
722 color: Color::Foreground,
723 font: Font::Helvetica,
724 size: crate::app::font_size(),
725 attr: TextAttr::None,
726 bgcolor: Color::Background2,
727 }
728 }
729}
730
731impl TextEditor {
732 pub const AnyState: crate::enums::Shortcut = crate::enums::Shortcut::from_i32(-1);
734
735 pub fn set_insert_mode(&mut self, b: bool) {
737 assert!(self.has_buffer());
738 unsafe { Fl_Text_Editor_set_insert_mode(self.inner.widget() as _, b as i32) }
739 }
740
741 pub fn insert_mode(&self) -> bool {
743 assert!(self.has_buffer());
744 unsafe { Fl_Text_Editor_insert_mode(self.inner.widget() as _) != 0 }
745 }
746
747 pub fn set_tab_nav(&mut self, val: bool) {
749 assert!(self.has_buffer());
750 unsafe { Fl_Text_Editor_set_tab_nav(self.inner.widget() as _, val as i32) }
751 }
752
753 pub fn tab_nav(&self) -> bool {
755 assert!(self.has_buffer());
756 unsafe { Fl_Text_Editor_tab_nav(self.inner.widget() as _) != 0 }
757 }
758
759 pub fn copy(&self) {
761 assert!(self.has_buffer());
762 unsafe {
763 Fl_Text_Editor_kf_copy(self.inner.widget() as _);
764 }
765 }
766
767 pub fn cut(&self) {
769 assert!(self.has_buffer());
770 unsafe {
771 Fl_Text_Editor_kf_cut(self.inner.widget() as _);
772 }
773 }
774
775 pub fn paste(&self) {
777 assert!(self.has_buffer());
778 unsafe {
779 Fl_Text_Editor_kf_paste(self.inner.widget() as _);
780 }
781 }
782
783 pub fn undo(&self) {
785 assert!(self.has_buffer());
786 unsafe {
787 Fl_Text_Editor_kf_undo(self.inner.widget() as _);
788 }
789 }
790
791 pub fn redo(&self) {
793 assert!(self.has_buffer());
794 unsafe {
795 Fl_Text_Editor_kf_redo(self.inner.widget() as _);
796 }
797 }
798
799 pub fn kf_default(&mut self, c: Key) {
801 assert!(self.has_buffer());
802 unsafe {
803 Fl_Text_Editor_kf_default(c.bits(), self.inner.widget() as _);
804 }
805 }
806
807 pub fn kf_ignore(&mut self, c: Key) {
809 assert!(self.has_buffer());
810 unsafe {
811 Fl_Text_Editor_kf_ignore(c.bits(), self.inner.widget() as _);
812 }
813 }
814
815 pub fn kf_backspace(&mut self) {
817 assert!(self.has_buffer());
818 unsafe {
819 Fl_Text_Editor_kf_backspace(self.inner.widget() as _);
820 }
821 }
822
823 pub fn kf_enter(&mut self) {
825 assert!(self.has_buffer());
826 unsafe {
827 Fl_Text_Editor_kf_enter(self.inner.widget() as _);
828 }
829 }
830
831 pub fn kf_move(&mut self, c: Key) {
833 assert!(self.has_buffer());
834 unsafe {
835 Fl_Text_Editor_kf_move(c.bits(), self.inner.widget() as _);
836 }
837 }
838
839 pub fn kf_shift_move(&mut self, c: Key) {
841 assert!(self.has_buffer());
842 unsafe {
843 Fl_Text_Editor_kf_shift_move(c.bits(), self.inner.widget() as _);
844 }
845 }
846
847 pub fn kf_ctrl_move(&mut self, c: Key) {
849 assert!(self.has_buffer());
850 unsafe {
851 Fl_Text_Editor_kf_ctrl_move(c.bits(), self.inner.widget() as _);
852 }
853 }
854
855 pub fn kf_c_s_move(&mut self, c: Key) {
857 assert!(self.has_buffer());
858 unsafe {
859 Fl_Text_Editor_kf_c_s_move(c.bits(), self.inner.widget() as _);
860 }
861 }
862
863 pub fn kf_meta_move(&mut self, c: Key) {
865 assert!(self.has_buffer());
866 unsafe {
867 Fl_Text_Editor_kf_meta_move(c.bits(), self.inner.widget() as _);
868 }
869 }
870
871 pub fn kf_m_s_move(&mut self, c: Key) {
873 assert!(self.has_buffer());
874 unsafe {
875 Fl_Text_Editor_kf_m_s_move(c.bits(), self.inner.widget() as _);
876 }
877 }
878
879 pub fn kf_home(&mut self) {
881 assert!(self.has_buffer());
882 unsafe {
883 Fl_Text_Editor_kf_home(self.inner.widget() as _);
884 }
885 }
886
887 pub fn kf_end(&mut self) {
889 assert!(self.has_buffer());
890 unsafe {
891 Fl_Text_Editor_kf_end(self.inner.widget() as _);
892 }
893 }
894
895 pub fn kf_left(&mut self) {
897 assert!(self.has_buffer());
898 unsafe {
899 Fl_Text_Editor_kf_left(self.inner.widget() as _);
900 }
901 }
902
903 pub fn kf_up(&mut self) {
905 assert!(self.has_buffer());
906 unsafe {
907 Fl_Text_Editor_kf_up(self.inner.widget() as _);
908 }
909 }
910
911 pub fn kf_right(&mut self) {
913 assert!(self.has_buffer());
914 unsafe {
915 Fl_Text_Editor_kf_right(self.inner.widget() as _);
916 }
917 }
918
919 pub fn kf_down(&mut self) {
921 assert!(self.has_buffer());
922 unsafe {
923 Fl_Text_Editor_kf_down(self.inner.widget() as _);
924 }
925 }
926
927 pub fn kf_page_up(&mut self) {
929 assert!(self.has_buffer());
930 unsafe {
931 Fl_Text_Editor_kf_page_up(self.inner.widget() as _);
932 }
933 }
934
935 pub fn kf_page_down(&mut self) {
937 assert!(self.has_buffer());
938 unsafe {
939 Fl_Text_Editor_kf_page_down(self.inner.widget() as _);
940 }
941 }
942
943 pub fn kf_insert(&mut self) {
945 assert!(self.has_buffer());
946 unsafe {
947 Fl_Text_Editor_kf_insert(self.inner.widget() as _);
948 }
949 }
950
951 pub fn kf_delete(&mut self) {
953 assert!(self.has_buffer());
954 unsafe {
955 Fl_Text_Editor_kf_delete(self.inner.widget() as _);
956 }
957 }
958
959 pub fn kf_select_all(&mut self) {
961 assert!(self.has_buffer());
962 unsafe {
963 Fl_Text_Editor_kf_select_all(self.inner.widget() as _);
964 }
965 }
966
967 pub fn add_key_binding(
969 &mut self,
970 key: crate::enums::Key,
971 shortcut: crate::enums::Shortcut,
972 cb: fn(key: crate::enums::Key, editor: TextEditorPtr) -> i32,
973 ) {
974 unsafe {
975 Fl_Text_Editor_add_key_binding(
976 self.inner.widget() as _,
977 key.bits(),
978 shortcut.bits(),
979 std::mem::transmute(Some(cb)),
980 );
981 }
982 }
983
984 pub fn remove_key_binding(&mut self, key: crate::enums::Key, shortcut: crate::enums::Shortcut) {
986 unsafe {
987 Fl_Text_Editor_remove_key_binding(
988 self.inner.widget() as _,
989 key.bits(),
990 shortcut.bits(),
991 );
992 }
993 }
994}