From 58140ab3350c3c6980a0ca64fa0318b1727887f1 Mon Sep 17 00:00:00 2001 From: yggverse Date: Tue, 17 Dec 2024 06:50:59 +0200 Subject: [PATCH] implement infinitive search iter --- .../window/tab/item/page/search/form.rs | 16 ++-- .../tab/item/page/search/form/navigation.rs | 92 ++++++------------- .../item/page/search/form/navigation/iter.rs | 45 +++++++++ 3 files changed, 78 insertions(+), 75 deletions(-) create mode 100644 src/app/browser/window/tab/item/page/search/form/navigation/iter.rs diff --git a/src/app/browser/window/tab/item/page/search/form.rs b/src/app/browser/window/tab/item/page/search/form.rs index 1e670783..5f63bf90 100644 --- a/src/app/browser/window/tab/item/page/search/form.rs +++ b/src/app/browser/window/tab/item/page/search/form.rs @@ -48,12 +48,13 @@ impl Form { let navigation = navigation.clone(); let subject = subject.clone(); move |_| { - navigation.update(find( + let matches = find( &subject, input.entry.text().as_str(), match_case.is_active(), - )); - input.update(navigation.is_match()); + ); + input.update(!matches.is_empty()); + navigation.update(matches); } }); @@ -62,12 +63,9 @@ impl Form { let navigation = navigation.clone(); let subject = subject.clone(); move |this| { - navigation.update(find( - &subject, - input.entry.text().as_str(), - this.is_active(), - )); - input.update(navigation.is_match()); + let matches = find(&subject, input.entry.text().as_str(), this.is_active()); + input.update(!matches.is_empty()); + navigation.update(matches); } }); diff --git a/src/app/browser/window/tab/item/page/search/form/navigation.rs b/src/app/browser/window/tab/item/page/search/form/navigation.rs index 7d500c0a..6ae379e0 100644 --- a/src/app/browser/window/tab/item/page/search/form/navigation.rs +++ b/src/app/browser/window/tab/item/page/search/form/navigation.rs @@ -1,18 +1,17 @@ mod back; mod forward; +mod iter; use back::Back; use forward::Forward; +use iter::Iter; use super::Subject; use gtk::{ prelude::{BoxExt, TextBufferExt, TextViewExt}, Box, Orientation, TextIter, }; -use std::{ - cell::{Cell, RefCell}, - rc::Rc, -}; +use std::cell::RefCell; const MARGIN: i32 = 6; @@ -20,8 +19,7 @@ pub struct Navigation { pub back: Back, pub forward: Forward, pub g_box: Box, - index: Rc>, - matches: Rc>>, + iter: RefCell>, } impl Navigation { @@ -29,10 +27,6 @@ impl Navigation { /// Create new `Self` pub fn new() -> Self { - // Init shared matches holder - let index = Rc::new(Cell::new(0)); - let matches = Rc::new(RefCell::new(Vec::new())); - // Init components let back = Back::new(); let forward = Forward::new(); @@ -53,21 +47,16 @@ impl Navigation { back, forward, g_box, - index, - matches, + iter: RefCell::new(None), } } // Actions pub fn update(&self, matches: Vec<(TextIter, TextIter)>) { - // Update self - self.matches.replace(matches); - self.index.replace(0); // reset - - // Update child components - self.back.update(self.is_match()); - self.forward.update(self.is_match()); + self.back.update(!matches.is_empty()); + self.forward.update(!matches.is_empty()); + self.iter.replace(Some(Iter::new(matches))); } pub fn back(&self, subject: &Subject) -> Option<(TextIter, TextIter)> { @@ -79,23 +68,15 @@ impl Navigation { &buffer.end_iter(), ); - let index = self.index.take(); - - match self.matches.borrow().get(back(index)) { - Some((start, end)) => { - buffer.apply_tag(&subject.tag.current, start, end); - self.index.replace(if index == 0 { - len_to_index(self.matches.borrow().len()) - } else { - index - }); - Some((*start, *end)) - } - None => { - self.index - .replace(len_to_index(self.matches.borrow().len())); // go last - None - } + match self.iter.borrow_mut().as_mut() { + Some(iter) => match iter.back() { + Some((start, end)) => { + buffer.apply_tag(&subject.tag.current, &start, &end); + Some((start, end)) + } + None => iter.reset(), + }, + None => todo!(), } } @@ -108,36 +89,15 @@ impl Navigation { &buffer.end_iter(), ); - let index = self.index.take(); - let next = forward(index); - match self.matches.borrow().get(next) { - Some((start, end)) => { - buffer.apply_tag(&subject.tag.current, start, end); - self.index.replace(next); - Some((*start, *end)) - } - None => { - self.index.replace(0); - None - } + match self.iter.borrow_mut().as_mut() { + Some(iter) => match iter.forward() { + Some((start, end)) => { + buffer.apply_tag(&subject.tag.current, &start, &end); + Some((start, end)) + } + None => iter.reset(), + }, + None => todo!(), } } - - // Getters - - pub fn is_match(&self) -> bool { - !self.matches.borrow().is_empty() - } -} - -fn back(index: usize) -> usize { - index - 1 -} - -fn forward(index: usize) -> usize { - index + 1 -} - -fn len_to_index(len: usize) -> usize { - len - 1 } diff --git a/src/app/browser/window/tab/item/page/search/form/navigation/iter.rs b/src/app/browser/window/tab/item/page/search/form/navigation/iter.rs new file mode 100644 index 00000000..28359746 --- /dev/null +++ b/src/app/browser/window/tab/item/page/search/form/navigation/iter.rs @@ -0,0 +1,45 @@ +use gtk::TextIter; + +pub struct Iter { + value: Vec<(TextIter, TextIter)>, + index: Option, +} + +impl Iter { + pub fn new(value: Vec<(TextIter, TextIter)>) -> Self { + Self { index: None, value } + } + + pub fn back(&mut self) -> Option<(TextIter, TextIter)> { + self.index = match self.index { + Some(index) => { + if index > 0 { + Some(index - 1) + } else { + Some(self.value.len()) + } + } + None => Some(self.value.len()), // init + }; + self.value.get(self.index.unwrap_or_default()).copied() + } + + pub fn forward(&mut self) -> Option<(TextIter, TextIter)> { + self.index = match self.index { + Some(index) => { + if index < self.value.len() { + Some(index + 1) + } else { + Some(0) + } + } + None => Some(0), // init + }; + self.value.get(self.index.unwrap_or_default()).copied() + } + + pub fn reset(&mut self) -> Option<(TextIter, TextIter)> { + self.index = None; + self.forward() + } +}