use super::*;
unsafe fn style_dialog_layout(dialog: *mut gtk_sys::GtkWidget) {
let content = gtk_sys::gtk_dialog_get_content_area(dialog as *mut gtk_sys::GtkDialog);
gtk_sys::gtk_box_set_spacing(content as *mut gtk_sys::GtkBox, 10);
gtk_sys::gtk_container_set_border_width(content as *mut gtk_sys::GtkContainer, 14);
}
pub fn text_input(p: &TextInput<'_>) -> Option<String> {
match p.mode {
TextInputMode::SingleLine => text_input_entry(p, false),
TextInputMode::MultiLine => text_input_multiline(p),
TextInputMode::Password => text_input_entry(p, true),
}
}
fn text_input_entry(p: &TextInput<'_>, password: bool) -> Option<String> {
ensure_gtk_initialized();
let dialog = unsafe { gtk_sys::gtk_dialog_new() };
let title = cstring(p.title);
let message = cstring(p.message);
let value = cstring(p.value);
let ok = c"OK";
let cancel = c"Cancel";
unsafe {
gtk_sys::gtk_window_set_title(dialog as *mut gtk_sys::GtkWindow, title.as_ptr());
gtk_sys::gtk_window_set_default_size(dialog as *mut gtk_sys::GtkWindow, 520, -1);
gtk_sys::gtk_dialog_add_button(dialog as *mut gtk_sys::GtkDialog, cancel.as_ptr(), gtk_sys::GTK_RESPONSE_CANCEL);
gtk_sys::gtk_dialog_add_button(dialog as *mut gtk_sys::GtkDialog, ok.as_ptr(), gtk_sys::GTK_RESPONSE_OK);
gtk_sys::gtk_dialog_set_default_response(dialog as *mut gtk_sys::GtkDialog, gtk_sys::GTK_RESPONSE_OK);
let content = gtk_sys::gtk_dialog_get_content_area(dialog as *mut gtk_sys::GtkDialog);
style_dialog_layout(dialog);
let label = gtk_sys::gtk_label_new(message.as_ptr());
gtk_sys::gtk_label_set_xalign(label as *mut gtk_sys::GtkLabel, 0.0);
let entry = gtk_sys::gtk_entry_new();
gtk_sys::gtk_entry_set_text(entry as *mut gtk_sys::GtkEntry, value.as_ptr());
gtk_sys::gtk_entry_set_activates_default(entry as *mut gtk_sys::GtkEntry, 1);
if password {
gtk_sys::gtk_entry_set_visibility(entry as *mut gtk_sys::GtkEntry, 0);
}
gtk_sys::gtk_box_pack_start(content as *mut gtk_sys::GtkBox, label, 0, 0, 0);
gtk_sys::gtk_box_pack_start(content as *mut gtk_sys::GtkBox, entry, 0, 0, 0);
gtk_sys::gtk_widget_show_all(dialog);
let response = gtk_sys::gtk_dialog_run(dialog as *mut gtk_sys::GtkDialog);
let result = if response == gtk_sys::GTK_RESPONSE_OK {
let text_ptr = gtk_sys::gtk_entry_get_text(entry as *mut gtk_sys::GtkEntry);
if text_ptr.is_null() {
None
} else {
Some(CStr::from_ptr(text_ptr).to_string_lossy().to_string())
}
} else {
None
};
gtk_sys::gtk_widget_destroy(dialog);
while gtk_sys::gtk_events_pending() != 0 {
gtk_sys::gtk_main_iteration();
}
result
}
}
fn text_input_multiline(p: &TextInput<'_>) -> Option<String> {
ensure_gtk_initialized();
let dialog = unsafe { gtk_sys::gtk_dialog_new() };
let title = cstring(p.title);
let message = cstring(p.message);
let value = cstring(p.value);
let ok = c"OK";
let cancel = c"Cancel";
unsafe {
gtk_sys::gtk_window_set_title(dialog as *mut gtk_sys::GtkWindow, title.as_ptr());
gtk_sys::gtk_window_set_default_size(dialog as *mut gtk_sys::GtkWindow, 500, 380);
gtk_sys::gtk_dialog_add_button(dialog as *mut gtk_sys::GtkDialog, cancel.as_ptr(), gtk_sys::GTK_RESPONSE_CANCEL);
gtk_sys::gtk_dialog_add_button(dialog as *mut gtk_sys::GtkDialog, ok.as_ptr(), gtk_sys::GTK_RESPONSE_OK);
let content = gtk_sys::gtk_dialog_get_content_area(dialog as *mut gtk_sys::GtkDialog);
style_dialog_layout(dialog);
let label = gtk_sys::gtk_label_new(message.as_ptr());
gtk_sys::gtk_label_set_xalign(label as *mut gtk_sys::GtkLabel, 0.0);
let scrolled = gtk_sys::gtk_scrolled_window_new(ptr::null_mut(), ptr::null_mut());
let text_view = gtk_sys::gtk_text_view_new();
let buffer = gtk_sys::gtk_text_view_get_buffer(text_view as *mut gtk_sys::GtkTextView);
gtk_sys::gtk_text_buffer_set_text(buffer, value.as_ptr(), -1);
gtk_sys::gtk_widget_set_size_request(scrolled, 480, 280);
gtk_sys::gtk_container_add(scrolled as *mut gtk_sys::GtkContainer, text_view);
gtk_sys::gtk_box_pack_start(content as *mut gtk_sys::GtkBox, label, 0, 0, 0);
gtk_sys::gtk_box_pack_start(content as *mut gtk_sys::GtkBox, scrolled, 1, 1, 0);
gtk_sys::gtk_widget_show_all(dialog);
let response = gtk_sys::gtk_dialog_run(dialog as *mut gtk_sys::GtkDialog);
let result = if response == gtk_sys::GTK_RESPONSE_OK {
let mut start = std::mem::zeroed();
let mut end = std::mem::zeroed();
gtk_sys::gtk_text_buffer_get_bounds(buffer, &mut start, &mut end);
let text_ptr = gtk_sys::gtk_text_buffer_get_text(buffer, &mut start, &mut end, 0);
if text_ptr.is_null() {
None
} else {
let text = CStr::from_ptr(text_ptr).to_string_lossy().to_string();
glib_sys::g_free(text_ptr as *mut _);
Some(text)
}
} else {
None
};
gtk_sys::gtk_widget_destroy(dialog);
while gtk_sys::gtk_events_pending() != 0 {
gtk_sys::gtk_main_iteration();
}
result
}
}