Skip to content

Commit fd6eba4

Browse files
committed
complete search ui
1 parent 5570675 commit fd6eba4

File tree

4 files changed

+84
-21
lines changed

4 files changed

+84
-21
lines changed

asm_egui/src/top_bar.rs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::app::EguiApp;
22
use egui::containers::PopupCloseBehavior;
3-
use egui::{popup_below_widget, Context, Ui};
3+
use egui::{popup_below_widget, Context, Id, Response, TextEdit, Ui};
44
use java_asm_server::AsmServer;
55
use std::ops::Deref;
66

@@ -38,16 +38,23 @@ impl EguiApp {
3838
fn file_path_input(&mut self, ui: &mut Ui) {
3939
let mut locked_top = self.server_app.top().lock();
4040
let Some(file_path) = &mut locked_top.file_path else { return; };
41-
let edit_path_ui = ui.text_edit_singleline(file_path);
4241

43-
let popup_id = ui.make_persistent_id("file_path_popup");
42+
let edit_path_ui = Self::file_path_input_area(ui, file_path);
43+
44+
let popup_id = Id::new("file_path_popup");
4445
if edit_path_ui.gained_focus() {
4546
let server_locked = self.server.lock();
4647
let Some(server) = server_locked.deref() else { return; };
4748
server.search(&mut locked_top);
4849
ui.memory_mut(|m| m.open_popup(popup_id));
4950
}
5051

52+
if edit_path_ui.changed() {
53+
let server_locked = self.server.lock();
54+
let Some(server) = server_locked.deref() else { return; };
55+
server.search(&mut locked_top);
56+
}
57+
5158
let search_results = locked_top.search_result.clone();
5259
drop(locked_top);
5360

@@ -56,20 +63,38 @@ impl EguiApp {
5663
ui, popup_id, &edit_path_ui,
5764
PopupCloseBehavior::CloseOnClickOutside, |ui| {
5865
ui.vertical(|ui| {
59-
for result in search_results {
60-
if ui.label(result.to_string()).clicked() {
61-
let server_locked = self.server.lock();
62-
let Some(server) = server_locked.deref() else { return; };
63-
let mut content_locked = self.server_app.content().lock();
64-
let mut locked_top = self.server_app.top().lock();
65-
let accessor = server.accessor.lock();
66-
let Some(accessor) = accessor.deref() else { return; };
67-
server.switch_or_open_lock_free(
68-
&result, accessor, &mut content_locked, &mut locked_top,
69-
);
70-
}
71-
}
66+
Self::popup_file_path_ui(self, ui);
7267
})
7368
});
7469
}
70+
71+
fn file_path_input_area(ui: &mut Ui, file_path: &mut String) -> Response {
72+
let id_for_input_remaining = Id::new("file_path_input_area_remaining");
73+
let max_width = ui.max_rect().width();
74+
let last_time_remaining = ui
75+
.data(|data| data.get_temp(id_for_input_remaining)
76+
.unwrap_or(max_width));
77+
let target_width_for_content = max_width - last_time_remaining;
78+
79+
let edit_path_ui = TextEdit::singleline(file_path)
80+
.desired_width(target_width_for_content).show(ui).response;
81+
82+
let remaining_width = ui.min_rect().width() - target_width_for_content;
83+
ui.data_mut(|data| {
84+
data.insert_temp(id_for_input_remaining, remaining_width);
85+
});
86+
edit_path_ui
87+
}
88+
89+
fn popup_file_path_ui(&mut self, ui: &mut Ui) {
90+
let search_results = self.server_app.top().lock().search_result.clone();
91+
for result in search_results {
92+
let selectable_label = ui.selectable_label(false, result.to_string());
93+
if selectable_label.clicked() {
94+
let server_locked = self.server.lock();
95+
let Some(server) = server_locked.deref() else { return; };
96+
server.switch_or_open(&result, &self.server_app);
97+
}
98+
}
99+
}
75100
}

asm_egui/src/util.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,36 @@
1-
use egui::{RichText, WidgetText};
2-
use java_asm::StrRef;
1+
use egui::{Id, Ui};
32

4-
pub fn widget_text(str_ref: StrRef) -> WidgetText {
5-
WidgetText::RichText(RichText::new(&*str_ref))
3+
// content: (ui, target_width_for_content)
4+
pub fn fill_width_in_parent(
5+
ui: &mut Ui, content_id_for_fill: Id, content: impl FnOnce(&mut Ui, f32),
6+
) {
7+
let before_ui_available = ui.available_width();
8+
let last_time_allocated = ui
9+
.data(|data| data.get_temp(content_id_for_fill)
10+
.unwrap_or(before_ui_available));
11+
let target_width_for_content = before_ui_available - last_time_allocated;
12+
content(ui, target_width_for_content);
13+
14+
let after_ui_available = ui.available_width();
15+
ui.data_mut(|data| {
16+
let allocated = before_ui_available - after_ui_available;
17+
data.insert_temp(content_id_for_fill, allocated);
18+
})
19+
}
20+
21+
pub fn available_width_to_fill(ui: &mut Ui, content_id_for_fill: Id) -> f32 {
22+
let before_ui_available = ui.available_width();
23+
let last_time_allocated = ui
24+
.data(|data| data.get_temp(content_id_for_fill)
25+
.unwrap_or(before_ui_available));
26+
before_ui_available - last_time_allocated
27+
}
28+
29+
pub fn record_remain_width_after_rendered(ui: &mut Ui, content_id_for_fill: Id) {
30+
let before_ui_available = ui.available_width();
31+
let after_ui_available = ui.available_width();
32+
let allocated = before_ui_available - after_ui_available;
33+
ui.data_mut(|data| {
34+
data.insert_temp(content_id_for_fill, allocated);
35+
})
636
}

asm_server/src/impls/server.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ pub struct ProgressMessage {
2424
pub in_loading: bool,
2525
}
2626

27+
// search is too fast now, it's meaningless to use the message to dispatch.
28+
// so we didn't use this message currently.
2729
pub struct SearchResultMessage {
2830
pub result: Vec<StrRef>,
2931
}

asm_server/src/server.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ impl AsmServer {
3939
pub fn get_trie(&self) -> &ArcNullable<Trie<u8>> {
4040
let mut current = self.trie.lock();
4141
if current.is_some() { return &self.trie; }
42+
let load_start = Instant::now();
4243
let classes_locked = self.get_classes().lock();
4344
let Some(classes) = classes_locked.deref() else { return &self.trie; };
4445
let mut trie_builder = TrieBuilder::new();
@@ -47,6 +48,11 @@ impl AsmServer {
4748
};
4849
let trie = trie_builder.build();
4950
current.replace(trie);
51+
let load_end = Instant::now();
52+
info!(
53+
"trie loaded in {}ms",
54+
load_end.duration_since(load_start).as_millis()
55+
);
5056
&self.trie
5157
}
5258

@@ -122,7 +128,7 @@ impl AsmServer {
122128
let Some(query) = &top.file_path else { return; };
123129
let trie_locked = self.get_trie().lock();
124130
let Some(trie) = trie_locked.deref() else { return; };
125-
let results: Vec<String> = trie.predictive_search(query).collect();
131+
let results: Vec<String> = trie.predictive_search(query).take(20).collect();
126132
top.search_result = results.into_iter().map(StrRef::from).collect();
127133
}
128134
}

0 commit comments

Comments
 (0)