use crate::enums::{Color, Font, Key};
use crate::prelude::*;
use crate::utils::FlString;
use fltk_sys::text::*;
use std::{
ffi::{CStr, CString},
os::raw,
sync::Arc,
};
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Cursor {
Normal,
Caret,
Dim,
Block,
Heavy,
Simple,
}
#[derive(Debug)]
pub struct TextBuffer {
inner: Arc<*mut Fl_Text_Buffer>,
}
impl std::default::Default for TextBuffer {
fn default() -> TextBuffer {
unsafe {
let text_buffer = Fl_Text_Buffer_new();
assert!(!text_buffer.is_null());
TextBuffer {
inner: Arc::new(text_buffer),
}
}
}
}
impl TextBuffer {
pub unsafe fn delete(buf: Self) {
drop(buf);
}
pub unsafe fn delete_buffer(buf: TextBuffer) {
drop(buf);
}
pub unsafe fn from_ptr(ptr: *mut Fl_Text_Buffer) -> Self {
assert!(!ptr.is_null());
let inner = Arc::from(ptr);
let ptr = Arc::into_raw(inner);
Arc::increment_strong_count(ptr);
let inner = Arc::from_raw(ptr);
TextBuffer { inner }
}
pub unsafe fn as_ptr(&self) -> *mut Fl_Text_Buffer {
let ptr = Arc::into_raw(Arc::clone(&self.inner));
Arc::increment_strong_count(ptr);
let inner = Arc::from_raw(ptr);
*inner
}
pub fn set_text(&mut self, txt: &str) {
assert!(!self.inner.is_null());
unsafe {
let txt = CString::safe_new(txt);
Fl_Text_Buffer_set_text(*self.inner, txt.as_ptr())
}
}
pub fn text(&self) -> String {
assert!(!self.inner.is_null());
unsafe {
let text = Fl_Text_Buffer_text(*self.inner);
assert!(!text.is_null());
CStr::from_ptr(text as *mut raw::c_char)
.to_string_lossy()
.to_string()
}
}
pub fn append(&mut self, text: &str) {
assert!(!self.inner.is_null());
let text = CString::safe_new(text);
unsafe { Fl_Text_Buffer_append(*self.inner, text.as_ptr()) }
}
pub fn length(&self) -> i32 {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_length(*self.inner) }
}
pub fn remove(&mut self, start: i32, end: i32) {
assert!(!self.inner.is_null());
unsafe {
Fl_Text_Buffer_remove(*self.inner, start, end);
}
}
pub fn text_range(&self, start: i32, end: i32) -> Option<String> {
assert!(!self.inner.is_null());
unsafe {
let x = Fl_Text_Buffer_text_range(*self.inner, start, end);
if x.is_null() {
None
} else {
Some(
CStr::from_ptr(x as *mut raw::c_char)
.to_string_lossy()
.to_string(),
)
}
}
}
pub fn insert(&mut self, pos: i32, text: &str) {
assert!(!self.inner.is_null());
let text = CString::safe_new(text);
unsafe { Fl_Text_Buffer_insert(*self.inner, pos, text.as_ptr()) }
}
pub fn replace(&mut self, start: i32, end: i32, text: &str) {
assert!(!self.inner.is_null());
let text = CString::safe_new(text);
unsafe { Fl_Text_Buffer_replace(*self.inner, start, end, text.as_ptr()) }
}
pub fn copy_from(&mut self, source_buf: &TextBuffer, start: i32, end: i32, to: i32) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_copy(*self.inner, *source_buf.inner, start, end, to) }
}
pub fn copy(&self) -> TextBuffer {
assert!(!self.inner.is_null());
let mut temp = TextBuffer::default();
temp.copy_from(self, 0, 0, self.length());
temp
}
pub fn undo(&mut self) -> Result<(), FltkError> {
assert!(!self.inner.is_null());
unsafe {
match Fl_Text_Buffer_undo(*self.inner, std::ptr::null_mut()) {
0 => Err(FltkError::Unknown(String::from("Failed to undo"))),
_ => Ok(()),
}
}
}
pub fn can_undo(&mut self, flag: bool) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_canUndo(*self.inner, flag as raw::c_char) }
}
pub fn load_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), FltkError> {
assert!(!self.inner.is_null());
if !path.as_ref().exists() {
return Err(FltkError::Internal(FltkErrorKind::ResourceNotFound));
}
let path = path
.as_ref()
.to_str()
.ok_or_else(|| FltkError::Unknown(String::from("Failed to convert path to string")))?;
let path = CString::new(path)?;
unsafe {
match Fl_Text_Buffer_load_file(*self.inner, path.as_ptr()) {
0 => Ok(()),
_ => Err(FltkError::Internal(FltkErrorKind::ResourceNotFound)),
}
}
}
pub fn save_file<P: AsRef<std::path::Path>>(&mut self, path: P) -> Result<(), FltkError> {
assert!(!self.inner.is_null());
let path = path
.as_ref()
.to_str()
.ok_or_else(|| FltkError::Unknown(String::from("Failed to convert path to string")))?;
let path = CString::new(path)?;
unsafe {
match Fl_Text_Buffer_save_file(*self.inner, path.as_ptr()) {
0 => Ok(()),
_ => Err(FltkError::Internal(FltkErrorKind::ResourceNotFound)),
}
}
}
pub fn tab_distance(&self) -> i32 {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_tab_distance(*self.inner) }
}
pub fn set_tab_distance(&mut self, tab_dist: i32) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_set_tab_distance(*self.inner, tab_dist) }
}
pub fn select(&mut self, start: i32, end: i32) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_select(*self.inner, start, end) }
}
pub fn selected(&self) -> bool {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_selected(*self.inner) != 0 }
}
pub fn unselect(&mut self) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_unselect(*self.inner) }
}
pub fn selection_position(&self) -> Option<(i32, i32)> {
assert!(!self.inner.is_null());
unsafe {
let mut start = 0;
let mut end = 0;
let ret =
Fl_Text_Buffer_selection_position(*self.inner, &mut start as _, &mut end as _);
if ret == 0 {
None
} else {
let x = (start, end);
Some(x)
}
}
}
pub fn selection_text(&self) -> String {
assert!(!self.inner.is_null());
unsafe {
let x = Fl_Text_Buffer_selection_text(*self.inner);
assert!(!x.is_null());
CStr::from_ptr(x as *mut raw::c_char)
.to_string_lossy()
.to_string()
}
}
pub fn remove_selection(&mut self) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_remove_selection(*self.inner) }
}
pub fn replace_selection(&mut self, text: &str) {
assert!(!self.inner.is_null());
let text = CString::safe_new(text);
unsafe { Fl_Text_Buffer_replace_selection(*self.inner, text.as_ptr()) }
}
pub fn secondary_select(&mut self, start: i32, end: i32) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_secondary_select(*self.inner, start, end) }
}
pub fn secondary_selected(&self) -> bool {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_secondary_selected(*self.inner) != 0 }
}
pub fn secondary_unselect(&mut self) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_secondary_unselect(*self.inner) }
}
pub fn secondary_selection_position(&self) -> Option<(i32, i32)> {
assert!(!self.inner.is_null());
unsafe {
let mut start = 0;
let mut end = 0;
let ret = Fl_Text_Buffer_secondary_selection_position(
*self.inner,
&mut start as _,
&mut end as _,
);
if ret == 0 {
None
} else {
let x = (start, end);
Some(x)
}
}
}
pub fn secondary_selection_text(&self) -> String {
assert!(!self.inner.is_null());
unsafe {
let x = Fl_Text_Buffer_secondary_selection_text(*self.inner);
assert!(!x.is_null());
CStr::from_ptr(x as *mut raw::c_char)
.to_string_lossy()
.to_string()
}
}
pub fn remove_secondary_selection(&mut self) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_remove_secondary_selection(*self.inner) }
}
pub fn replace_secondary_selection(&mut self, text: &str) {
assert!(!self.inner.is_null());
let text = CString::safe_new(text);
unsafe { Fl_Text_Buffer_replace_secondary_selection(*self.inner, text.as_ptr()) }
}
pub fn highlight(&mut self, start: i32, end: i32) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_highlight(*self.inner, start, end) }
}
pub fn is_highlighted(&self) -> bool {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_is_highlighted(*self.inner) != 0 }
}
pub fn unhighlight(&mut self) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_unhighlight(*self.inner) }
}
pub fn highlight_position(&self) -> Option<(i32, i32)> {
assert!(!self.inner.is_null());
unsafe {
let mut start = 0;
let mut end = 0;
let ret =
Fl_Text_Buffer_highlight_position(*self.inner, &mut start as _, &mut end as _);
if ret == 0 {
None
} else {
let x = (start, end);
Some(x)
}
}
}
pub fn highlight_text(&self) -> String {
assert!(!self.inner.is_null());
unsafe {
let x = Fl_Text_Buffer_highlight_text(*self.inner);
assert!(!x.is_null());
CStr::from_ptr(x as *mut raw::c_char)
.to_string_lossy()
.to_string()
}
}
pub fn line_text(&self, pos: i32) -> String {
assert!(!self.inner.is_null());
unsafe {
let x = Fl_Text_Buffer_line_text(*self.inner, pos);
assert!(!x.is_null());
CStr::from_ptr(x as *mut raw::c_char)
.to_string_lossy()
.to_string()
}
}
pub fn line_start(&self, pos: i32) -> i32 {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_line_start(*self.inner, pos) }
}
pub fn word_start(&self, pos: i32) -> i32 {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_word_start(*self.inner, pos) }
}
pub fn word_end(&self, pos: i32) -> i32 {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_word_end(*self.inner, pos) }
}
pub fn count_lines(&self, start: i32, end: i32) -> i32 {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_count_lines(*self.inner, start, end) }
}
pub fn call_modify_callbacks(&mut self) {
assert!(!self.inner.is_null());
unsafe { Fl_Text_Buffer_call_modify_callbacks(*self.inner) }
}
pub fn add_modify_callback<F: FnMut(i32, i32, i32, i32, &str) + 'static>(&mut self, cb: F) {
assert!(!self.inner.is_null());
unsafe {
unsafe extern "C" fn shim(
pos: raw::c_int,
inserted: raw::c_int,
deleted: raw::c_int,
restyled: raw::c_int,
deleted_text: *const raw::c_char,
data: *mut raw::c_void,
) {
let temp = if deleted_text.is_null() {
String::from("")
} else {
CStr::from_ptr(deleted_text).to_string_lossy().to_string()
};
let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
data as *mut Box<dyn for<'r> FnMut(i32, i32, i32, i32, &'r str)>;
let f: &mut (dyn FnMut(i32, i32, i32, i32, &str)) = &mut **a;
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
f(pos, inserted, deleted, restyled, &temp)
}));
}
let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut std::ffi::c_void;
let callback: Fl_Text_Modify_Cb = Some(shim);
Fl_Text_Buffer_add_modify_callback(*self.inner, callback, data);
}
}
pub fn remove_modify_callback<F: FnMut(i32, i32, i32, i32, &str) + 'static>(&mut self, cb: F) {
assert!(!self.inner.is_null());
unsafe {
unsafe extern "C" fn shim(
pos: raw::c_int,
inserted: raw::c_int,
deleted: raw::c_int,
restyled: raw::c_int,
deleted_text: *const raw::c_char,
data: *mut raw::c_void,
) {
let temp = if deleted_text.is_null() {
String::from("")
} else {
CStr::from_ptr(deleted_text).to_string_lossy().to_string()
};
let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
data as *mut Box<dyn for<'r> FnMut(i32, i32, i32, i32, &'r str)>;
let f: &mut (dyn FnMut(i32, i32, i32, i32, &str)) = &mut **a;
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
f(pos, inserted, deleted, restyled, &temp)
}));
}
let a: *mut Box<dyn FnMut(i32, i32, i32, i32, &str)> =
Box::into_raw(Box::new(Box::new(cb)));
let data: *mut raw::c_void = a as *mut std::ffi::c_void;
let callback: Fl_Text_Modify_Cb = Some(shim);
Fl_Text_Buffer_remove_modify_callback(*self.inner, callback, data);
}
}
pub fn search_forward(
&self,
start_pos: i32,
search_string: &str,
match_case: bool,
) -> Option<i32> {
unsafe {
let search_string = CString::safe_new(search_string);
let mut found_pos = 0;
let ret = Fl_Text_Buffer_search_forward(
*self.inner,
start_pos,
search_string.as_ptr() as _,
&mut found_pos as _,
match_case as _,
);
if ret == 0 {
None
} else {
Some(found_pos)
}
}
}
pub fn search_backward(
&self,
start_pos: i32,
search_string: &str,
match_case: bool,
) -> Option<i32> {
unsafe {
let search_string = CString::safe_new(search_string);
let mut found_pos = 0;
let ret = Fl_Text_Buffer_search_backward(
*self.inner,
start_pos,
search_string.as_ptr() as _,
&mut found_pos as _,
match_case as _,
);
if ret == 0 {
None
} else {
Some(found_pos)
}
}
}
pub fn find_char_forward(&self, start_pos: i32, search_char: char) -> Option<i32> {
unsafe {
let mut found_pos = 0;
let ret = Fl_Text_Buffer_findchar_forward(
*self.inner,
start_pos,
search_char as _,
&mut found_pos as _,
);
if ret == 0 {
None
} else {
Some(found_pos)
}
}
}
pub fn find_char_backward(&self, start_pos: i32, search_char: char) -> Option<i32> {
unsafe {
let mut found_pos = 0;
let ret = Fl_Text_Buffer_findchar_backward(
*self.inner,
start_pos,
search_char as _,
&mut found_pos as _,
);
if ret == 0 {
None
} else {
Some(found_pos)
}
}
}
}
unsafe impl Sync for TextBuffer {}
unsafe impl Send for TextBuffer {}
impl PartialEq for TextBuffer {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl Eq for TextBuffer {}
impl Clone for TextBuffer {
fn clone(&self) -> TextBuffer {
assert!(!self.inner.is_null());
TextBuffer {
inner: Arc::clone(&self.inner),
}
}
}
impl Drop for TextBuffer {
fn drop(&mut self) {
assert!(!self.inner.is_null());
if Arc::strong_count(&self.inner) == 1 {
unsafe {
Fl_Text_Buffer_delete(*self.inner);
}
}
}
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum WrapMode {
None,
AtColumn,
AtPixel,
AtBounds,
}
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DragType {
None = -2,
StartDnd = -1,
Char = 0,
Word = 1,
Line = 2,
}
#[derive(Debug)]
pub struct TextDisplay {
inner: *mut Fl_Text_Display,
tracker: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(TextDisplay, Fl_Text_Display);
crate::macros::widget::impl_widget_base!(TextDisplay, Fl_Text_Display);
crate::macros::widget::impl_widget_default!(TextDisplay);
crate::macros::display::impl_display_ext!(TextDisplay, Fl_Text_Display);
#[derive(Debug)]
pub struct TextEditor {
inner: *mut Fl_Text_Editor,
tracker: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(TextEditor, Fl_Text_Editor);
crate::macros::widget::impl_widget_base!(TextEditor, Fl_Text_Editor);
crate::macros::widget::impl_widget_default!(TextEditor);
crate::macros::display::impl_display_ext!(TextEditor, Fl_Text_Editor);
pub type TextEditorPtr = *mut Fl_Text_Editor;
#[derive(Debug)]
pub struct SimpleTerminal {
inner: *mut Fl_Simple_Terminal,
tracker: crate::widget::WidgetTracker,
is_derived: bool,
}
crate::macros::widget::impl_widget_ext!(SimpleTerminal, Fl_Simple_Terminal);
crate::macros::widget::impl_widget_base!(SimpleTerminal, Fl_Simple_Terminal);
crate::macros::widget::impl_widget_default!(SimpleTerminal);
crate::macros::display::impl_display_ext!(SimpleTerminal, Fl_Simple_Terminal);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
#[non_exhaustive]
pub enum TextAttr {
None = 0x0000,
BgColor = 0x0001,
BgColorExt = 0x0003,
Underline = 0x0004,
Grammar = 0x0008,
Spelling = 0x000C,
StrikeThrough = 0x0010,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StyleTableEntry {
pub color: Color,
pub font: Font,
pub size: i32,
}
impl Default for StyleTableEntry {
fn default() -> Self {
Self {
color: Color::Foreground,
font: Font::Helvetica,
size: crate::app::font_size(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StyleTableEntryExt {
pub color: Color,
pub font: Font,
pub size: i32,
pub attr: TextAttr,
pub bgcolor: Color,
}
impl Default for StyleTableEntryExt {
fn default() -> Self {
Self {
color: Color::Foreground,
font: Font::Helvetica,
size: crate::app::font_size(),
attr: TextAttr::None,
bgcolor: Color::Background2,
}
}
}
impl TextEditor {
pub const AnyState: crate::enums::Shortcut = crate::enums::Shortcut::from_i32(-1);
pub fn set_insert_mode(&mut self, b: bool) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Text_Editor_set_insert_mode(self.inner, b as i32) }
}
pub fn insert_mode(&self) -> bool {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Text_Editor_insert_mode(self.inner) != 0 }
}
pub fn set_tab_nav(&mut self, val: bool) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Text_Editor_set_tab_nav(self.inner, val as i32) }
}
pub fn tab_nav(&self) -> bool {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Text_Editor_tab_nav(self.inner) != 0 }
}
pub fn copy(&self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_copy(self.inner);
}
}
pub fn cut(&self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_cut(self.inner);
}
}
pub fn paste(&self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_paste(self.inner);
}
}
pub fn undo(&self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_undo(self.inner);
}
}
pub fn kf_default(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_default(c.bits(), self.inner);
}
}
pub fn kf_ignore(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_ignore(c.bits(), self.inner);
}
}
pub fn kf_backspace(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_backspace(self.inner);
}
}
pub fn kf_enter(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_enter(self.inner);
}
}
pub fn kf_move(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_move(c.bits(), self.inner);
}
}
pub fn kf_shift_move(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_shift_move(c.bits(), self.inner);
}
}
pub fn kf_ctrl_move(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_ctrl_move(c.bits(), self.inner);
}
}
pub fn kf_c_s_move(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_c_s_move(c.bits(), self.inner);
}
}
pub fn kf_meta_move(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_meta_move(c.bits(), self.inner);
}
}
pub fn kf_m_s_move(&mut self, c: Key) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_m_s_move(c.bits(), self.inner);
}
}
pub fn kf_home(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_home(self.inner);
}
}
pub fn kf_end(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_end(self.inner);
}
}
pub fn kf_left(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_left(self.inner);
}
}
pub fn kf_up(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_up(self.inner);
}
}
pub fn kf_right(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_right(self.inner);
}
}
pub fn kf_down(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_down(self.inner);
}
}
pub fn kf_page_up(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_page_up(self.inner);
}
}
pub fn kf_page_down(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_page_down(self.inner);
}
}
pub fn kf_insert(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_insert(self.inner);
}
}
pub fn kf_delete(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_delete(self.inner);
}
}
pub fn kf_select_all(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
Fl_Text_Editor_kf_select_all(self.inner);
}
}
pub fn add_key_binding(
&mut self,
key: crate::enums::Key,
shortcut: crate::enums::Shortcut,
cb: fn(key: crate::enums::Key, editor: TextEditorPtr) -> i32,
) {
assert!(!self.was_deleted());
unsafe {
Fl_Text_Editor_add_key_binding(
self.inner,
key.bits(),
shortcut.bits(),
std::mem::transmute(Some(cb)),
);
}
}
pub fn remove_key_binding(&mut self, key: crate::enums::Key, shortcut: crate::enums::Shortcut) {
assert!(!self.was_deleted());
unsafe {
Fl_Text_Editor_remove_key_binding(self.inner, key.bits(), shortcut.bits());
}
}
}
impl SimpleTerminal {
pub fn set_stay_at_bottom(&mut self, arg1: bool) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_set_stay_at_bottom(self.inner, arg1 as i32) }
}
pub fn stay_at_bottom(&self) -> bool {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_stay_at_bottom(self.inner) != 0 }
}
pub fn set_history_lines(&mut self, arg1: i32) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_set_history_lines(self.inner, arg1) }
}
pub fn history_lines(&self) -> i32 {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_history_lines(self.inner) }
}
pub fn set_ansi(&mut self, val: bool) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_set_ansi(self.inner, val as i32) }
}
pub fn ansi(&self) -> bool {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_ansi(self.inner) != 0 }
}
pub fn append(&mut self, s: &str) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
let s = CString::safe_new(s);
unsafe { Fl_Simple_Terminal_append(self.inner, s.into_raw() as _) }
}
pub fn append2(&mut self, s: &[u8]) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_append2(self.inner, s.as_ptr() as _, s.len() as _) }
}
pub fn set_text(&mut self, s: &str) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
let s = CString::safe_new(s);
unsafe { Fl_Simple_Terminal_set_text(self.inner, s.into_raw() as _) }
}
pub fn text(&self) -> String {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe {
let ptr = Fl_Simple_Terminal_text(self.inner);
assert!(!ptr.is_null());
CStr::from_ptr(ptr as *mut raw::c_char)
.to_string_lossy()
.to_string()
}
}
pub fn clear(&mut self) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_clear(self.inner) }
}
pub fn remove_lines(&mut self, start: i32, count: i32) {
assert!(!self.was_deleted());
assert!(self.buffer().is_some());
unsafe { Fl_Simple_Terminal_remove_lines(self.inner, start, count) }
}
}