The up axis preference (Preferences > Design, ui.prefs up_axis) turns the view: the camera, home view, ground grid and orbit follow it, at startup too
Fixes #3 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
This commit is contained in:
1 parent
74f70614cc
commit
524ef6b8c2
1 file changed
+30
-1
@@ -88,6 +88,8 @@ pub struct PrefsWindow {
|
|||||||
pub section: usize,
|
pub section: usize,
|
||||||
/// Everything as it was when the dialog opened (or at the last Apply), for Cancel.
|
/// Everything as it was when the dialog opened (or at the last Apply), for Cancel.
|
||||||
snapshot: Option<Snapshot>,
|
snapshot: Option<Snapshot>,
|
||||||
|
/// The up axis preference the view follows now (applied when it changes, and at startup).
|
||||||
|
applied_up: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Open the dialog at a page.
|
/// Open the dialog at a page.
|
||||||
@@ -196,6 +198,10 @@ fn defaults(app: &mut SolveApp, page: usize) {
|
|||||||
/// Settings that follow the preferences every frame: the theme when it follows the system, and
|
/// Settings that follow the preferences every frame: the theme when it follows the system, and
|
||||||
/// the interface scale.
|
/// the interface scale.
|
||||||
pub fn apply(app: &mut SolveApp, ctx: &egui::Context) {
|
pub fn apply(app: &mut SolveApp, ctx: &egui::Context) {
|
||||||
|
// The view's up axis follows the preference (set in the dialog, by ui.prefs or loaded).
|
||||||
|
if app.prefs_window.applied_up.as_deref() != Some(app.preferences.up_axis.as_str()) {
|
||||||
|
up_axis_changed(app);
|
||||||
|
}
|
||||||
if app.preferences.theme == "system"
|
if app.preferences.theme == "system"
|
||||||
&& let Some(t) = ctx.system_theme()
|
&& let Some(t) = ctx.system_theme()
|
||||||
{
|
{
|
||||||
@@ -451,7 +457,12 @@ fn close(app: &mut SolveApp, revert: bool) {
|
|||||||
|
|
||||||
/// The default orientation changed: the view turns to match.
|
/// The default orientation changed: the view turns to match.
|
||||||
fn up_axis_changed(app: &mut SolveApp) {
|
fn up_axis_changed(app: &mut SolveApp) {
|
||||||
app.animate_view("home");
|
use solvecraft_engine::render::UpAxis;
|
||||||
|
app.prefs_window.applied_up = Some(app.preferences.up_axis.clone());
|
||||||
|
let up = if app.preferences.up_axis.eq_ignore_ascii_case("y") { UpAxis::Y } else { UpAxis::Z };
|
||||||
|
if app.ui.up_axis != up || app.cam.up != up {
|
||||||
|
app.set_up_axis(up);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One page of the dialog.
|
/// One page of the dialog.
|
||||||
@@ -822,4 +833,22 @@ mod tests {
|
|||||||
let s = crate::viewport::projection(&app, rect).to_screen(pivot).unwrap();
|
let s = crate::viewport::projection(&app, rect).to_screen(pivot).unwrap();
|
||||||
assert!(s.distance(at) < 2.0, "{s:?}");
|
assert!(s.distance(at) < 2.0, "{s:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The Y up preference turns the view: the camera's up axis follows it, startup included.
|
||||||
|
#[test]
|
||||||
|
fn up_axis_preference_turns_the_view() {
|
||||||
|
use solvecraft_engine::render::UpAxis;
|
||||||
|
let mut app = SolveApp::new(solvecraft_engine::Session::default(), crate::Services::default());
|
||||||
|
let ctx = egui::Context::default();
|
||||||
|
apply(&mut app, &ctx);
|
||||||
|
assert_eq!(app.cam.up, UpAxis::Z);
|
||||||
|
app.preferences.up_axis = "y".into();
|
||||||
|
apply(&mut app, &ctx);
|
||||||
|
assert_eq!((app.ui.up_axis, app.cam.up), (UpAxis::Y, UpAxis::Y));
|
||||||
|
// Home looks at the model with Y up: the eye is above the XZ ground.
|
||||||
|
assert!(app.cam.back().y > 0.3, "{:?}", app.cam.back());
|
||||||
|
app.preferences.up_axis = "z".into();
|
||||||
|
apply(&mut app, &ctx);
|
||||||
|
assert_eq!(app.cam.up, UpAxis::Z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user