mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-15 09:10:08 +00:00
implement self update
This commit is contained in:
parent
24160d39eb
commit
b3e64a485b
@ -52,7 +52,7 @@ impl Widget {
|
|||||||
let text_view = text_view.clone();
|
let text_view = text_view.clone();
|
||||||
move |_| {
|
move |_| {
|
||||||
text_view.set_gutter(TextWindowType::Bottom, Some(&find.g_box));
|
text_view.set_gutter(TextWindowType::Bottom, Some(&find.g_box));
|
||||||
find.entry.grab_focus();
|
find.input.entry.grab_focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
mod close;
|
mod close;
|
||||||
mod entry;
|
mod input;
|
||||||
mod match_case;
|
mod match_case;
|
||||||
mod navigation;
|
mod navigation;
|
||||||
mod tag;
|
mod tag;
|
||||||
|
|
||||||
|
use input::Input;
|
||||||
use navigation::Navigation;
|
use navigation::Navigation;
|
||||||
use tag::Tag;
|
use tag::Tag;
|
||||||
|
|
||||||
use gtk::{
|
use gtk::{
|
||||||
prelude::{BoxExt, ButtonExt, CheckButtonExt, EditableExt, TextBufferExt, WidgetExt},
|
prelude::{BoxExt, ButtonExt, CheckButtonExt, EditableExt, TextBufferExt},
|
||||||
Box, Button, Entry, Orientation, TextBuffer, TextIter, TextSearchFlags, TextTag,
|
Box, Button, Orientation, TextBuffer, TextIter, TextSearchFlags, TextTag,
|
||||||
};
|
};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct Find {
|
pub struct Find {
|
||||||
pub close: Button,
|
pub close: Button,
|
||||||
pub entry: Entry,
|
pub input: Rc<Input>,
|
||||||
pub g_box: Box,
|
pub g_box: Box,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ impl Find {
|
|||||||
pub fn new(text_buffer: &TextBuffer) -> Self {
|
pub fn new(text_buffer: &TextBuffer) -> Self {
|
||||||
// Init components
|
// Init components
|
||||||
let close = close::new();
|
let close = close::new();
|
||||||
let entry = entry::new();
|
let input = Rc::new(Input::new());
|
||||||
let match_case = match_case::new();
|
let match_case = match_case::new();
|
||||||
let navigation = Rc::new(Navigation::new());
|
let navigation = Rc::new(Navigation::new());
|
||||||
let tag = Rc::new(Tag::new(text_buffer.tag_table()));
|
let tag = Rc::new(Tag::new(text_buffer.tag_table()));
|
||||||
@ -35,19 +36,19 @@ impl Find {
|
|||||||
.orientation(Orientation::Horizontal)
|
.orientation(Orientation::Horizontal)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
g_box.append(&entry);
|
g_box.append(&input.entry);
|
||||||
g_box.append(&navigation.g_box);
|
g_box.append(&navigation.g_box);
|
||||||
g_box.append(&match_case);
|
g_box.append(&match_case);
|
||||||
g_box.append(&close);
|
g_box.append(&close);
|
||||||
|
|
||||||
// Connect events
|
// Connect events
|
||||||
close.connect_clicked({
|
close.connect_clicked({
|
||||||
let entry = entry.clone();
|
let input = input.clone();
|
||||||
move |_| entry.delete_text(0, -1)
|
move |_| input.clean()
|
||||||
});
|
});
|
||||||
|
|
||||||
entry.connect_changed({
|
input.entry.connect_changed({
|
||||||
let entry = entry.clone();
|
let input = input.clone();
|
||||||
let match_case = match_case.clone();
|
let match_case = match_case.clone();
|
||||||
let navigation = navigation.clone();
|
let navigation = navigation.clone();
|
||||||
let tag = tag.clone();
|
let tag = tag.clone();
|
||||||
@ -56,15 +57,15 @@ impl Find {
|
|||||||
navigation.update(find(
|
navigation.update(find(
|
||||||
&text_buffer,
|
&text_buffer,
|
||||||
&tag.found,
|
&tag.found,
|
||||||
entry.text().as_str(),
|
input.entry.text().as_str(),
|
||||||
match_case.is_active(),
|
match_case.is_active(),
|
||||||
));
|
));
|
||||||
update(&entry, &navigation);
|
input.update(navigation.is_match());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
match_case.connect_toggled({
|
match_case.connect_toggled({
|
||||||
let entry = entry.clone();
|
let input = input.clone();
|
||||||
let navigation = navigation.clone();
|
let navigation = navigation.clone();
|
||||||
let tag = tag.clone();
|
let tag = tag.clone();
|
||||||
let text_buffer = text_buffer.clone();
|
let text_buffer = text_buffer.clone();
|
||||||
@ -72,17 +73,17 @@ impl Find {
|
|||||||
navigation.update(find(
|
navigation.update(find(
|
||||||
&text_buffer,
|
&text_buffer,
|
||||||
&tag.found,
|
&tag.found,
|
||||||
entry.text().as_str(),
|
input.entry.text().as_str(),
|
||||||
this.is_active(),
|
this.is_active(),
|
||||||
));
|
));
|
||||||
update(&entry, &navigation);
|
input.update(navigation.is_match());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
Self {
|
Self {
|
||||||
close,
|
close,
|
||||||
entry,
|
input,
|
||||||
g_box,
|
g_box,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,15 +123,3 @@ fn find(
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(entry: &Entry, navigation: &Rc<Navigation>) {
|
|
||||||
if navigation.matches.borrow().is_empty() {
|
|
||||||
entry.add_css_class("error");
|
|
||||||
navigation.back.set_sensitive(false);
|
|
||||||
navigation.forward.set_sensitive(false);
|
|
||||||
} else {
|
|
||||||
entry.remove_css_class("error");
|
|
||||||
navigation.back.set_sensitive(false);
|
|
||||||
navigation.forward.set_sensitive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
use gtk::{
|
|
||||||
prelude::{EditableExt, EntryExt},
|
|
||||||
Entry, EntryIconPosition,
|
|
||||||
};
|
|
||||||
|
|
||||||
const MARGIN: i32 = 6;
|
|
||||||
|
|
||||||
pub fn new() -> Entry {
|
|
||||||
// Init widget
|
|
||||||
let entry = Entry::builder()
|
|
||||||
.hexpand(true)
|
|
||||||
.margin_bottom(MARGIN)
|
|
||||||
.margin_end(MARGIN)
|
|
||||||
.margin_start(MARGIN)
|
|
||||||
.margin_top(MARGIN)
|
|
||||||
.placeholder_text("Find in text..")
|
|
||||||
.primary_icon_activatable(false)
|
|
||||||
.primary_icon_sensitive(false)
|
|
||||||
.primary_icon_name("system-search-symbolic")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Connect events
|
|
||||||
entry.connect_icon_release(|this, position| match position {
|
|
||||||
EntryIconPosition::Secondary => this.delete_text(0, -1),
|
|
||||||
_ => todo!(), // unexpected
|
|
||||||
});
|
|
||||||
|
|
||||||
entry.connect_changed(|this| {
|
|
||||||
// toggle entry clear button
|
|
||||||
if this.text().is_empty() {
|
|
||||||
this.set_secondary_icon_name(None);
|
|
||||||
} else {
|
|
||||||
this.set_secondary_icon_name(Some("edit-clear-symbolic"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Done
|
|
||||||
entry
|
|
||||||
}
|
|
@ -0,0 +1,66 @@
|
|||||||
|
use gtk::{
|
||||||
|
prelude::{EditableExt, EntryExt, WidgetExt},
|
||||||
|
Entry, EntryIconPosition,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARGIN: i32 = 6;
|
||||||
|
|
||||||
|
pub struct Input {
|
||||||
|
pub entry: Entry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
/// Create new `Self`
|
||||||
|
pub fn new() -> Self {
|
||||||
|
// Init widget
|
||||||
|
let entry = Entry::builder()
|
||||||
|
.hexpand(true)
|
||||||
|
.margin_bottom(MARGIN)
|
||||||
|
.margin_end(MARGIN)
|
||||||
|
.margin_start(MARGIN)
|
||||||
|
.margin_top(MARGIN)
|
||||||
|
.placeholder_text("Find in text..")
|
||||||
|
.primary_icon_activatable(false)
|
||||||
|
.primary_icon_sensitive(false)
|
||||||
|
.primary_icon_name("system-search-symbolic")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Connect events
|
||||||
|
entry.connect_icon_release(|this, position| match position {
|
||||||
|
EntryIconPosition::Secondary => clean(this),
|
||||||
|
_ => todo!(), // unexpected
|
||||||
|
});
|
||||||
|
|
||||||
|
entry.connect_changed(|this| {
|
||||||
|
// toggle entry clear button
|
||||||
|
if this.text().is_empty() {
|
||||||
|
this.set_secondary_icon_name(None);
|
||||||
|
} else {
|
||||||
|
this.set_secondary_icon_name(Some("edit-clear-symbolic"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Done
|
||||||
|
Self { entry }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
pub fn clean(&self) {
|
||||||
|
clean(&self.entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&self, is_match: bool) {
|
||||||
|
if is_match {
|
||||||
|
self.entry.remove_css_class("error");
|
||||||
|
} else {
|
||||||
|
self.entry.add_css_class("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clean(entry: &Entry) {
|
||||||
|
entry.delete_text(0, -1)
|
||||||
|
}
|
@ -1,16 +1,19 @@
|
|||||||
mod back;
|
mod back;
|
||||||
mod forward;
|
mod forward;
|
||||||
|
|
||||||
use gtk::{prelude::BoxExt, Box, Button, Orientation, TextIter};
|
use back::Back;
|
||||||
|
use forward::Forward;
|
||||||
|
|
||||||
|
use gtk::{prelude::BoxExt, Box, Orientation, TextIter};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
const MARGIN: i32 = 6;
|
const MARGIN: i32 = 6;
|
||||||
|
|
||||||
pub struct Navigation {
|
pub struct Navigation {
|
||||||
pub back: Button,
|
pub back: Back,
|
||||||
pub forward: Button,
|
pub forward: Forward,
|
||||||
pub g_box: Box,
|
pub g_box: Box,
|
||||||
pub matches: Rc<RefCell<Vec<(TextIter, TextIter)>>>,
|
matches: Rc<RefCell<Vec<(TextIter, TextIter)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Navigation {
|
impl Navigation {
|
||||||
@ -22,8 +25,8 @@ impl Navigation {
|
|||||||
let matches = Rc::new(RefCell::new(Vec::new()));
|
let matches = Rc::new(RefCell::new(Vec::new()));
|
||||||
|
|
||||||
// Init components
|
// Init components
|
||||||
let back = back::new();
|
let back = Back::new();
|
||||||
let forward = forward::new();
|
let forward = Forward::new();
|
||||||
|
|
||||||
// Init main container
|
// Init main container
|
||||||
let g_box = Box::builder()
|
let g_box = Box::builder()
|
||||||
@ -34,8 +37,8 @@ impl Navigation {
|
|||||||
.orientation(Orientation::Horizontal)
|
.orientation(Orientation::Horizontal)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
g_box.append(&back);
|
g_box.append(&back.button);
|
||||||
g_box.append(&forward);
|
g_box.append(&forward.button);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
back,
|
back,
|
||||||
@ -45,7 +48,24 @@ impl Navigation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
pub fn update(&self, matches: Vec<(TextIter, TextIter)>) {
|
pub fn update(&self, matches: Vec<(TextIter, TextIter)>) {
|
||||||
|
// Update self
|
||||||
self.matches.replace(matches);
|
self.matches.replace(matches);
|
||||||
|
|
||||||
|
// Update child components
|
||||||
|
self.back.update(self.is_match());
|
||||||
|
self.forward.update(self.is_match());
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn back(&self) {}
|
||||||
|
|
||||||
|
// pub fn forward(&self) {}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
pub fn is_match(&self) -> bool {
|
||||||
|
!self.matches.borrow().is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,31 @@
|
|||||||
use super::MARGIN;
|
use gtk::{gdk::Cursor, prelude::WidgetExt, Button};
|
||||||
use gtk::{gdk::Cursor, Button};
|
|
||||||
|
|
||||||
pub fn new() -> Button {
|
const MARGIN: i32 = 6;
|
||||||
Button::builder()
|
|
||||||
.cursor(&Cursor::from_name("default", None).unwrap())
|
pub struct Back {
|
||||||
.icon_name("go-previous-symbolic")
|
pub button: Button,
|
||||||
.margin_bottom(MARGIN)
|
}
|
||||||
.margin_top(MARGIN)
|
|
||||||
.sensitive(false)
|
impl Back {
|
||||||
.tooltip_text("Back")
|
// Constructors
|
||||||
.build()
|
|
||||||
|
/// Create new `Self`
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
button: Button::builder()
|
||||||
|
.cursor(&Cursor::from_name("default", None).unwrap())
|
||||||
|
.icon_name("go-previous-symbolic")
|
||||||
|
.margin_bottom(MARGIN)
|
||||||
|
.margin_top(MARGIN)
|
||||||
|
.sensitive(false)
|
||||||
|
.tooltip_text("Back")
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
pub fn update(&self, is_sensitive: bool) {
|
||||||
|
self.button.set_sensitive(is_sensitive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,31 @@
|
|||||||
use super::MARGIN;
|
use gtk::{gdk::Cursor, prelude::WidgetExt, Button};
|
||||||
use gtk::{gdk::Cursor, Button};
|
|
||||||
|
|
||||||
pub fn new() -> Button {
|
const MARGIN: i32 = 6;
|
||||||
Button::builder()
|
|
||||||
.cursor(&Cursor::from_name("default", None).unwrap())
|
pub struct Forward {
|
||||||
.icon_name("go-next-symbolic")
|
pub button: Button,
|
||||||
.margin_bottom(MARGIN)
|
}
|
||||||
.margin_top(MARGIN)
|
|
||||||
.sensitive(false)
|
impl Forward {
|
||||||
.tooltip_text("Forward")
|
// Constructors
|
||||||
.build()
|
|
||||||
|
/// Create new `Self`
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
button: Button::builder()
|
||||||
|
.cursor(&Cursor::from_name("default", None).unwrap())
|
||||||
|
.icon_name("go-next-symbolic")
|
||||||
|
.margin_bottom(MARGIN)
|
||||||
|
.margin_top(MARGIN)
|
||||||
|
.sensitive(false)
|
||||||
|
.tooltip_text("Forward")
|
||||||
|
.build(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
|
||||||
|
pub fn update(&self, is_sensitive: bool) {
|
||||||
|
self.button.set_sensitive(is_sensitive);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user