pages are fun
This commit is contained in:
175
src/apad/mod.rs
175
src/apad/mod.rs
@@ -32,7 +32,10 @@ use bevy_egui::{
|
||||
};
|
||||
use bevy_mod_openxr::session::OxrSession;
|
||||
use bevy_pkv::{PersistentResourceAppExtensions, PkvStore};
|
||||
use egui::{Color32, Margin, PointerButton, Pos2};
|
||||
use egui::{
|
||||
Button, Color32, Layout, Margin, PointerButton, Pos2, Rect, TextEdit, Theme, Ui,
|
||||
scroll_area::ScrollSource,
|
||||
};
|
||||
use openxr::Path;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -46,7 +49,7 @@ use crate::{
|
||||
keyboard::VirtualKeyboard,
|
||||
otdipcplugin::{OtdIpcPlugin, PenButtons, PenDelta, PenPosition},
|
||||
},
|
||||
egui_pages::{Overview, overview},
|
||||
egui_pages::*,
|
||||
vrcontrollerplugin::{
|
||||
LeftController, LeftControllerActions, RightController, RightControllerActions,
|
||||
},
|
||||
@@ -101,6 +104,9 @@ impl Default for KneeboardPosition {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource, Serialize, Deserialize, Default)]
|
||||
pub struct KneeboardNotepad(String);
|
||||
|
||||
pub struct APadPlugin;
|
||||
impl Plugin for APadPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
@@ -109,10 +115,12 @@ impl Plugin for APadPlugin {
|
||||
.add_plugins(MaterialPlugin::<MyCustomMaterial>::default());
|
||||
|
||||
app.insert_resource(PkvStore::new("Avii", "Kneeboard"))
|
||||
.init_persistent_resource::<KneeboardPosition>();
|
||||
.init_persistent_resource::<KneeboardPosition>()
|
||||
.init_persistent_resource::<KneeboardNotepad>();
|
||||
|
||||
app.insert_resource(TabletSize(Vec2::new(210.0, 279.0)));
|
||||
app.insert_resource(TabletResolutionScale(2.25));
|
||||
// app.insert_resource(TabletResolutionScale(2.25));
|
||||
app.insert_resource(TabletResolutionScale(2.5));
|
||||
app.insert_resource(PointerImage(None));
|
||||
app.insert_resource(Name("".to_string()));
|
||||
app.insert_resource(KeyboardVisible(false));
|
||||
@@ -127,9 +135,11 @@ impl Plugin for APadPlugin {
|
||||
position_kneeboard,
|
||||
move_kneeboard,
|
||||
sync_camera_with_kneeboard,
|
||||
),
|
||||
)
|
||||
.chain(),
|
||||
)
|
||||
.add_systems(Update, pointer.in_set(EguiInputSet::InitReading))
|
||||
.add_systems(Update, update_pointer.in_set(EguiInputSet::WriteEguiEvents))
|
||||
.add_systems(Update, render_pointer)
|
||||
.add_systems(WorldspaceContextPass, update);
|
||||
}
|
||||
}
|
||||
@@ -158,29 +168,16 @@ fn setup_pointer(
|
||||
pointer.0 = Some(image);
|
||||
}
|
||||
|
||||
fn pointer(
|
||||
fn update_pointer(
|
||||
tablet_size: Res<TabletSize>,
|
||||
tablet_res: Res<TabletResolutionScale>,
|
||||
ent: Single<Entity, With<bevy_egui::EguiContext>>,
|
||||
mesh_material: Single<&MeshMaterial3d<MyCustomMaterial>, With<Kneeboard>>,
|
||||
mut pen_buttons: MessageReader<PenButtons>,
|
||||
mut pen_delta: MessageReader<PenDelta>,
|
||||
mut pen_position: MessageReader<PenPosition>,
|
||||
mut input_writer: MessageWriter<EguiInputEvent>,
|
||||
mut materials: ResMut<Assets<MyCustomMaterial>>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
mut pointer: ResMut<PointerImage>,
|
||||
mut pen_button_pressed: ResMut<WasPenButtonPressed>,
|
||||
) {
|
||||
let Some(ref mut pointer) = pointer.0 else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(image) = images.get_mut(&*pointer) else {
|
||||
return;
|
||||
};
|
||||
|
||||
image.clear(&[0u8; 4]);
|
||||
for pos in pen_position.read() {
|
||||
let x = pos.x * tablet_size.x * **tablet_res;
|
||||
let y = pos.y * tablet_size.y * **tablet_res;
|
||||
@@ -206,6 +203,7 @@ fn pointer(
|
||||
continue;
|
||||
}
|
||||
|
||||
// this is making me drop inputs or something
|
||||
if **pen_button_pressed != button.tip() {
|
||||
input_writer.write(EguiInputEvent {
|
||||
context: *ent,
|
||||
@@ -219,7 +217,31 @@ fn pointer(
|
||||
**pen_button_pressed = button.tip();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn render_pointer(
|
||||
tablet_size: Res<TabletSize>,
|
||||
tablet_res: Res<TabletResolutionScale>,
|
||||
mesh_material: Single<&MeshMaterial3d<MyCustomMaterial>, With<Kneeboard>>,
|
||||
mut pen_position: MessageReader<PenPosition>,
|
||||
mut materials: ResMut<Assets<MyCustomMaterial>>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
mut pointer: ResMut<PointerImage>,
|
||||
) {
|
||||
let Some(ref mut pointer) = pointer.0 else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(image) = images.get_mut(&*pointer) else {
|
||||
return;
|
||||
};
|
||||
|
||||
image.clear(&[0u8; 4]);
|
||||
|
||||
for pos in pen_position.read() {
|
||||
let x = pos.x * tablet_size.x * **tablet_res;
|
||||
let y = pos.y * tablet_size.y * **tablet_res;
|
||||
draw_pointer(image, x, y);
|
||||
|
||||
if let Some(material) = materials.get_mut(mesh_material.0.id()) {
|
||||
@@ -354,44 +376,109 @@ fn update(
|
||||
mut input: Single<&mut bevy_egui::EguiInput>,
|
||||
mut keyboard: Single<&mut Keyboard>,
|
||||
|
||||
mut notepad: ResMut<KneeboardNotepad>,
|
||||
|
||||
mo: Res<Overview>,
|
||||
sr: Res<Sitrep>,
|
||||
pr: Res<PilotRoster>,
|
||||
pe: Res<PackageElements>,
|
||||
ta: Res<ThreatAnalysis>,
|
||||
sp: Res<Steerpoints>,
|
||||
cl: Res<Commladder>,
|
||||
or: Res<Ordnance>,
|
||||
wt: Res<Weather>,
|
||||
su: Res<Support>,
|
||||
ro: Res<RulesOfEngagement>,
|
||||
ep: Res<Emergency>,
|
||||
) {
|
||||
let bgcolor = egui::containers::Frame {
|
||||
fill: egui::Color32::from_rgb(43, 44, 47),
|
||||
inner_margin: Margin {
|
||||
left: 15,
|
||||
right: 15,
|
||||
top: 15,
|
||||
bottom: 15,
|
||||
},
|
||||
ctx.get_mut().options_mut(|opt| {
|
||||
opt.input_options.max_click_dist = 24.0;
|
||||
opt.input_options.max_click_duration = 1.0;
|
||||
});
|
||||
|
||||
let margins = egui::containers::Frame {
|
||||
inner_margin: Margin::same(15),
|
||||
..Default::default()
|
||||
};
|
||||
let focus = keyboard.is_active(ctx.get_mut());
|
||||
|
||||
let height = if focus { 200.0 } else { 0.0 };
|
||||
|
||||
egui::containers::CentralPanel::default()
|
||||
.frame(bgcolor)
|
||||
.show(ctx.get_mut(), |ui| {
|
||||
egui::containers::TopBottomPanel::bottom("bottom_panel")
|
||||
.resizable(false)
|
||||
.height_range(egui::Rangef::new(0., height))
|
||||
.show_inside(ui, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
keyboard.show(ui);
|
||||
});
|
||||
egui::containers::CentralPanel::default().show(ctx.get_mut(), |ui| {
|
||||
egui::containers::TopBottomPanel::bottom("bottom_panel")
|
||||
.resizable(false)
|
||||
.height_range(egui::Rangef::new(0., height))
|
||||
.show_inside(ui, |ui| {
|
||||
ui.with_layout(Layout::top_down_justified(egui::Align::Center), |ui| {
|
||||
keyboard.show(ui);
|
||||
});
|
||||
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
overview(ui, mo);
|
||||
|
||||
// ..
|
||||
});
|
||||
|
||||
ui.with_layout(Layout::top_down_justified(egui::Align::LEFT), |ui| {
|
||||
let rect = ui
|
||||
.add(TextEdit::multiline(&mut notepad.0).margin(Margin::same(8)))
|
||||
.rect;
|
||||
global_theme_preference_switch(ui, &rect);
|
||||
});
|
||||
|
||||
egui::containers::CentralPanel::default()
|
||||
.frame(margins)
|
||||
.show_inside(ui, |ui| {
|
||||
egui::ScrollArea::vertical()
|
||||
// .scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysHidden)
|
||||
.scroll_source(ScrollSource::MOUSE_WHEEL | ScrollSource::SCROLL_BAR)
|
||||
.show(ui, |ui| {
|
||||
overview(ui, &mo);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
sitrep(ui, &sr);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
pilot_roster(ui, &pr);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
package_elements(ui, &pe);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
threat_analysis(ui, &ta);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
steerpoints(ui, &sp);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
commladder(ui, &cl);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
ordnance(ui, &or, &mo);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
weather(ui, &wt);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
support(ui, &su);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
rulesofengagement(ui, &ro);
|
||||
ui.add(egui::Separator::default().grow(8.0));
|
||||
emergency(ui, &ep);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
keyboard.bump_events(ctx.get_mut(), &mut input.0);
|
||||
}
|
||||
|
||||
pub fn global_theme_preference_switch(ui: &mut Ui, rect: &egui::Rect) {
|
||||
let theme = ui.ctx().theme();
|
||||
let icon = if theme == Theme::Dark { "☀" } else { "🌙" };
|
||||
let new_theme = if theme == Theme::Dark {
|
||||
Theme::Light
|
||||
} else {
|
||||
Theme::Dark
|
||||
};
|
||||
|
||||
let size = 16.;
|
||||
|
||||
let min = egui::pos2(rect.max.x - size, rect.min.y - 2.);
|
||||
let max = egui::pos2(rect.max.x, size - 2.);
|
||||
|
||||
let new_rect = Rect::from_min_max(min, max);
|
||||
|
||||
if ui.put(new_rect, Button::new(icon).frame(false)).clicked() {
|
||||
ui.ctx().set_theme(new_theme);
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_camera_with_kneeboard(
|
||||
kneeboard: Query<&Transform, With<Kneeboard>>,
|
||||
mut cameras: Query<&mut Transform, (With<MainCamera>, Without<Kneeboard>)>,
|
||||
@@ -482,8 +569,6 @@ fn move_kneeboard(
|
||||
if let Ok(trigger_state) = left.squeeze_click.state(&session, Path::NULL)
|
||||
&& trigger_state.current_state
|
||||
{
|
||||
dbg!("squeeze triggered");
|
||||
|
||||
let Ok(transform) = left_transform.single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user