Add Windows SpaceMouse navigation through 3DxWare

This commit is contained in:
Christopher Overbeck committed 2026-09-15 13:20:19 -05:00
1 parent 612124b84b
commit 6a63726eff
32 files changed
+3510 -12

No files matched your search

+7
View File
@@ -1,6 +1,7 @@
//! Bottom status bar — Model/Layout tabs + OSNAP toggle + status info
pub mod status_menu;
pub(crate) mod spacemouse;
pub mod statusbar_config;
pub mod statusbar_menu;
@@ -135,6 +136,7 @@ impl StatusBar {
parametric_conflicts: usize,
// What is drawing the scene. Only a degraded verdict shows anything.
gpu_status: &'a crate::scene::pipeline::GpuStatus,
spacemouse: Option<Element<'a, Message>>,
) -> Element<'a, Message> {
let StatusMenuData {
layout_names,
@@ -241,6 +243,11 @@ impl StatusBar {
// when the width can't hold them all on one line.
let vis = |p: StatusPill| config.is_visible(p);
let mut pills: Vec<Element<'_, Message>> = Vec::new();
if vis(StatusPill::SpaceMouse) {
if let Some(pill) = spacemouse {
pills.push(pill);
}
}
// Not a `StatusPill` and not hideable: the scene is on a software
// rasterizer or not drawn at all, and the popup that said so has been
// dismissed. This stays for the session and reopens it. Many people
+78
View File
@@ -0,0 +1,78 @@
use super::status_menu::{self, Entry};
use crate::app::Message;
use crate::input::spacemouse::{NavigationMode, Preferences, Status};
use iced::widget::{button, row, text};
use iced::{Element, Fill};
pub(crate) fn view(
preferences: Preferences,
status: Status,
paused: bool,
label: String,
sheet: bool,
) -> Element<'static, Message> {
let root = button(
row![
crate::ui::icons::themed(crate::ui::window::options::spacemouse::ICON, 15.),
text(label).size(11),
crate::ui::icons::themed_arrow_toggle(false, 8.)
]
.spacing(5)
.align_y(iced::Center),
)
.padding([3, 6])
.style(button::subtle);
let mut entries = vec![Entry::stay(
text(format!("SpaceMouse · {}", crate::t!(status.label()))).size(11),
)];
for mode in NavigationMode::ALL {
let label = format!(
"{} {}",
if mode == preferences.mode {
"●"
} else {
"○"
},
crate::t!(mode.label())
);
entries.push(Entry::close(
button(text(label).size(12))
.width(Fill)
.padding([7, 10])
.style(button::text)
.on_press(Message::SpaceMouseMode(mode)),
));
}
if sheet {
entries.push(Entry::stay(
text(crate::t!("Paper sheets keep rotation locked.")).size(11),
));
}
entries.push(Entry::close(
button(
text(crate::t!(if paused {
"Resume SpaceMouse"
} else {
"Pause SpaceMouse"
}))
.size(12),
)
.on_press(Message::SpaceMousePause)
.style(button::text)
.width(Fill)
.padding([7, 10]),
));
for (label, message) in [
("SpaceMouse preferences…", Message::SpaceMousePreferences),
("3Dconnexion settings…", Message::SpaceMouseDriverSettings),
] {
entries.push(Entry::close(
button(text(crate::t!(label)).size(12))
.on_press(message)
.style(button::text)
.width(Fill)
.padding([7, 10]),
));
}
status_menu::menu_bar(root, entries, 260.)
}
+4
View File
@@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
/// Identifies a toggleable status-bar pill.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub enum StatusPill {
SpaceMouse,
Coords,
Ortho,
Lwt,
@@ -37,6 +38,7 @@ impl StatusPill {
/// Every pill, in status-bar display order. Drives both the bar layout and
/// the customization menu.
pub const ALL: &'static [StatusPill] = &[
StatusPill::SpaceMouse,
StatusPill::Coords,
StatusPill::Ortho,
StatusPill::Lwt,
@@ -62,6 +64,7 @@ impl StatusPill {
/// Stable identifier used for persistence.
pub fn id(self) -> &'static str {
match self {
StatusPill::SpaceMouse => "spacemouse",
StatusPill::Coords => "coords",
StatusPill::Ortho => "ortho",
StatusPill::Lwt => "lwt",
@@ -88,6 +91,7 @@ impl StatusPill {
/// Label shown in the customization menu.
pub fn label(self) -> &'static str {
match self {
StatusPill::SpaceMouse => "SpaceMouse",
StatusPill::Coords => "Coordinates",
StatusPill::Ortho => "Ortho Mode",
StatusPill::Lwt => "Show Lineweight",