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
36type BoxedModifyCallbackHandle = *mut Box<dyn FnMut(i32, i32, i32, i32, Option<&str>)>;
37
38pub type ModifyCallbackHandle = *mut ();
40
41#[allow(clippy::type_complexity)]
42unsafe extern "C" fn modify_callback_shim(
43 pos: raw::c_int,
44 inserted: raw::c_int,
45 deleted: raw::c_int,
46 restyled: raw::c_int,
47 deleted_text: *const raw::c_char,
48 data: *mut raw::c_void,
49) {
50 unsafe {
51 let temp = if deleted_text.is_null() {
52 None
53 } else {
54 CStr::from_ptr(deleted_text).to_str().ok()
55 };
56 let a = data as *mut Box<dyn for<'r> FnMut(i32, i32, i32, i32, Option<&'r str>)>;
57 let f: &mut (dyn FnMut(i32, i32, i32, i32, Option<&str>)) = &mut **a;
58 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
59 f(pos, inserted, deleted, restyled, temp);
60 }));
61 }
62}
63
64impl std::default::Default for TextBuffer {
65 fn default() -> TextBuffer {
67 unsafe {
68 let text_buffer = Fl_Text_Buffer_new();
69 assert!(!text_buffer.is_null());
70 TextBuffer {
71 inner: BufWrapper::new(text_buffer),
72 }
73 }
74 }
75}
76
77impl TextBuffer {
78 pub unsafe fn delete(buf: &Self) {
82 assert!(!buf.inner.is_null());
83 unsafe {
84 Fl_Text_Buffer_delete(*buf.inner);
85 }
86 }
87
88 pub unsafe fn delete_buffer(buf: &Self) {
92 unsafe { Self::delete(buf) }
93 }
94
95 pub unsafe fn from_ptr(ptr: *mut Fl_Text_Buffer) -> Self {
99 unsafe {
100 assert!(!ptr.is_null());
101 let inner = BufWrapper::from(ptr);
102 let ptr = BufWrapper::into_raw(inner);
103 BufWrapper::increment_strong_count(ptr);
104 let inner = BufWrapper::from_raw(ptr);
105 TextBuffer { inner }
106 }
107 }
108
109 pub unsafe fn as_ptr(&self) -> *mut Fl_Text_Buffer {
113 unsafe {
114 let ptr = BufWrapper::into_raw(BufWrapper::clone(&self.inner));
115 BufWrapper::increment_strong_count(ptr);
116 let inner = BufWrapper::from_raw(ptr);
117 *inner
118 }
119 }
120
121 pub fn set_text(&mut self, txt: &str) {
123 assert!(!self.inner.is_null());
124 unsafe {
125 let txt = CString::safe_new(txt);
126 Fl_Text_Buffer_set_text(*self.inner, txt.as_ptr());
127 }
128 }
129
130 pub fn text(&self) -> String {
132 assert!(!self.inner.is_null());
133 unsafe {
134 let text = Fl_Text_Buffer_text(*self.inner);
135 assert!(!text.is_null());
136 CStr::from_ptr(text as *mut raw::c_char)
137 .to_string_lossy()
138 .to_string()
139 }
140 }
141
142 pub fn append(&mut self, text: &str) {
160 assert!(!self.inner.is_null());
161 let text = CString::safe_new(text);
162 unsafe { Fl_Text_Buffer_append(*self.inner, text.as_ptr()) }
163 }
164
165 pub fn append_bytes(&mut self, text: &[u8]) {
167 assert!(!self.inner.is_null());
168 unsafe { Fl_Text_Buffer_append_bytes(*self.inner, text.as_ptr() as _, text.len() as _) }
169 }
170
171 pub fn length(&self) -> i32 {
173 assert!(!self.inner.is_null());
174 unsafe { Fl_Text_Buffer_length(*self.inner) }
175 }
176
177 pub fn remove(&mut self, start: i32, end: i32) {
179 assert!(!self.inner.is_null());
180 unsafe {
181 Fl_Text_Buffer_remove(*self.inner, start, end);
182 }
183 }
184
185 pub fn text_range(&self, start: i32, end: i32) -> Option<String> {
187 assert!(!self.inner.is_null());
188 unsafe {
189 let x = Fl_Text_Buffer_text_range(*self.inner, start, end);
190 if x.is_null() {
191 None
192 } else {
193 Some(
194 CStr::from_ptr(x as *mut raw::c_char)
195 .to_string_lossy()
196 .to_string(),
197 )
198 }
199 }
200 }
201
202 pub fn insert(&mut self, pos: i32, text: &str) {
204 assert!(!self.inner.is_null());
205 let text = CString::safe_new(text);
206 unsafe { Fl_Text_Buffer_insert(*self.inner, pos, text.as_ptr()) }
207 }
208
209 pub fn replace(&mut self, start: i32, end: i32, text: &str) {
211 assert!(!self.inner.is_null());
212 assert!(end >= start);
213 let text = CString::safe_new(text);
214 unsafe { Fl_Text_Buffer_replace(*self.inner, start, end, text.as_ptr()) }
215 }
216
217 pub fn copy_from(&mut self, source_buf: &TextBuffer, start: i32, end: i32, to: i32) {
219 assert!(!self.inner.is_null());
220 unsafe { Fl_Text_Buffer_copy(*self.inner, *source_buf.inner, start, end, to) }
221 }
222
223 #[must_use]
225 pub fn copy(&self) -> TextBuffer {
226 assert!(!self.inner.is_null());
227 let mut temp = TextBuffer::default();
228 temp.copy_from(self, 0, 0, self.length());
229 temp
230 }
231
232 pub fn undo(&mut self) -> Result<(), FltkError> {
236 assert!(!self.inner.is_null());
237 unsafe {
238 match Fl_Text_Buffer_undo(*self.inner, std::ptr::null_mut()) {
239 0 => Err(FltkError::Unknown(String::from("Failed to undo"))),
240 _ => Ok(()),
241 }
242 }
243 }
244
245 pub fn redo(&mut self) -> Result<i32, FltkError> {
250 assert!(!self.inner.is_null());
251 unsafe {
252 let mut i = 0;
253 match Fl_Text_Buffer_redo(*self.inner, &mut i) {
254 0 => Err(FltkError::Unknown(String::from("Failed to redo"))),
255 _ => Ok(i),
256 }
257 }
258 }
259
260 pub fn can_undo(&mut self, flag: bool) {
262 assert!(!self.inner.is_null());
263 unsafe { Fl_Text_Buffer_canUndo(*self.inner, raw::c_char::from(flag)) }
264 }
265
266 pub fn get_can_undo(&mut self) -> bool {
268 assert!(!self.inner.is_null());
269 unsafe { Fl_Text_Buffer_can_undo(*self.inner) != 0 }
270 }
271
272 pub fn can_redo(&mut self) -> bool {
274 assert!(!self.inner.is_null());
275 unsafe { Fl_Text_Buffer_can_redo(*self.inner) != 0 }
276 }
277
278 pub fn load_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), FltkError> {
282 assert!(!self.inner.is_null());
283 if !path.as_ref().exists() {
284 return Err(FltkError::Internal(FltkErrorKind::ResourceNotFound));
285 }
286 let path = path
287 .as_ref()
288 .to_str()
289 .ok_or_else(|| FltkError::Unknown(String::from("Failed to convert path to string")))?;
290 let path = CString::new(path)?;
291 unsafe {
292 match Fl_Text_Buffer_load_file(*self.inner, path.as_ptr()) {
293 0 => Ok(()),
294 _ => Err(FltkError::Internal(FltkErrorKind::ResourceNotFound)),
295 }
296 }
297 }
298
299 pub fn save_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), FltkError> {
303 assert!(!self.inner.is_null());
304 let path = path
305 .as_ref()
306 .to_str()
307 .ok_or_else(|| FltkError::Unknown(String::from("Failed to convert path to string")))?;
308 let path = CString::new(path)?;
309 unsafe {
310 match Fl_Text_Buffer_save_file(*self.inner, path.as_ptr()) {
311 0 => Ok(()),
312 _ => Err(FltkError::Internal(FltkErrorKind::ResourceNotFound)),
313 }
314 }
315 }
316
317 pub fn tab_distance(&self) -> i32 {
319 assert!(!self.inner.is_null());
320 unsafe { Fl_Text_Buffer_tab_distance(*self.inner) }
321 }
322
323 pub fn set_tab_distance(&mut self, tab_dist: i32) {
325 assert!(!self.inner.is_null());
326 unsafe { Fl_Text_Buffer_set_tab_distance(*self.inner, tab_dist) }
327 }
328
329 pub fn select(&mut self, start: i32, end: i32) {
331 assert!(!self.inner.is_null());
332 unsafe { Fl_Text_Buffer_select(*self.inner, start, end) }
333 }
334
335 pub fn selected(&self) -> bool {
337 assert!(!self.inner.is_null());
338 unsafe { Fl_Text_Buffer_selected(*self.inner) != 0 }
339 }
340
341 pub fn unselect(&mut self) {
343 assert!(!self.inner.is_null());
344 unsafe { Fl_Text_Buffer_unselect(*self.inner) }
345 }
346
347 pub fn selection_position(&self) -> Option<(i32, i32)> {
349 assert!(!self.inner.is_null());
350 unsafe {
351 let mut start = 0;
352 let mut end = 0;
353 let ret = Fl_Text_Buffer_selection_position(
354 *self.inner,
355 std::ptr::from_mut(&mut start),
356 std::ptr::from_mut(&mut end),
357 );
358 if ret == 0 {
359 None
360 } else {
361 let x = (start, end);
362 Some(x)
363 }
364 }
365 }
366
367 pub fn selection_text(&self) -> String {
369 assert!(!self.inner.is_null());
370 unsafe {
371 let x = Fl_Text_Buffer_selection_text(*self.inner);
372 assert!(!x.is_null());
373 CStr::from_ptr(x as *mut raw::c_char)
374 .to_string_lossy()
375 .to_string()
376 }
377 }
378
379 pub fn remove_selection(&mut self) {
381 assert!(!self.inner.is_null());
382 unsafe { Fl_Text_Buffer_remove_selection(*self.inner) }
383 }
384
385 pub fn replace_selection(&mut self, text: &str) {
387 assert!(!self.inner.is_null());
388 let text = CString::safe_new(text);
389 unsafe { Fl_Text_Buffer_replace_selection(*self.inner, text.as_ptr()) }
390 }
391
392 pub fn secondary_select(&mut self, start: i32, end: i32) {
394 assert!(!self.inner.is_null());
395 unsafe { Fl_Text_Buffer_secondary_select(*self.inner, start, end) }
396 }
397
398 pub fn secondary_selected(&self) -> bool {
400 assert!(!self.inner.is_null());
401 unsafe { Fl_Text_Buffer_secondary_selected(*self.inner) != 0 }
402 }
403
404 pub fn secondary_unselect(&mut self) {
406 assert!(!self.inner.is_null());
407 unsafe { Fl_Text_Buffer_secondary_unselect(*self.inner) }
408 }
409
410 pub fn secondary_selection_position(&self) -> Option<(i32, i32)> {
412 assert!(!self.inner.is_null());
413 unsafe {
414 let mut start = 0;
415 let mut end = 0;
416 let ret = Fl_Text_Buffer_secondary_selection_position(
417 *self.inner,
418 std::ptr::from_mut(&mut start),
419 std::ptr::from_mut(&mut end),
420 );
421 if ret == 0 {
422 None
423 } else {
424 let x = (start, end);
425 Some(x)
426 }
427 }
428 }
429
430 pub fn secondary_selection_text(&self) -> String {
432 assert!(!self.inner.is_null());
433 unsafe {
434 let x = Fl_Text_Buffer_secondary_selection_text(*self.inner);
435 assert!(!x.is_null());
436 CStr::from_ptr(x as *mut raw::c_char)
437 .to_string_lossy()
438 .to_string()
439 }
440 }
441
442 pub fn remove_secondary_selection(&mut self) {
444 assert!(!self.inner.is_null());
445 unsafe { Fl_Text_Buffer_remove_secondary_selection(*self.inner) }
446 }
447
448 pub fn replace_secondary_selection(&mut self, text: &str) {
450 assert!(!self.inner.is_null());
451 let text = CString::safe_new(text);
452 unsafe { Fl_Text_Buffer_replace_secondary_selection(*self.inner, text.as_ptr()) }
453 }
454
455 pub fn highlight(&mut self, start: i32, end: i32) {
457 assert!(!self.inner.is_null());
458 unsafe { Fl_Text_Buffer_highlight(*self.inner, start, end) }
459 }
460
461 pub fn is_highlighted(&self) -> bool {
463 assert!(!self.inner.is_null());
464 unsafe { Fl_Text_Buffer_is_highlighted(*self.inner) != 0 }
465 }
466
467 pub fn unhighlight(&mut self) {
469 assert!(!self.inner.is_null());
470 unsafe { Fl_Text_Buffer_unhighlight(*self.inner) }
471 }
472
473 pub fn highlight_position(&self) -> Option<(i32, i32)> {
475 assert!(!self.inner.is_null());
476 unsafe {
477 let mut start = 0;
478 let mut end = 0;
479 let ret = Fl_Text_Buffer_highlight_position(
480 *self.inner,
481 std::ptr::from_mut(&mut start),
482 std::ptr::from_mut(&mut end),
483 );
484 if ret == 0 {
485 None
486 } else {
487 let x = (start, end);
488 Some(x)
489 }
490 }
491 }
492
493 pub fn highlight_text(&self) -> String {
495 assert!(!self.inner.is_null());
496 unsafe {
497 let x = Fl_Text_Buffer_highlight_text(*self.inner);
498 assert!(!x.is_null());
499 CStr::from_ptr(x as *mut raw::c_char)
500 .to_string_lossy()
501 .to_string()
502 }
503 }
504
505 pub fn line_text(&self, pos: i32) -> String {
507 assert!(!self.inner.is_null());
508 unsafe {
509 let x = Fl_Text_Buffer_line_text(*self.inner, pos);
510 assert!(!x.is_null());
511 CStr::from_ptr(x as *mut raw::c_char)
512 .to_string_lossy()
513 .to_string()
514 }
515 }
516
517 pub fn line_start(&self, pos: i32) -> i32 {
519 assert!(!self.inner.is_null());
520 unsafe { Fl_Text_Buffer_line_start(*self.inner, pos) }
521 }
522
523 pub fn word_start(&self, pos: i32) -> i32 {
525 assert!(!self.inner.is_null());
526 unsafe { Fl_Text_Buffer_word_start(*self.inner, pos) }
527 }
528
529 pub fn word_end(&self, pos: i32) -> i32 {
531 assert!(!self.inner.is_null());
532 unsafe { Fl_Text_Buffer_word_end(*self.inner, pos) }
533 }
534
535 pub fn count_lines(&self, start: i32, end: i32) -> i32 {
537 assert!(!self.inner.is_null());
538 unsafe { Fl_Text_Buffer_count_lines(*self.inner, start, end) }
539 }
540
541 pub fn call_modify_callbacks(&mut self) {
543 assert!(!self.inner.is_null());
544 unsafe { Fl_Text_Buffer_call_modify_callbacks(*self.inner) }
545 }
546
547 fn add_modify_callback_<F: FnMut(i32, i32, i32, i32, Option<&str>) + 'static>(
548 &mut self,
549 cb: F,
550 ) -> ModifyCallbackHandle {
551 assert!(!self.inner.is_null());
552 unsafe {
553 let a: BoxedModifyCallbackHandle = Box::into_raw(Box::new(Box::new(cb)));
554 let data: *mut raw::c_void = a as *mut std::ffi::c_void;
555 let callback: Fl_Text_Modify_Cb = Some(modify_callback_shim);
556 Fl_Text_Buffer_add_modify_callback(*self.inner, callback, data);
557 data as _
558 }
559 }
560
561 pub fn add_modify_callback<F: FnMut(&mut Self, i32, i32, i32, i32, Option<&str>) + 'static>(
565 &mut self,
566 mut cb: F,
567 ) -> ModifyCallbackHandle {
568 let mut s = self.clone();
569 self.add_modify_callback_(move |pos, ins, del, restyled, txt| {
570 cb(&mut s, pos, ins, del, restyled, txt);
571 })
572 }
573
574 pub fn remove_modify_callback(&mut self, cb: ModifyCallbackHandle) {
578 assert!(!self.inner.is_null());
579 unsafe {
580 let data: *mut raw::c_void = cb as *mut std::ffi::c_void;
581 let callback: Fl_Text_Modify_Cb = Some(modify_callback_shim);
582 Fl_Text_Buffer_remove_modify_callback(*self.inner, callback, data);
583 }
584 }
585
586 pub fn search_forward(
588 &self,
589 start_pos: i32,
590 search_string: &str,
591 match_case: bool,
592 ) -> Option<i32> {
593 unsafe {
594 let search_string = CString::safe_new(search_string);
595 let mut found_pos = 0;
596 let ret = Fl_Text_Buffer_search_forward(
597 *self.inner,
598 start_pos,
599 search_string.as_ptr() as _,
600 std::ptr::from_mut(&mut found_pos),
601 match_case.into(),
602 );
603 if ret == 0 { None } else { Some(found_pos) }
604 }
605 }
606
607 pub fn search_backward(
609 &self,
610 start_pos: i32,
611 search_string: &str,
612 match_case: bool,
613 ) -> Option<i32> {
614 unsafe {
615 let search_string = CString::safe_new(search_string);
616 let mut found_pos = 0;
617 let ret = Fl_Text_Buffer_search_backward(
618 *self.inner,
619 start_pos,
620 search_string.as_ptr() as _,
621 std::ptr::from_mut(&mut found_pos),
622 match_case.into(),
623 );
624 if ret == 0 { None } else { Some(found_pos) }
625 }
626 }
627
628 pub fn find_char_forward(&self, start_pos: i32, search_char: char) -> Option<i32> {
630 unsafe {
631 let mut found_pos = 0;
632 let ret = Fl_Text_Buffer_findchar_forward(
633 *self.inner,
634 start_pos,
635 search_char as _,
636 std::ptr::from_mut(&mut found_pos),
637 );
638 if ret == 0 { None } else { Some(found_pos) }
639 }
640 }
641
642 pub fn find_char_backward(&self, start_pos: i32, search_char: char) -> Option<i32> {
644 unsafe {
645 let mut found_pos = 0;
646 let ret = Fl_Text_Buffer_findchar_backward(
647 *self.inner,
648 start_pos,
649 search_char as _,
650 std::ptr::from_mut(&mut found_pos),
651 );
652 if ret == 0 { None } else { Some(found_pos) }
653 }
654 }
655}
656
657#[cfg(not(feature = "single-threaded"))]
658unsafe impl Sync for TextBuffer {}
659
660#[cfg(not(feature = "single-threaded"))]
661unsafe impl Send for TextBuffer {}
662
663impl PartialEq for TextBuffer {
664 fn eq(&self, other: &Self) -> bool {
665 self.inner == other.inner
666 }
667}
668
669impl Eq for TextBuffer {}
670
671impl Clone for TextBuffer {
672 fn clone(&self) -> TextBuffer {
673 assert!(!self.inner.is_null());
674 TextBuffer {
675 inner: BufWrapper::clone(&self.inner),
676 }
677 }
678}
679
680impl Drop for TextBuffer {
681 fn drop(&mut self) {
682 assert!(!self.inner.is_null());
683 if BufWrapper::strong_count(&self.inner) == 1 {
684 unsafe {
685 Fl_Text_Buffer_delete(*self.inner);
686 }
687 }
688 }
689}
690
691#[repr(i32)]
693#[derive(Debug, Copy, Clone, PartialEq, Eq)]
694pub enum WrapMode {
695 None,
697 AtColumn,
699 AtPixel,
701 AtBounds,
703}
704
705#[repr(i32)]
707#[derive(Debug, Copy, Clone, PartialEq, Eq)]
708pub enum DragType {
709 None = -2,
711 StartDnd = -1,
713 Char = 0,
715 Word = 1,
717 Line = 2,
719}
720
721#[derive(Debug)]
723pub struct TextDisplay {
724 inner: crate::widget::WidgetTracker,
725 is_derived: bool,
726}
727
728crate::macros::widget::impl_widget_ext!(TextDisplay, Fl_Text_Display);
729crate::macros::widget::impl_widget_base!(TextDisplay, Fl_Text_Display);
730crate::macros::widget::impl_widget_default!(TextDisplay, Fl_Text_Display);
731crate::macros::display::impl_display_ext!(TextDisplay, Fl_Text_Display);
732
733#[derive(Debug)]
735pub struct TextEditor {
736 inner: crate::widget::WidgetTracker,
737 is_derived: bool,
738}
739
740crate::macros::widget::impl_widget_ext!(TextEditor, Fl_Text_Editor);
741crate::macros::widget::impl_widget_base!(TextEditor, Fl_Text_Editor);
742crate::macros::widget::impl_widget_default!(TextEditor, Fl_Text_Editor);
743crate::macros::display::impl_display_ext!(TextEditor, Fl_Text_Editor);
744
745pub type TextEditorPtr = *mut Fl_Text_Editor;
747
748#[derive(Debug, Clone, Copy, PartialEq, Eq)]
750#[repr(u32)]
751#[non_exhaustive]
752pub enum TextAttr {
753 None = 0x0000,
755 BgColor = 0x0001,
757 BgColorExt = 0x0003,
759 Underline = 0x0004,
761 Grammar = 0x0008,
763 Spelling = 0x000C,
765 StrikeThrough = 0x0010,
767}
768
769#[derive(Debug, Clone, Copy, PartialEq, Eq)]
771pub struct StyleTableEntry {
772 pub color: Color,
774 pub font: Font,
776 pub size: i32,
778 pub attr: TextAttr,
780 pub bgcolor: Color,
782}
783
784impl Default for StyleTableEntry {
785 fn default() -> Self {
786 Self {
787 color: Color::Foreground,
788 font: Font::Helvetica,
789 size: crate::app::font_size(),
790 attr: TextAttr::None,
791 bgcolor: Color::Background2,
792 }
793 }
794}
795
796impl TextEditor {
797 pub const AnyState: crate::enums::Shortcut = crate::enums::Shortcut::from_i32(-1);
799
800 pub fn set_insert_mode(&mut self, b: bool) {
802 assert!(self.has_buffer());
803 unsafe { Fl_Text_Editor_set_insert_mode(self.inner.widget() as _, i32::from(b)) }
804 }
805
806 pub fn insert_mode(&self) -> bool {
808 assert!(self.has_buffer());
809 unsafe { Fl_Text_Editor_insert_mode(self.inner.widget() as _) != 0 }
810 }
811
812 pub fn set_tab_nav(&mut self, val: bool) {
814 assert!(self.has_buffer());
815 unsafe { Fl_Text_Editor_set_tab_nav(self.inner.widget() as _, i32::from(val)) }
816 }
817
818 pub fn tab_nav(&self) -> bool {
820 assert!(self.has_buffer());
821 unsafe { Fl_Text_Editor_tab_nav(self.inner.widget() as _) != 0 }
822 }
823
824 pub fn copy(&self) {
826 assert!(self.has_buffer());
827 unsafe {
828 Fl_Text_Editor_kf_copy(self.inner.widget() as _);
829 }
830 }
831
832 pub fn cut(&self) {
834 assert!(self.has_buffer());
835 unsafe {
836 Fl_Text_Editor_kf_cut(self.inner.widget() as _);
837 }
838 }
839
840 pub fn paste(&self) {
842 assert!(self.has_buffer());
843 unsafe {
844 Fl_Text_Editor_kf_paste(self.inner.widget() as _);
845 }
846 }
847
848 pub fn undo(&self) {
850 assert!(self.has_buffer());
851 unsafe {
852 Fl_Text_Editor_kf_undo(self.inner.widget() as _);
853 }
854 }
855
856 pub fn redo(&self) {
858 assert!(self.has_buffer());
859 unsafe {
860 Fl_Text_Editor_kf_redo(self.inner.widget() as _);
861 }
862 }
863
864 pub fn kf_default(&mut self, c: Key) {
866 assert!(self.has_buffer());
867 unsafe {
868 Fl_Text_Editor_kf_default(c.bits(), self.inner.widget() as _);
869 }
870 }
871
872 pub fn kf_ignore(&mut self, c: Key) {
874 assert!(self.has_buffer());
875 unsafe {
876 Fl_Text_Editor_kf_ignore(c.bits(), self.inner.widget() as _);
877 }
878 }
879
880 pub fn kf_backspace(&mut self) {
882 assert!(self.has_buffer());
883 unsafe {
884 Fl_Text_Editor_kf_backspace(self.inner.widget() as _);
885 }
886 }
887
888 pub fn kf_enter(&mut self) {
890 assert!(self.has_buffer());
891 unsafe {
892 Fl_Text_Editor_kf_enter(self.inner.widget() as _);
893 }
894 }
895
896 pub fn kf_move(&mut self, c: Key) {
898 assert!(self.has_buffer());
899 unsafe {
900 Fl_Text_Editor_kf_move(c.bits(), self.inner.widget() as _);
901 }
902 }
903
904 pub fn kf_shift_move(&mut self, c: Key) {
906 assert!(self.has_buffer());
907 unsafe {
908 Fl_Text_Editor_kf_shift_move(c.bits(), self.inner.widget() as _);
909 }
910 }
911
912 pub fn kf_ctrl_move(&mut self, c: Key) {
914 assert!(self.has_buffer());
915 unsafe {
916 Fl_Text_Editor_kf_ctrl_move(c.bits(), self.inner.widget() as _);
917 }
918 }
919
920 pub fn kf_c_s_move(&mut self, c: Key) {
922 assert!(self.has_buffer());
923 unsafe {
924 Fl_Text_Editor_kf_c_s_move(c.bits(), self.inner.widget() as _);
925 }
926 }
927
928 pub fn kf_meta_move(&mut self, c: Key) {
930 assert!(self.has_buffer());
931 unsafe {
932 Fl_Text_Editor_kf_meta_move(c.bits(), self.inner.widget() as _);
933 }
934 }
935
936 pub fn kf_m_s_move(&mut self, c: Key) {
938 assert!(self.has_buffer());
939 unsafe {
940 Fl_Text_Editor_kf_m_s_move(c.bits(), self.inner.widget() as _);
941 }
942 }
943
944 pub fn kf_home(&mut self) {
946 assert!(self.has_buffer());
947 unsafe {
948 Fl_Text_Editor_kf_home(self.inner.widget() as _);
949 }
950 }
951
952 pub fn kf_end(&mut self) {
954 assert!(self.has_buffer());
955 unsafe {
956 Fl_Text_Editor_kf_end(self.inner.widget() as _);
957 }
958 }
959
960 pub fn kf_left(&mut self) {
962 assert!(self.has_buffer());
963 unsafe {
964 Fl_Text_Editor_kf_left(self.inner.widget() as _);
965 }
966 }
967
968 pub fn kf_up(&mut self) {
970 assert!(self.has_buffer());
971 unsafe {
972 Fl_Text_Editor_kf_up(self.inner.widget() as _);
973 }
974 }
975
976 pub fn kf_right(&mut self) {
978 assert!(self.has_buffer());
979 unsafe {
980 Fl_Text_Editor_kf_right(self.inner.widget() as _);
981 }
982 }
983
984 pub fn kf_down(&mut self) {
986 assert!(self.has_buffer());
987 unsafe {
988 Fl_Text_Editor_kf_down(self.inner.widget() as _);
989 }
990 }
991
992 pub fn kf_page_up(&mut self) {
994 assert!(self.has_buffer());
995 unsafe {
996 Fl_Text_Editor_kf_page_up(self.inner.widget() as _);
997 }
998 }
999
1000 pub fn kf_page_down(&mut self) {
1002 assert!(self.has_buffer());
1003 unsafe {
1004 Fl_Text_Editor_kf_page_down(self.inner.widget() as _);
1005 }
1006 }
1007
1008 pub fn kf_insert(&mut self) {
1010 assert!(self.has_buffer());
1011 unsafe {
1012 Fl_Text_Editor_kf_insert(self.inner.widget() as _);
1013 }
1014 }
1015
1016 pub fn kf_delete(&mut self) {
1018 assert!(self.has_buffer());
1019 unsafe {
1020 Fl_Text_Editor_kf_delete(self.inner.widget() as _);
1021 }
1022 }
1023
1024 pub fn kf_select_all(&mut self) {
1026 assert!(self.has_buffer());
1027 unsafe {
1028 Fl_Text_Editor_kf_select_all(self.inner.widget() as _);
1029 }
1030 }
1031
1032 pub fn add_key_binding(
1034 &mut self,
1035 key: crate::enums::Key,
1036 shortcut: crate::enums::Shortcut,
1037 cb: fn(key: crate::enums::Key, editor: TextEditorPtr) -> i32,
1038 ) {
1039 unsafe {
1040 Fl_Text_Editor_add_key_binding(
1041 self.inner.widget() as _,
1042 key.bits(),
1043 shortcut.bits(),
1044 std::mem::transmute(Some(cb)),
1045 );
1046 }
1047 }
1048
1049 pub fn remove_key_binding(&mut self, key: crate::enums::Key, shortcut: crate::enums::Shortcut) {
1051 unsafe {
1052 Fl_Text_Editor_remove_key_binding(
1053 self.inner.widget() as _,
1054 key.bits(),
1055 shortcut.bits(),
1056 );
1057 }
1058 }
1059}