modde_ui/views/
data_tab.rs1use iced::widget::{button, checkbox, column, container, row, scrollable, text, text_input};
2use iced::{Alignment, Element, Length};
3
4use crate::app::Message;
5
6#[derive(Debug, Clone, Default)]
8pub struct DataTabState {
9 pub filter: String,
10 pub show_conflicts_only: bool,
11}
12
13pub fn view<'a>(
15 state: &'a DataTabState,
16 conflict_files: &'a [(String, Vec<String>)],
17) -> Element<'a, Message> {
18 let title_bar = row![
19 text("Data Files").size(20),
20 iced::widget::space::horizontal(),
21 ]
22 .align_y(Alignment::Center);
23
24 let toolbar = row![
25 text_input("Filter files...", &state.filter)
26 .on_input(Message::DataTabFilterChanged)
27 .padding(6)
28 .width(Length::Fill),
29 checkbox(state.show_conflicts_only)
30 .on_toggle(Message::DataTabToggleConflicts),
31 text("Conflicts only").size(13),
32 ]
33 .spacing(8)
34 .align_y(Alignment::Center);
35
36 let filter_lower = state.filter.to_lowercase();
37 let filtered: Vec<&(String, Vec<String>)> = conflict_files
38 .iter()
39 .filter(|(file, _)| {
40 if !filter_lower.is_empty() && !file.to_lowercase().contains(&filter_lower) {
41 return false;
42 }
43 if state.show_conflicts_only {
44 return true; }
46 true
47 })
48 .collect();
49
50 let file_count = filtered.len();
51
52 let file_rows: Element<Message> = if filtered.is_empty() {
53 container(
54 text("No data files to display.").size(14),
55 )
56 .padding(20)
57 .width(Length::Fill)
58 .center_x(Length::Fill)
59 .into()
60 } else {
61 let rows = filtered
62 .into_iter()
63 .fold(column![].spacing(4), |col, (file, providers)| {
64 let provider_list = providers.join(", ");
65 let file_row = row![
66 text(file).size(13).width(Length::Fill),
67 text(provider_list).size(12).width(Length::Fixed(300.0)),
68 ]
69 .spacing(8)
70 .padding([4, 8]);
71 col.push(file_row)
72 });
73
74 scrollable(rows).height(Length::Fill).into()
75 };
76
77 let header = row![
78 text("File Path").size(12).width(Length::Fill),
79 text("Providing Mods").size(12).width(Length::Fixed(300.0)),
80 ]
81 .spacing(8)
82 .padding([4, 8]);
83
84 let status = text(format!("{file_count} file(s) shown")).size(12);
85
86 column![
87 title_bar,
88 toolbar,
89 header,
90 iced::widget::rule::horizontal(1),
91 file_rows,
92 status,
93 ]
94 .spacing(8)
95 .padding(16)
96 .width(Length::Fill)
97 .height(Length::Fill)
98 .into()
99}