|
|
@ -3,11 +3,10 @@ mod database; |
|
|
|
use database::Database; |
|
|
|
use database::Database; |
|
|
|
|
|
|
|
|
|
|
|
use gtk::{ |
|
|
|
use gtk::{ |
|
|
|
gdk::BUTTON_PRIMARY, |
|
|
|
|
|
|
|
gio::SimpleAction, |
|
|
|
gio::SimpleAction, |
|
|
|
glib::{timeout_add_local, ControlFlow, GString, SourceId}, |
|
|
|
glib::{timeout_add_local, ControlFlow, GString, SourceId}, |
|
|
|
prelude::{ActionExt, EditableExt, EntryExt, ToVariant, WidgetExt}, |
|
|
|
prelude::{ActionExt, EditableExt, EntryExt, ToVariant, WidgetExt}, |
|
|
|
Entry, GestureClick, |
|
|
|
Entry, StateFlags, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use sqlite::Transaction; |
|
|
|
use sqlite::Transaction; |
|
|
|
use std::{cell::RefCell, sync::Arc, time::Duration}; |
|
|
|
use std::{cell::RefCell, sync::Arc, time::Duration}; |
|
|
@ -40,20 +39,12 @@ impl Widget { |
|
|
|
source_id: RefCell::new(None), |
|
|
|
source_id: RefCell::new(None), |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Init additional controllers
|
|
|
|
|
|
|
|
let primary_button_controller = GestureClick::builder().button(BUTTON_PRIMARY).build(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Init widget
|
|
|
|
// Init widget
|
|
|
|
let gobject = Entry::builder() |
|
|
|
let gobject = Entry::builder() |
|
|
|
.placeholder_text(PLACEHOLDER_TEXT) |
|
|
|
.placeholder_text(PLACEHOLDER_TEXT) |
|
|
|
.hexpand(true) |
|
|
|
.hexpand(true) |
|
|
|
.build(); |
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
gobject |
|
|
|
|
|
|
|
.first_child() |
|
|
|
|
|
|
|
.unwrap() // text widget should be there
|
|
|
|
|
|
|
|
.add_controller(primary_button_controller.clone()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Connect events
|
|
|
|
// Connect events
|
|
|
|
gobject.connect_changed(move |_| { |
|
|
|
gobject.connect_changed(move |_| { |
|
|
|
action_update.activate(Some(&"".to_variant())); // @TODO
|
|
|
|
action_update.activate(Some(&"".to_variant())); // @TODO
|
|
|
@ -63,20 +54,17 @@ impl Widget { |
|
|
|
action_page_reload.activate(None); |
|
|
|
action_page_reload.activate(None); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
primary_button_controller.connect_pressed({ |
|
|
|
gobject.connect_state_flags_changed(|this, state| { |
|
|
|
let gobject = gobject.clone(); |
|
|
|
// Select entire text on key release
|
|
|
|
move |_, _, _, _| { |
|
|
|
|
|
|
|
let gobject = gobject.clone(); |
|
|
|
|
|
|
|
// Select entire text on first focus at entry
|
|
|
|
|
|
|
|
// this behavior implemented in most web-browsers,
|
|
|
|
// this behavior implemented in most web-browsers,
|
|
|
|
// to simply overwrite current request with new value
|
|
|
|
// to simply overwrite current request with new value
|
|
|
|
if !gobject.first_child().unwrap().has_focus() { |
|
|
|
// Note:
|
|
|
|
// Small trick to overwrite default GTK behavior
|
|
|
|
// * Custom GestureClick is not option here, as GTK Entry already has default one
|
|
|
|
// @TODO find another way to prevent defaults but with timeout
|
|
|
|
println!("{:?}", state); |
|
|
|
timeout_add_local(Duration::from_millis(100), move || { |
|
|
|
if state.contains(StateFlags::ACTIVE) && state.contains(StateFlags::FOCUS_WITHIN) { |
|
|
|
gobject.select_region(0, gobject.text_length().into()); |
|
|
|
// Continue on first focus event
|
|
|
|
ControlFlow::Break |
|
|
|
if this.selection_bounds().is_none() { |
|
|
|
}); |
|
|
|
this.select_region(0, this.text_length().into()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|