mod activity;
mod auto_solve;
mod callbacks;
mod compare;
mod cut_sheet;
mod deep_solve;
pub(in crate::gui::editor) mod edit_intent;
mod guide;
#[cfg(test)]
mod identity_pins;
mod loading;
pub(in crate::gui) mod material_lookup;
mod manipulate;
pub(in crate::gui) mod native_io;
mod optimize_solve;
pub use indicatrix_editor::retarget;
mod setup;
mod shortcuts;
mod solve_service;
mod stale;
mod stall_guard;
mod state;
mod templates;
mod view;
pub(in crate::gui) use compare::close_compare_window;
use crate::{
MainWindow,
bridge::{library::source::LibrarySource, render_thread::RenderContext},
gui::solid_preview::preview_state::{SolidLastSolved, SolidPickState, SolidPreviewState},
};
use indicatrix::geometry::meet_solver::SolvedTier;
use indicatrix_vault::db::sqlite::Database;
use setup::{setup_solve_cancel_callback, setup_startup_restore, setup_tier_cutoff_callback};
use slint::ComponentHandle;
use state::EditorState;
use std::{
cell::RefCell,
rc::Rc,
sync::{Arc, Mutex},
};
fn setup_edit_view_entered_callback(
ui: &MainWindow,
state: &Rc<RefCell<EditorState>>,
render_ctx: &Arc<Mutex<RenderContext>>,
preview_state: &Arc<SolidPreviewState>,
solid_last_solved: &SolidLastSolved,
) {
let ui_weak = ui.as_weak();
let state = Rc::clone(state);
let render_ctx = Arc::clone(render_ctx);
let preview_state = Arc::clone(preview_state);
let solid_last_solved = Arc::clone(solid_last_solved);
ui.on_edit_view_entered(move || {
let Some(ui) = ui_weak.upgrade() else {
return;
};
view::reclaim_viewport_for_editor(
&ui,
&render_ctx,
&preview_state,
&solid_last_solved,
&state.borrow(),
);
});
}
pub fn setup_editor_callbacks(
ui: &MainWindow,
db: &Arc<Mutex<Database>>,
source: &Arc<Mutex<LibrarySource>>,
render_ctx: &Arc<Mutex<RenderContext>>,
preview_state: &Arc<SolidPreviewState>,
solid_last_solved: &SolidLastSolved,
solid_pick_state: &SolidPickState,
) {
let activity = activity::ActivityRegistry::new(ui);
auto_solve::init(preview_state, solid_last_solved, &activity);
let state = Rc::new(RefCell::new(EditorState::fresh()));
view::refresh_editor_panel(ui, render_ctx, &state.borrow());
setup_startup_restore(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_new_design_create_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_load_selected_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
db,
source,
);
callbacks::setup_solve_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
setup_edit_view_entered_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_undo_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_redo_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_apply_preform_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_apply_yield_inputs_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_save_tier_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_remove_tier_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_toggle_detach_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_inline_set_angle_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_nudge_angle_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_duplicate_tier_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_toggle_multi_select_callback(ui, &state);
native_io::setup_export_asc_callback(ui, &state, render_ctx);
native_io::setup_export_cutting_sheet_callback(ui, &state, render_ctx);
native_io::setup_export_diagram_callback(ui, &state);
native_io::setup_save_native_callback(ui, &state, db, source, render_ctx);
native_io::setup_open_native_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_adopt_meet_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_deep_solve_callback(ui, &state);
setup_solve_cancel_callback(ui);
setup_tier_cutoff_callback(ui, &state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_deep_solve_cancel_callback(ui, &state);
callbacks::setup_optimize_callback(ui, &state, render_ctx);
callbacks::setup_optimize_cancel_callback(ui, &state);
callbacks::setup_optimize_apply_callback(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_batch_tilt_for_open_design_callback(ui, &state, render_ctx, db);
guide::setup_guide(ui, &state);
shortcuts::setup_shortcuts_overlay(ui);
templates::setup_template_gallery(ui);
setup_editor_secondary_callbacks(
ui,
&state,
render_ctx,
preview_state,
solid_last_solved,
solid_pick_state,
);
}
fn setup_editor_secondary_callbacks(
ui: &MainWindow,
state: &Rc<RefCell<EditorState>>,
render_ctx: &Arc<Mutex<RenderContext>>,
preview_state: &Arc<SolidPreviewState>,
solid_last_solved: &SolidLastSolved,
solid_pick_state: &SolidPickState,
) {
callbacks::setup_apply_preform_y_offset_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_apply_cheater_offset_callback(ui, state, render_ctx);
callbacks::setup_apply_tier_note_callback(ui, state, render_ctx);
callbacks::setup_apply_design_meta_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_apply_design_material_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_gear_apply_callback(ui, state);
callbacks::setup_gear_remap_confirm_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_gear_remap_cancel_callback(ui, state);
callbacks::setup_apply_symmetry_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_viewport_material_linked_changed_callback(ui, state, render_ctx);
callbacks::setup_material_suggestion_accept_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_material_suggestion_dismiss_callback(ui);
callbacks::setup_retarget_open_callback(ui, state, render_ctx);
callbacks::setup_retarget_proposal_changed_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_retarget_apply_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_retarget_close_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
setup_editor_tertiary_callbacks(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
solid_pick_state,
);
}
fn setup_editor_tertiary_callbacks(
ui: &MainWindow,
state: &Rc<RefCell<EditorState>>,
render_ctx: &Arc<Mutex<RenderContext>>,
preview_state: &Arc<SolidPreviewState>,
solid_last_solved: &SolidLastSolved,
solid_pick_state: &SolidPickState,
) {
callbacks::setup_snapshot_callbacks(ui, state, solid_last_solved);
compare::setup_compare_callbacks(ui, state, render_ctx, preview_state, solid_last_solved);
callbacks::setup_deep_solve_pin_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_optimize_preview_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_tier_filter_callback(ui);
callbacks::setup_angle_live_preview_callback(ui, state);
callbacks::setup_anchor_explainer_dismiss_callback(ui);
callbacks::setup_material_guess_set_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
callbacks::setup_solid_facet_hover_callback(ui, solid_pick_state);
callbacks::setup_solid_facet_click_callback(ui, solid_pick_state);
callbacks::setup_solid_selected_tier_changed_callback(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
);
manipulate::setup_manipulate_callbacks(
ui,
state,
render_ctx,
preview_state,
solid_last_solved,
solid_pick_state,
);
}
pub fn apply_matching_preview_frame(
ui: &MainWindow,
render_ctx: &Arc<Mutex<RenderContext>>,
generation: u64,
solved: &[SolvedTier],
) {
if let Some((design, multi_selected)) = auto_solve::take_matching_design(generation) {
let (custom_materials, custom_sg) = {
let ctx = render_ctx
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
(
ctx.custom_materials.as_ref().clone(),
Arc::clone(&ctx.custom_material_specific_gravity),
)
};
view::push_solved_preview(
ui,
&design,
solved,
&multi_selected,
&custom_materials,
&custom_sg,
);
auto_solve::schedule_idle_replan_if_stale(
ui,
render_ctx,
generation,
&design,
&multi_selected,
);
}
}
pub fn on_solid_frame_landed(ui: &MainWindow, generation: u64) {
manipulate::on_frame_landed(ui, generation);
}
#[must_use]
pub const fn frame_updates_mast_cache(generation: u64) -> bool {
manipulate::frame_updates_mast_cache(generation)
}
pub fn note_provisional_frame_masts(masts: Vec<SolvedTier>) {
manipulate::note_provisional_masts(masts);
}
pub fn note_provisional_frame_planes(planes: &[(glam::Vec3, f32)]) {
manipulate::note_provisional_planes(planes);
}
pub use loading::{CataloguePlanesSource, resolve_catalogue_planes};