paiagram/interface/tabs/
start.rs

1use crate::interface::tabs::tree_view;
2
3use super::Tab;
4use bevy::ecs::system::{In, InMut};
5use bevy::log::prelude::*;
6use egui::{Frame, Label, Response, ScrollArea, Sense, Ui, UiBuilder, Vec2, vec2};
7use strum::IntoEnumIterator;
8use strum_macros::EnumIter;
9use egui_i18n::tr;
10
11#[derive(Debug, Default, Clone, Copy, EnumIter, PartialEq)]
12enum CurrentField {
13    #[default]
14    List,
15    About,
16    Misc,
17}
18
19impl CurrentField {
20    fn name(self) -> &'static str {
21        match self {
22            Self::List => "List",
23            Self::About => "About",
24            Self::Misc => "Misc",
25        }
26    }
27}
28
29#[derive(Debug, Default, Clone, Copy)]
30pub struct StartTab {
31    current_field: CurrentField,
32}
33
34impl PartialEq for StartTab {
35    fn eq(&self, _other: &Self) -> bool {
36        true
37    }
38}
39
40impl Tab for StartTab {
41    const NAME: &'static str = "Start";
42    fn main_display(&mut self, world: &mut bevy::ecs::world::World, ui: &mut Ui) {
43        match self.current_field {
44            CurrentField::List => {
45                if let Err(e) = world.run_system_cached_with(show_start, ui) {
46                    error!("UI Error while displaying start page: {e}")
47                }
48            }
49            CurrentField::About => {
50                show_about(ui);
51            }
52            CurrentField::Misc => {}
53        }
54    }
55    fn title(&self) -> egui::WidgetText {
56        tr!("tab-start").into()
57    }
58    fn edit_display(&mut self, world: &mut bevy::ecs::world::World, ui: &mut Ui) {
59        if let Err(e) = world.run_system_cached_with(tree_view::show_tree_view, ui) {
60            error!("UI Error while displaying tree view: {e}")
61        }
62    }
63    fn display_display(&mut self, world: &mut bevy::ecs::world::World, ui: &mut Ui) {
64        for field in CurrentField::iter() {
65            ui.add_sized(vec2(ui.available_width(), 20.0), |ui: &mut Ui| {
66                ui.selectable_value(&mut self.current_field, field, field.name())
67            });
68        }
69    }
70    fn scroll_bars(&self) -> [bool; 2] {
71        [false, true]
72    }
73}
74
75fn show_start(InMut(ui): InMut<Ui>) {
76    const CARD_SPACING: f32 = 10.0;
77    ui.spacing_mut().item_spacing.x = CARD_SPACING;
78    ui.spacing_mut().item_spacing.y = CARD_SPACING;
79    ui.vertical_centered(|ui| {
80        ui.horizontal_wrapped(|ui| {
81            for _ in 0..=100 {
82                diagram_card(ui, "Create new diagram", None);
83            }
84        });
85    });
86}
87
88fn diagram_card(ui: &mut Ui, title: &str, image: Option<i32>) -> Response {
89    // the image is handled later.
90    const CARD_WIDTH: f32 = 150.0;
91    const CARD_SIZE: Vec2 = Vec2 {
92        x: CARD_WIDTH,
93        y: CARD_WIDTH / 2.0 * 3.0,
94    };
95
96    let (rect, resp) = ui.allocate_exact_size(CARD_SIZE, Sense::click());
97    ui.scope_builder(UiBuilder::new().max_rect(rect).sense(resp.sense), |ui| {
98        let visuals = ui.style().interact(&ui.response());
99        let stroke = {
100            let mut a = visuals.bg_stroke;
101            a.width = 1.5;
102            a
103        };
104        Frame::new()
105            .fill(visuals.bg_fill)
106            .stroke(stroke)
107            .inner_margin(3)
108            .corner_radius(3)
109            .show(ui, |ui| {
110                ui.set_min_size(ui.available_size());
111                ui.with_layout(egui::Layout::bottom_up(egui::Align::Min), |ui| {
112                    ui.add(Label::new(title).truncate())
113                });
114            });
115    })
116    .response
117}
118
119fn show_about(ui: &mut Ui) {
120    ui.vertical_centered(|ui| {
121        let max_width = (620.0f32).min(ui.available_width()) - 40.0;
122        ui.set_max_width(max_width);
123        ui.add_space(20.0);
124        ui.heading(tr!("program-name"));
125        ui.label(format!("Version: {}", env!("CARGO_PKG_VERSION")));
126        ui.monospace(format!("Revision: {}", git_version::git_version!()));
127        ui.add_space(10.0);
128        ui.separator();
129        ui.add_space(10.0);
130        ui.label("A high-performance transport timetable diagramming and analysis tool built with egui and Bevy.");
131        ui.add_space(20.0);
132
133        ui.collapsing("Authors", |ui| {
134            ui.label("• Lead Developer: Jeremy Gao");
135            ui.label("• Contributors: We don't have any yet");
136        });
137
138        ui.collapsing("Third-party Libraries", |ui| {
139            ui.label("Paiagram is made possible by the following open-source projects:");
140            ui.horizontal(|ui| {
141                ui.label("•");
142                ui.hyperlink_to("egui", "https://github.com/emilk/egui");
143            });
144            ui.horizontal(|ui| {
145                ui.label("•");
146                ui.hyperlink_to("Bevy Engine", "https://bevyengine.org/");
147            });
148            ui.horizontal(|ui| {
149                ui.label("•");
150                ui.hyperlink_to("Petgraph", "https://docs.rs/petgraph/latest/petgraph/");
151            });
152            ui.label("• Other Rust libraries. See cargo.toml and cargo.lock for a complete list of libraries used.");
153        });
154
155        ui.collapsing("License Information", |ui| {
156            ui.label("Paiagram is a free software. If you bought it, you're likely scammed :-(");
157            ScrollArea::vertical()
158                .max_height(400.0)
159                .show(ui, |ui| {
160                    ui.monospace(include_str!("../../../LICENSE.md"));
161                });
162        });
163
164        ui.collapsing("Contact & Support", |ui| {
165            ui.label("• Bug Reports: We don't have one yet.");
166            ui.label("• Discussions: We don't have one yet.");
167            ui.horizontal(|ui| {
168                ui.label("• Email: ");
169                ui.hyperlink("mailto://wensimehrp@gmail.com");
170            });
171        });
172
173        ui.collapsing("Special Thanks", |ui| {
174            ui.label("• x.e.p., for showing how to make stuff");
175            ui.label("• Tantacurl, for showing how make accessible, reliable, and cool stuff");
176        });
177
178        ui.add_space(20.0);
179        ui.horizontal(|ui| {
180            ui.hyperlink_to("GitHub", "https://github.com/wensimehrp/Paiagram");
181            ui.label("•");
182            ui.hyperlink_to("Documentation", "https://wensimehrp.github.io/Paiagram");
183        });
184        ui.add_space(20.0);
185    });
186}