mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-15 09:10:08 +00:00
separate components
This commit is contained in:
parent
965a89ffc0
commit
f8112a8d24
@ -1,9 +1,18 @@
|
|||||||
|
mod close;
|
||||||
|
mod entry;
|
||||||
|
mod match_case;
|
||||||
|
mod navigation;
|
||||||
|
mod tag;
|
||||||
|
|
||||||
|
use navigation::Navigation;
|
||||||
|
use tag::Tag;
|
||||||
|
|
||||||
use gtk::{
|
use gtk::{
|
||||||
gdk::{Cursor, RGBA},
|
|
||||||
prelude::{BoxExt, ButtonExt, CheckButtonExt, EditableExt, EntryExt, TextBufferExt, WidgetExt},
|
prelude::{BoxExt, ButtonExt, CheckButtonExt, EditableExt, EntryExt, TextBufferExt, WidgetExt},
|
||||||
Box, Button, CheckButton, Entry, EntryIconPosition, Orientation, TextBuffer, TextIter,
|
Box, Button, Entry, EntryIconPosition, Orientation, TextBuffer, TextIter, TextSearchFlags,
|
||||||
TextSearchFlags, TextTag,
|
TextTag,
|
||||||
};
|
};
|
||||||
|
use std::{cell::Cell, rc::Rc};
|
||||||
|
|
||||||
const MARGIN: i32 = 6;
|
const MARGIN: i32 = 6;
|
||||||
|
|
||||||
@ -16,65 +25,15 @@ pub struct Find {
|
|||||||
impl Find {
|
impl Find {
|
||||||
// Construct
|
// Construct
|
||||||
pub fn new(text_buffer: &TextBuffer) -> Self {
|
pub fn new(text_buffer: &TextBuffer) -> Self {
|
||||||
|
// Init shared matches holder
|
||||||
|
let matches = Rc::new(Cell::new(Vec::<(TextIter, TextIter)>::new()));
|
||||||
|
|
||||||
// Init components
|
// Init components
|
||||||
let close = Button::builder()
|
let close = close::new();
|
||||||
.cursor(&Cursor::from_name("default", None).unwrap())
|
let entry = entry::new();
|
||||||
.icon_name("window-close-symbolic")
|
let match_case = match_case::new();
|
||||||
.margin_bottom(MARGIN)
|
let navigation = Navigation::new();
|
||||||
.margin_end(MARGIN)
|
let tag = Tag::new(text_buffer.tag_table());
|
||||||
.margin_start(MARGIN)
|
|
||||||
.margin_top(MARGIN)
|
|
||||||
.tooltip_text("Close find bar")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let match_case = CheckButton::builder()
|
|
||||||
.cursor(&Cursor::from_name("default", None).unwrap())
|
|
||||||
.label("Match case")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let navigation = Box::builder()
|
|
||||||
.css_classes([
|
|
||||||
"linked", // merge childs
|
|
||||||
])
|
|
||||||
.margin_end(MARGIN)
|
|
||||||
.orientation(Orientation::Horizontal)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let back = Button::builder()
|
|
||||||
.icon_name("go-previous-symbolic")
|
|
||||||
.margin_bottom(MARGIN)
|
|
||||||
.margin_top(MARGIN)
|
|
||||||
.sensitive(false)
|
|
||||||
.tooltip_text("Back")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let forward = Button::builder()
|
|
||||||
.icon_name("go-next-symbolic")
|
|
||||||
.margin_bottom(MARGIN)
|
|
||||||
.margin_top(MARGIN)
|
|
||||||
.sensitive(false)
|
|
||||||
.tooltip_text("Forward")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
navigation.append(&back);
|
|
||||||
navigation.append(&forward);
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
let found_tag = TextTag::builder()
|
|
||||||
.background_rgba(&RGBA::new(0.502, 0.502, 0.502, 0.5)) // @TODO
|
|
||||||
.build();
|
|
||||||
text_buffer.tag_table().add(&found_tag);
|
|
||||||
|
|
||||||
// Init main container
|
// Init main container
|
||||||
let g_box = Box::builder()
|
let g_box = Box::builder()
|
||||||
@ -83,7 +42,7 @@ impl Find {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
g_box.append(&entry);
|
g_box.append(&entry);
|
||||||
g_box.append(&navigation);
|
g_box.append(&navigation.g_box);
|
||||||
g_box.append(&match_case);
|
g_box.append(&match_case);
|
||||||
g_box.append(&close);
|
g_box.append(&close);
|
||||||
|
|
||||||
@ -94,30 +53,34 @@ impl Find {
|
|||||||
});
|
});
|
||||||
|
|
||||||
entry.connect_changed({
|
entry.connect_changed({
|
||||||
|
let back = navigation.back.clone();
|
||||||
let entry = entry.clone();
|
let entry = entry.clone();
|
||||||
let found_tag = found_tag.clone();
|
let forward = navigation.forward.clone();
|
||||||
|
let found_tag = tag.found.clone();
|
||||||
let match_case = match_case.clone();
|
let match_case = match_case.clone();
|
||||||
|
let matches = matches.clone();
|
||||||
let text_buffer = text_buffer.clone();
|
let text_buffer = text_buffer.clone();
|
||||||
move |this| {
|
move |this| {
|
||||||
// toggle clear action
|
// toggle entry clear button
|
||||||
if this.text().is_empty() {
|
if this.text().is_empty() {
|
||||||
this.set_secondary_icon_name(None);
|
this.set_secondary_icon_name(None);
|
||||||
} else {
|
} else {
|
||||||
this.set_secondary_icon_name(Some("edit-clear-symbolic"));
|
this.set_secondary_icon_name(Some("edit-clear-symbolic"));
|
||||||
}
|
}
|
||||||
// apply changes
|
|
||||||
if find(
|
// do search
|
||||||
|
let result = find(
|
||||||
&text_buffer,
|
&text_buffer,
|
||||||
&found_tag,
|
&found_tag,
|
||||||
entry.text().as_str(),
|
entry.text().as_str(),
|
||||||
match_case.is_active(),
|
match_case.is_active(),
|
||||||
)
|
);
|
||||||
.is_empty()
|
|
||||||
{
|
// update components
|
||||||
entry.add_css_class("error");
|
update(&entry, &back, &forward, result.is_empty());
|
||||||
} else {
|
|
||||||
entry.remove_css_class("error");
|
// update matches index
|
||||||
}
|
matches.replace(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,21 +91,28 @@ impl Find {
|
|||||||
|
|
||||||
match_case.connect_toggled({
|
match_case.connect_toggled({
|
||||||
let entry = entry.clone();
|
let entry = entry.clone();
|
||||||
let found_tag = found_tag.clone();
|
let found_tag = tag.found.clone();
|
||||||
|
let matches = matches.clone();
|
||||||
let text_buffer = text_buffer.clone();
|
let text_buffer = text_buffer.clone();
|
||||||
move |this| {
|
move |this| {
|
||||||
if find(
|
// do search
|
||||||
|
let result = find(
|
||||||
&text_buffer,
|
&text_buffer,
|
||||||
&found_tag,
|
&found_tag,
|
||||||
entry.text().as_str(),
|
entry.text().as_str(),
|
||||||
this.is_active(),
|
this.is_active(),
|
||||||
)
|
);
|
||||||
.is_empty()
|
|
||||||
{
|
// update components
|
||||||
entry.add_css_class("error");
|
update(
|
||||||
} else {
|
&entry,
|
||||||
entry.remove_css_class("error");
|
&navigation.back,
|
||||||
}
|
&navigation.forward,
|
||||||
|
result.is_empty(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// update matches index
|
||||||
|
matches.replace(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -155,12 +125,14 @@ impl Find {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tools
|
||||||
|
|
||||||
fn find(
|
fn find(
|
||||||
text_buffer: &TextBuffer,
|
text_buffer: &TextBuffer,
|
||||||
found_tag: &TextTag,
|
found_tag: &TextTag,
|
||||||
subject: &str,
|
subject: &str,
|
||||||
is_match_case: bool,
|
is_match_case: bool,
|
||||||
) -> Vec<TextIter> {
|
) -> Vec<(TextIter, TextIter)> {
|
||||||
// Init start matches result
|
// Init start matches result
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
|
|
||||||
@ -182,8 +154,20 @@ fn find(
|
|||||||
None, // unlimited
|
None, // unlimited
|
||||||
) {
|
) {
|
||||||
text_buffer.apply_tag(found_tag, &start, &end);
|
text_buffer.apply_tag(found_tag, &start, &end);
|
||||||
result.push(start);
|
next = end.clone();
|
||||||
next = end;
|
result.push((start, end));
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update(entry: &Entry, back: &Button, forward: &Button, is_empty: bool) {
|
||||||
|
if is_empty {
|
||||||
|
entry.add_css_class("error");
|
||||||
|
back.set_sensitive(false);
|
||||||
|
forward.set_sensitive(false);
|
||||||
|
} else {
|
||||||
|
entry.remove_css_class("error");
|
||||||
|
back.set_sensitive(false);
|
||||||
|
forward.set_sensitive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
use super::MARGIN;
|
||||||
|
use gtk::{gdk::Cursor, Button};
|
||||||
|
|
||||||
|
pub fn new() -> Button {
|
||||||
|
Button::builder()
|
||||||
|
.cursor(&Cursor::from_name("default", None).unwrap())
|
||||||
|
.icon_name("window-close-symbolic")
|
||||||
|
.margin_bottom(MARGIN)
|
||||||
|
.margin_end(MARGIN)
|
||||||
|
.margin_start(MARGIN)
|
||||||
|
.margin_top(MARGIN)
|
||||||
|
.tooltip_text("Close find bar")
|
||||||
|
.build()
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
use super::MARGIN;
|
||||||
|
use gtk::Entry;
|
||||||
|
|
||||||
|
pub fn new() -> 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()
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
use gtk::{gdk::Cursor, CheckButton};
|
||||||
|
|
||||||
|
pub fn new() -> CheckButton {
|
||||||
|
CheckButton::builder()
|
||||||
|
.cursor(&Cursor::from_name("default", None).unwrap())
|
||||||
|
.label("Match case")
|
||||||
|
.build()
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
mod back;
|
||||||
|
mod forward;
|
||||||
|
|
||||||
|
use super::MARGIN;
|
||||||
|
use gtk::{prelude::BoxExt, Box, Button, Orientation};
|
||||||
|
|
||||||
|
pub struct Navigation {
|
||||||
|
pub back: Button,
|
||||||
|
pub forward: Button,
|
||||||
|
pub g_box: Box,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Navigation {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
/// Create new `Self`
|
||||||
|
pub fn new() -> Self {
|
||||||
|
// Init components
|
||||||
|
let back = back::new();
|
||||||
|
let forward = forward::new();
|
||||||
|
|
||||||
|
// Init main container
|
||||||
|
let g_box = Box::builder()
|
||||||
|
.css_classes([
|
||||||
|
"linked", // merge childs
|
||||||
|
])
|
||||||
|
.margin_end(MARGIN)
|
||||||
|
.orientation(Orientation::Horizontal)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
g_box.append(&back);
|
||||||
|
g_box.append(&forward);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
back,
|
||||||
|
forward,
|
||||||
|
g_box,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
use super::MARGIN;
|
||||||
|
use gtk::Button;
|
||||||
|
|
||||||
|
pub fn new() -> Button {
|
||||||
|
Button::builder()
|
||||||
|
.icon_name("go-previous-symbolic")
|
||||||
|
.margin_bottom(MARGIN)
|
||||||
|
.margin_top(MARGIN)
|
||||||
|
.sensitive(false)
|
||||||
|
.tooltip_text("Back")
|
||||||
|
.build()
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
use super::MARGIN;
|
||||||
|
use gtk::Button;
|
||||||
|
|
||||||
|
pub fn new() -> Button {
|
||||||
|
Button::builder()
|
||||||
|
.icon_name("go-next-symbolic")
|
||||||
|
.margin_bottom(MARGIN)
|
||||||
|
.margin_top(MARGIN)
|
||||||
|
.sensitive(false)
|
||||||
|
.tooltip_text("Forward")
|
||||||
|
.build()
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
mod current;
|
||||||
|
mod found;
|
||||||
|
|
||||||
|
use gtk::{TextTag, TextTagTable};
|
||||||
|
|
||||||
|
pub struct Tag {
|
||||||
|
// pub current: TextTag,
|
||||||
|
pub found: TextTag,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tag {
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
pub fn new(tag_table: TextTagTable) -> Self {
|
||||||
|
// Init components
|
||||||
|
let current = current::new();
|
||||||
|
let found = found::new();
|
||||||
|
|
||||||
|
// Init `Self`
|
||||||
|
tag_table.add(¤t);
|
||||||
|
tag_table.add(&found);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
/*current,*/ found,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
use gtk::{gdk::RGBA, TextTag};
|
||||||
|
|
||||||
|
pub fn new() -> TextTag {
|
||||||
|
TextTag::builder()
|
||||||
|
.background_rgba(&RGBA::new(0.502, 0.502, 0.502, 0.5)) // @TODO
|
||||||
|
.build()
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
use gtk::{gdk::RGBA, TextTag};
|
||||||
|
|
||||||
|
pub fn new() -> TextTag {
|
||||||
|
TextTag::builder()
|
||||||
|
.background_rgba(&RGBA::new(0.502, 0.502, 0.502, 0.5)) // @TODO
|
||||||
|
.build()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user