refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
use super ::super ::{ Message , OpenCADStudio } ;
2026-08-02 22:09:25 +03:00
use crate ::t ;
2026-07-30 14:47:28 +03:00
use iced ::widget ::{ button , column , container , row , text , Space } ;
2026-08-01 18:24:05 +03:00
use iced ::{ Background , Element , Fill , Fit , Theme } ;
2026-08-02 22:09:25 +03:00
use std ::borrow ::Cow ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
impl OpenCADStudio {
2026-07-30 14:47:28 +03:00
/// Title shown in the active modal's title bar. Keep in sync with the
/// [`Self::modal_content`] dispatch.
2026-08-02 18:53:38 +03:00
pub ( super ) fn modal_title ( & self ) -> String {
2026-07-21 23:00:36 +03:00
use super ::super ::ModalKind as K ;
match self . active_modal {
2026-08-02 18:53:38 +03:00
Some ( K ::About ) = > crate ::tr! ( " modal-about " ) ,
Some ( K ::Shortcuts ) = > crate ::tr! ( " modal-keyboard-shortcuts " ) ,
Some ( K ::Aliases ) = > crate ::tr! ( " modal-command-aliases " ) ,
Some ( K ::Options ) = > crate ::tr! ( " action-options " ) ,
Some ( K ::FindReplace ) = > crate ::tr! ( " modal-find-replace " ) ,
Some ( K ::PluginManager ) = > crate ::tr! ( " modal-plugin-manager " ) ,
Some ( K ::UpdateNotice ) = > crate ::tr! ( " modal-update-available " ) ,
Some ( K ::Layers ) = > crate ::tr! ( " modal-layer-manager " ) ,
Some ( K ::LayerStateManager ) = > crate ::tr! ( " modal-layer-state-manager " ) ,
Some ( K ::LayerStateEditor ) = > crate ::tr! ( " modal-edit-layer-state " ) ,
Some ( K ::Plot ) = > crate ::tr! ( " modal-plot " ) ,
2026-08-04 11:29:11 +03:00
Some ( K ::PrintAll ) = > t! ( " Print All " ) . into_owned ( ) ,
2026-08-02 18:53:38 +03:00
Some ( K ::LayoutManager ) = > crate ::tr! ( " modal-layout-manager " ) ,
Some ( K ::ScaleManager ) = > crate ::tr! ( " modal-scale-manager " ) ,
Some ( K ::AnnoObjectScale ) = > crate ::tr! ( " modal-annotation-object-scale " ) ,
Some ( K ::Plotstyle ) = > crate ::tr! ( " modal-plot-style-editor " ) ,
Some ( K ::TextStyle ) = > crate ::tr! ( " modal-text-style-manager " ) ,
Some ( K ::MlStyle ) = > crate ::tr! ( " modal-multiline-style-manager " ) ,
Some ( K ::TableStyle ) = > crate ::tr! ( " modal-table-style-manager " ) ,
Some ( K ::MLeaderStyle ) = > crate ::tr! ( " modal-multileader-style-manager " ) ,
Some ( K ::DimStyle ) = > crate ::tr! ( " modal-dimension-style-manager " ) ,
Some ( K ::AssocPrompt ) = > crate ::tr! ( " modal-default-application " ) ,
Some ( K ::AecDropWarning ) = > crate ::tr! ( " modal-save-warning " ) ,
2026-07-27 13:13:58 +03:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2026-08-02 18:53:38 +03:00
Some ( K ::FileInUse ) = > crate ::tr! ( " modal-unable-save " ) ,
2026-07-27 13:13:58 +03:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2026-08-02 18:53:38 +03:00
Some ( K ::ExternalChange ) = > crate ::tr! ( " modal-drawing-changed " ) ,
Some ( K ::LayerDeleteWarning ) = > crate ::tr! ( " modal-delete-layer " ) ,
Some ( K ::Unsaved ) = > crate ::tr! ( " modal-unsaved-changes " ) ,
Some ( K ::PointStyle ) = > crate ::tr! ( " modal-point-style " ) ,
Some ( K ::AttributeEditor ) = > crate ::tr! ( " modal-attribute-editor " ) ,
Some ( K ::SaveDialog ) = > crate ::tr! ( " modal-save-drawing-as " ) ,
2026-08-03 12:47:48 +03:00
Some ( K ::Recovery ) = > crate ::tr! ( " modal-recovery-report " ) ,
Some ( K ::RecoveryPrompt ) = > crate ::tr! ( " modal-recovery-prompt " ) ,
2026-08-02 18:53:38 +03:00
None = > String ::new ( ) ,
2026-07-21 23:00:36 +03:00
}
}
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
/// Build the currently-open modal dialog's content (Plan B), or `None`.
2026-08-01 18:24:05 +03:00
/// Iced 0.15 measures the content first, so dialogs start at their natural
/// size and overflowing regions become scrollable where a cap is supplied.
2026-07-19 15:47:09 +03:00
pub ( super ) fn modal_content < ' s > ( & ' s self ) -> Option < Element < ' s , Message > > {
let ex = self . modal_resize ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
Some ( match self . active_modal ? {
2026-08-04 15:53:34 +03:00
super ::super ::ModalKind ::About = > {
automatic_flow ( ex , crate ::ui ::window ::about ::view_window )
}
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
super ::super ::ModalKind ::Shortcuts = > {
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
720 ,
520 ,
| flow | {
crate ::ui ::window ::shortcuts ::view_window (
2026-08-04 15:35:06 +03:00
& self . shortcut_editor_rows ,
2026-07-30 14:47:28 +03:00
flow ,
)
} ,
)
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
feat(alias): centralize command aliases in user-editable ocad.pgp (#286/#288)
Command aliases (L→LINE, CC→COPYCLIP) were scattered across dispatch match
arms and CommandRegistration name arrays. Move them all into a single
user-editable file:
- assets/ocad.pgp: shipped default alias table (ALIAS,*COMMAND format),
embedded and copied to config/ocad.pgp on first launch; only that user
copy is read after. AA→AREA default closes #286.
- resolve_alias() rewrites the leading command token at the top of
dispatch_command_inner, so aliases resolve for every path (families,
plugins, Repeat menu). Args after the first space are untouched.
- Autocomplete hides alias keys and, when the whole input is an alias,
surfaces its target command as the top (highlighted) suggestion so the
highlight matches what Enter runs (AA→AREA, L→LINE).
- ALIASEDIT opens a new editor modal (add/edit/delete rows) with an Apply
button; Apply persists to ocad.pgp, closing discards unapplied edits.
- Strip alias tokens from all 8 dispatch match-arm files and 71 module
CommandRegistration arrays, keeping canonical/synonym/distinct-command
names. ocad.pgp is now the sole source: deleting or remapping an alias
there takes effect. CUI stays on the keyboard-shortcut panel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:39:22 +03:00
super ::super ::ModalKind ::Aliases = > {
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
480 ,
520 ,
| flow | {
crate ::ui ::window ::alias_editor ::view_window (
& self . alias_editor_rows ,
flow ,
)
} ,
)
feat(alias): centralize command aliases in user-editable ocad.pgp (#286/#288)
Command aliases (L→LINE, CC→COPYCLIP) were scattered across dispatch match
arms and CommandRegistration name arrays. Move them all into a single
user-editable file:
- assets/ocad.pgp: shipped default alias table (ALIAS,*COMMAND format),
embedded and copied to config/ocad.pgp on first launch; only that user
copy is read after. AA→AREA default closes #286.
- resolve_alias() rewrites the leading command token at the top of
dispatch_command_inner, so aliases resolve for every path (families,
plugins, Repeat menu). Args after the first space are untouched.
- Autocomplete hides alias keys and, when the whole input is an alias,
surfaces its target command as the top (highlighted) suggestion so the
highlight matches what Enter runs (AA→AREA, L→LINE).
- ALIASEDIT opens a new editor modal (add/edit/delete rows) with an Apply
button; Apply persists to ocad.pgp, closing discards unapplied edits.
- Strip alias tokens from all 8 dispatch match-arm files and 71 module
CommandRegistration arrays, keeping canonical/synonym/distinct-command
names. ocad.pgp is now the sole source: deleting or remapping an alias
there takes effect. CUI stays on the keyboard-shortcut panel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:39:22 +03:00
}
2026-07-30 14:47:28 +03:00
super ::super ::ModalKind ::Options = > sized_flow (
ex ,
2026-07-28 09:33:12 +03:00
520 ,
500 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::window ::options ::view_window (
& self . default_save_format ,
& self . ui_theme ,
& self . theme_color_inputs ,
2026-08-02 18:53:38 +03:00
self . language ,
2026-07-30 14:47:28 +03:00
flow ,
)
} ,
2026-07-27 22:37:47 +03:00
) ,
2026-08-01 18:24:05 +03:00
super ::super ::ModalKind ::FindReplace = > automatic_flow ( ex , | flow | {
2026-07-30 17:56:54 +03:00
crate ::ui ::window ::find_replace ::view_window (
& self . find_replace . search ,
& self . find_replace . replacement ,
& self . find_replace . status ,
2026-08-01 18:24:05 +03:00
flow ,
)
} ) ,
2026-07-29 16:28:20 +03:00
super ::super ::ModalKind ::PluginManager = > {
#[ cfg(not(target_arch = " wasm32 " )) ]
{
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-07-29 16:28:20 +03:00
940 ,
600 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::window ::plugin_manager ::view_window (
& self . disabled_plugins ,
& self . external_plugins ,
& self . loaded_plugin_ids ,
2026-07-30 16:34:07 +03:00
& self . plugin_load_errors ,
2026-07-30 14:47:28 +03:00
crate ::ui ::window ::plugin_manager ::MarketView {
registry : & self . plugin_registry ,
registry_loading : self . plugin_registry_loading ,
registry_error : self . plugin_registry_error . as_deref ( ) ,
registry_error_details_open : self
. plugin_registry_error_details_open ,
input : & self . plugin_repo_input ,
search : & self . plugin_search_input ,
repos : & self . plugin_repos ,
release_tags : & self . repo_release_tags ,
selected_tag : & self . repo_selected_tag ,
selected_repo : self . selected_plugin_repo . as_deref ( ) ,
readmes : & self . plugin_readmes ,
readme_loading : & self . plugin_readme_loading ,
status : & self . marketplace_status ,
} ,
& self . active_theme ,
flow ,
)
} ,
2026-07-29 16:28:20 +03:00
)
}
#[ cfg(target_arch = " wasm32 " ) ]
{
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | {
container ( crate ::ui ::window ::plugin_manager ::view_web_notice ( ) )
. width ( flow . width )
. height ( flow . height )
. into ( )
} )
2026-07-29 16:28:20 +03:00
}
}
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
super ::super ::ModalKind ::UpdateNotice = > {
let latest = self . update_notice_version . as_deref ( ) . unwrap_or ( " ? " ) ;
let body = self . update_notice_body . as_deref ( ) . unwrap_or ( " " ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
560 ,
460 ,
| flow | crate ::ui ::window ::update_notice ::view_window ( latest , body , flow ) ,
)
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
super ::super ::ModalKind ::Layers = > {
let tab = & self . tabs [ self . active_tab ] ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
900 ,
360 ,
| flow | tab . layers . view_window ( self . layer_name_col_w , flow ) ,
)
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
2026-07-29 18:00:41 +03:00
super ::super ::ModalKind ::LayerStateManager = > {
let states = self . tabs [ self . active_tab ] . scene . document . layer_states ( ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-07-29 18:00:41 +03:00
720 ,
420 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::window ::layer_state_manager ::view_window (
states . clone ( ) ,
self . layer_state_selected . as_deref ( ) ,
& self . layer_state_name_buf ,
& self . layer_state_description_buf ,
& self . layer_state_filter ,
flow ,
)
} ,
2026-07-29 18:00:41 +03:00
)
}
2026-07-29 18:39:55 +03:00
super ::super ::ModalKind ::LayerStateEditor = > {
let tab = & self . tabs [ self . active_tab ] ;
if let Some ( state ) = self . layer_state_edit_draft . as_ref ( ) {
let mut linetypes : Vec < String > = tab
. scene
. document
. line_types
. iter ( )
. map ( | line_type | line_type . name . clone ( ) )
. collect ( ) ;
for layer in & state . layers {
if ! layer . line_type . is_empty ( )
& & ! linetypes
. iter ( )
. any ( | name | name . eq_ignore_ascii_case ( & layer . line_type ) )
{
linetypes . push ( layer . line_type . clone ( ) ) ;
}
}
linetypes . sort_by_key ( | name | name . to_lowercase ( ) ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-07-29 18:39:55 +03:00
1180 ,
560 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::window ::layer_state_manager ::view_editor (
state ,
& self . layer_state_edit_filter ,
self . layer_state_edit_color_open ,
linetypes . clone ( ) ,
flow ,
)
} ,
2026-07-29 18:39:55 +03:00
)
} else {
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | {
2026-08-02 22:09:25 +03:00
container ( text ( t! ( " The selected layer state is no longer available. " ) ) )
2026-07-29 18:39:55 +03:00
. padding ( 16 )
2026-08-01 18:24:05 +03:00
. width ( flow . width )
. height ( flow . height )
. into ( )
} )
2026-07-29 18:39:55 +03:00
}
}
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
super ::super ::ModalKind ::Plot = > {
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-07-31 12:11:18 +03:00
760 ,
540 ,
2026-08-04 11:29:11 +03:00
| flow | {
crate ::ui ::window ::plot ::view_window (
& self . plot_dialog ,
self . print_all_options ,
flow ,
)
} ,
2026-07-30 14:47:28 +03:00
)
feat(plot): unified plot/print dialog, retire Page Setup
Replace the old Page Setup panel with a single OCS-styled plot/print
dialog (dropdowns for printer, paper, orientation, rotation, plot area,
scale, quality, shaded plot; checkboxes for plot options). PLOT / PRINT
/ PAGESETUP all open it.
- Printer output via lp: -d printer, -n copies, -o ColorModel=Gray,
print-quality, Resolution; Windows printto verb; list_printers via
lpstat. Preview opens a temp PDF in the OS viewer (never a save
dialog). PDF export reuses the tested pipeline.
- Window pick returns to the new dialog (was the old Page Setup) and the
clipped window plot drives PDF / printer / preview.
- Remember the user's print preferences across sessions in
config/plot.txt (printer, copies, quality, output options, area,
scale); drawing-specific fields (offset/center/rotation) seed from the
layout. Default plot area Window, scale Fit.
- Delete src/ui/window/page_setup.rs and its ModalKind / Message /
buffer state; fold on_page_setup_commit into apply_plot_page_settings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 10:27:54 +03:00
}
2026-08-04 11:29:11 +03:00
super ::super ::ModalKind ::PrintAll = > sized_flow (
ex ,
520 ,
420 ,
| flow | {
crate ::ui ::window ::print_all ::view_window (
& self . print_all_layouts ,
self . plot_dialog . printer . as_deref ( ) ,
flow ,
)
} ,
) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
super ::super ::ModalKind ::LayoutManager = > {
let i = self . active_tab ;
let layouts = self . tabs [ i ] . scene . layout_names ( ) ;
let current = self . tabs [ i ] . scene . current_layout . clone ( ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
640 ,
320 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::window ::layout_manager ::view_window (
layouts . clone ( ) ,
& self . layout_manager_selected ,
& self . layout_manager_rename_buf ,
current . clone ( ) ,
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
)
}
2026-07-13 10:39:14 +03:00
super ::super ::ModalKind ::ScaleManager = > {
let tab = & self . tabs [ self . active_tab ] ;
let scales : Vec < ( String , String ) > = tab
. scene
. scale_list ( )
. into_iter ( )
. map ( | ( name , _ , _ ) | {
let ratio = tab
. scene
. scale_paper_drawing ( & name )
. map ( | ( p , d ) | format! ( " {p} : {d} " ) )
. unwrap_or_default ( ) ;
( name , ratio )
2026-07-30 14:47:28 +03:00
} )
2026-07-13 10:39:14 +03:00
. collect ( ) ;
let current = tab . scene . document . header . current_annotation_scale . clone ( ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-07-13 10:39:14 +03:00
520 ,
360 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::scale_manager ::view_window (
& scales ,
& self . scale_manager_selected ,
& current ,
self . scale_rename . as_deref ( ) ,
& self . scale_rename_buf ,
& self . scale_manager_paper_buf ,
& self . scale_manager_drawing_buf ,
flow ,
)
} ,
2026-07-13 10:39:14 +03:00
)
}
2026-07-13 22:38:29 +03:00
super ::super ::ModalKind ::AnnoObjectScale = > {
let tab = & self . tabs [ self . active_tab ] ;
let entity = self . anno_object_scale_target ;
// Which scales the object currently has a representation for.
let members : Vec < acadrust ::types ::Handle > = entity
. map ( | h | {
crate ::scene ::annotative ::object_scale_memberships (
& tab . scene . document ,
h ,
)
. into_iter ( )
. map ( | ( _ , sh ) | sh )
. collect ( )
} )
. unwrap_or_default ( ) ;
let label = entity
. and_then ( | h | tab . scene . document . get_entity ( h ) )
. map ( | e | match e {
acadrust ::EntityType ::Text ( _ ) = > " TEXT " ,
acadrust ::EntityType ::MText ( _ ) = > " MTEXT " ,
acadrust ::EntityType ::Insert ( _ ) = > " BLOCK " ,
acadrust ::EntityType ::MultiLeader ( _ ) = > " MULTILEADER " ,
_ = > " OBJECT " ,
} )
. unwrap_or ( " — " ) ;
let scales : Vec < ( String , String , bool ) > = tab
. scene
. scale_list ( )
. into_iter ( )
. map ( | ( name , _ , _ ) | {
let sh = tab . scene . scale_object_handle ( & name ) ;
let ratio = tab
. scene
. scale_paper_drawing ( & name )
. map ( | ( p , d ) | format! ( " {p} : {d} " ) )
. unwrap_or_default ( ) ;
let is_member = sh . map ( | h | members . contains ( & h ) ) . unwrap_or ( false ) ;
( name , ratio , is_member )
} )
. collect ( ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-07-13 22:38:29 +03:00
360 ,
420 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::anno_object_scale ::view_window (
& label ,
& scales ,
flow ,
)
} ,
2026-07-13 22:38:29 +03:00
)
}
2026-07-30 14:47:28 +03:00
super ::super ::ModalKind ::Plotstyle = > sized_flow (
ex ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
780 ,
540 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::plotstyle ::view_window (
self . active_plot_style . as_ref ( ) ,
self . plotstyle_panel_aci ,
& self . ps_color_buf ,
& self . ps_lineweight_buf ,
& self . ps_screening_buf ,
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
) ,
super ::super ::ModalKind ::TextStyle = > {
let tab = & self . tabs [ self . active_tab ] ;
2026-08-03 02:01:47 +03:00
let doc = & tab . scene . document ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
let styles : Vec < String > = tab
. scene
. document
. text_styles
. iter ( )
. map ( | s | s . name . clone ( ) )
. collect ( ) ;
2026-08-03 02:01:47 +03:00
let selected_style = doc
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
. text_styles
2026-08-03 02:01:47 +03:00
. get ( & self . textstyle_selected ) ;
let ( backward , upside_down , vertical , annotative , read_only ) = selected_style
. map ( | style | {
(
style . flags . backward ,
style . flags . upside_down ,
style . is_vertical ,
style . annotative ,
style . xref_dependent ,
)
} )
. unwrap_or ( ( false , false , false , false , false ) ) ;
let in_use = self . style_in_use (
crate ::app ::StyleKind ::Text ,
& self . textstyle_selected ,
) ;
let compare_opts : Vec < String > = styles
. iter ( )
. filter ( | name | ! name . eq_ignore_ascii_case ( & self . textstyle_selected ) )
. cloned ( )
. collect ( ) ;
let compare_name = compare_opts
. iter ( )
. find ( | name | name . eq_ignore_ascii_case ( & self . textstyle_compare ) )
. cloned ( )
. or_else ( | | compare_opts . first ( ) . cloned ( ) )
. unwrap_or_default ( ) ;
let mut comparison_sections = Vec ::new ( ) ;
if let ( Some ( a ) , Some ( b ) ) = ( selected_style , doc . text_styles . get ( & compare_name ) ) {
if (
& a . font_file ,
& a . big_font_file ,
& a . true_type_font ,
a . is_shape_file ,
) ! = (
& b . font_file ,
& b . big_font_file ,
& b . true_type_font ,
b . is_shape_file ,
) {
comparison_sections . push ( crate ::i18n ::translate ( " Fonts " ) . into_owned ( ) ) ;
}
if ( a . height , a . width_factor , a . oblique_angle , a . last_height )
! = ( b . height , b . width_factor , b . oblique_angle , b . last_height )
{
comparison_sections . push ( crate ::i18n ::translate ( " Size " ) . into_owned ( ) ) ;
}
if ( a . flags , a . is_vertical , a . annotative )
! = ( b . flags , b . is_vertical , b . annotative )
{
comparison_sections . push ( crate ::i18n ::translate ( " Effects " ) . into_owned ( ) ) ;
}
}
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-08-03 02:01:47 +03:00
960 ,
680 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::textstyle ::view_window (
crate ::ui ::style ::textstyle ::TextStyleView {
styles : styles . clone ( ) ,
selected : & self . textstyle_selected ,
current : & tab . scene . document . header . current_text_style_name ,
2026-08-03 02:01:47 +03:00
tab : self . textstyle_tab ,
compare_name : compare_name . clone ( ) ,
compare_opts : compare_opts . clone ( ) ,
comparison_sections : comparison_sections . clone ( ) ,
read_only ,
in_use ,
2026-07-30 14:47:28 +03:00
font_buf : & self . textstyle_font ,
width_buf : & self . textstyle_width ,
oblique_buf : & self . textstyle_oblique ,
height_buf : & self . textstyle_height ,
bigfont_buf : & self . textstyle_bigfont ,
ttf_buf : & self . textstyle_ttf ,
backward ,
upside_down ,
2026-08-03 02:01:47 +03:00
vertical ,
2026-07-30 14:47:28 +03:00
annotative ,
rename_active : self . style_rename . as_deref ( ) ,
rename_buf : & self . style_rename_buf ,
} ,
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
)
}
super ::super ::ModalKind ::MlStyle = > {
use acadrust ::objects ::ObjectType ;
let tab = & self . tabs [ self . active_tab ] ;
let styles : Vec < String > = tab
. scene
. document
. objects
. values ( )
. filter_map ( | o | match o {
ObjectType ::MLineStyle ( s ) = > Some ( s . name . clone ( ) ) ,
_ = > None ,
} )
. collect ( ) ;
let selected_style = tab . scene . document . objects . values ( ) . find_map ( | o | match o {
ObjectType ::MLineStyle ( s ) if s . name = = self . mlstyle_selected = > Some ( s ) ,
_ = > None ,
} ) ;
2026-08-03 02:01:47 +03:00
let compare_opts : Vec < String > = styles
. iter ( )
. filter ( | name | ! name . eq_ignore_ascii_case ( & self . mlstyle_selected ) )
. cloned ( )
. collect ( ) ;
let compare_name = compare_opts
. iter ( )
. find ( | name | name . eq_ignore_ascii_case ( & self . mlstyle_compare ) )
. cloned ( )
. or_else ( | | compare_opts . first ( ) . cloned ( ) )
. unwrap_or_default ( ) ;
let compare_style = tab . scene . document . objects . values ( ) . find_map ( | object | match object {
ObjectType ::MLineStyle ( style ) if style . name = = compare_name = > Some ( style ) ,
_ = > None ,
} ) ;
let mut comparison_sections = Vec ::new ( ) ;
if let ( Some ( a ) , Some ( b ) ) = ( selected_style , compare_style ) {
if ( & a . description , a . flags , a . fill_color , a . start_angle , a . end_angle )
! = ( & b . description , b . flags , b . fill_color , b . start_angle , b . end_angle )
{
comparison_sections . push ( crate ::i18n ::translate ( " Caps and Fill " ) . into_owned ( ) ) ;
}
if a . elements ! = b . elements {
comparison_sections . push ( crate ::i18n ::translate ( " Elements " ) . into_owned ( ) ) ;
}
}
let in_use = self . style_in_use (
crate ::app ::StyleKind ::MLine ,
& self . mlstyle_selected ,
) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-08-03 02:01:47 +03:00
960 ,
680 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::mlstyle ::view_window (
2026-08-03 02:01:47 +03:00
crate ::ui ::style ::mlstyle ::MlStyleView {
styles : styles . clone ( ) ,
selected : & self . mlstyle_selected ,
style : selected_style ,
current : tab . scene . document . header . multiline_style . clone ( ) ,
tab : self . mlstyle_tab ,
compare_name : compare_name . clone ( ) ,
compare_opts : compare_opts . clone ( ) ,
comparison_sections : comparison_sections . clone ( ) ,
in_use ,
description : & self . mln_description ,
start_angle : & self . mln_start_angle ,
end_angle : & self . mln_end_angle ,
fill_color : & self . mln_fill_color ,
elements : & self . mln_elements ,
rename_active : self . style_rename . as_deref ( ) ,
rename_buf : & self . style_rename_buf ,
} ,
2026-07-30 14:47:28 +03:00
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
)
}
super ::super ::ModalKind ::TableStyle = > {
use acadrust ::objects ::ObjectType ;
let tab = & self . tabs [ self . active_tab ] ;
let styles : Vec < String > = tab
. scene
. document
. objects
. values ( )
. filter_map ( | o | match o {
ObjectType ::TableStyle ( s ) = > Some ( s . name . clone ( ) ) ,
_ = > None ,
} )
. collect ( ) ;
let selected_style = tab . scene . document . objects . values ( ) . find_map ( | o | match o {
ObjectType ::TableStyle ( s ) if s . name = = self . tablestyle_selected = > Some ( s ) ,
_ = > None ,
} ) ;
2026-08-03 02:01:47 +03:00
let compare_opts : Vec < String > = styles
. iter ( )
. filter ( | name | ! name . eq_ignore_ascii_case ( & self . tablestyle_selected ) )
. cloned ( )
. collect ( ) ;
let compare_name = compare_opts
. iter ( )
. find ( | name | name . eq_ignore_ascii_case ( & self . tablestyle_compare ) )
. cloned ( )
. or_else ( | | compare_opts . first ( ) . cloned ( ) )
. unwrap_or_default ( ) ;
let compare_style = tab . scene . document . objects . values ( ) . find_map ( | object | match object {
ObjectType ::TableStyle ( style ) if style . name = = compare_name = > Some ( style ) ,
_ = > None ,
} ) ;
let mut comparison_sections = Vec ::new ( ) ;
if let ( Some ( a ) , Some ( b ) ) = ( selected_style , compare_style ) {
if (
& a . description ,
a . flow_direction ,
a . horizontal_margin ,
a . vertical_margin ,
a . title_suppressed ,
a . header_suppressed ,
a . annotative ,
) ! = (
& b . description ,
b . flow_direction ,
b . horizontal_margin ,
b . vertical_margin ,
b . title_suppressed ,
b . header_suppressed ,
b . annotative ,
) {
comparison_sections . push ( crate ::i18n ::translate ( " General " ) . into_owned ( ) ) ;
}
for ( label , different ) in [
( " Data Row " , a . data_row_style ! = b . data_row_style ) ,
( " Header Row " , a . header_row_style ! = b . header_row_style ) ,
( " Title Row " , a . title_row_style ! = b . title_row_style ) ,
] {
if different {
comparison_sections . push ( crate ::i18n ::translate ( label ) . into_owned ( ) ) ;
}
}
}
let in_use = self . style_in_use (
crate ::app ::StyleKind ::Table ,
& self . tablestyle_selected ,
) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-08-03 02:01:47 +03:00
960 ,
680 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::tablestyle ::view_window (
2026-08-03 02:01:47 +03:00
crate ::ui ::style ::tablestyle ::TableStyleView {
styles : styles . clone ( ) ,
selected : & self . tablestyle_selected ,
current : & tab . scene . document . header . current_table_style_name ,
style : selected_style ,
tab : self . tablestyle_tab ,
compare_name : compare_name . clone ( ) ,
compare_opts : compare_opts . clone ( ) ,
comparison_sections : comparison_sections . clone ( ) ,
in_use ,
hmargin : & self . ts_hmargin ,
vmargin : & self . ts_vmargin ,
description : & self . ts_description ,
cell_textstyle : & self . ts_cell_textstyle ,
cell_height : & self . ts_cell_height ,
cell_textcolor : & self . ts_cell_textcolor ,
cell_fillcolor : & self . ts_cell_fillcolor ,
cell_datatype : & self . ts_cell_datatype ,
cell_unittype : & self . ts_cell_unittype ,
cell_format : & self . ts_cell_format ,
border_lw : & self . ts_border_lw ,
border_color : & self . ts_border_color ,
border_spacing : & self . ts_border_spacing ,
rename_active : self . style_rename . as_deref ( ) ,
rename_buf : & self . style_rename_buf ,
color_open : self . ts_color_open ,
} ,
2026-07-30 14:47:28 +03:00
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
)
}
super ::super ::ModalKind ::MLeaderStyle = > {
use acadrust ::objects ::ObjectType ;
let tab = & self . tabs [ self . active_tab ] ;
let styles : Vec < String > = tab
. scene
. document
. objects
. values ( )
. filter_map ( | o | match o {
ObjectType ::MultiLeaderStyle ( s ) = > Some ( s . name . clone ( ) ) ,
_ = > None ,
} )
. collect ( ) ;
let selected_style = tab . scene . document . objects . values ( ) . find_map ( | o | match o {
ObjectType ::MultiLeaderStyle ( s ) if s . name = = self . mleaderstyle_selected = > {
Some ( s )
}
_ = > None ,
} ) ;
let doc = & tab . scene . document ;
let mut block_opts : Vec < String > = vec! [ " None " . to_string ( ) ] ;
block_opts . extend ( doc . block_records . iter ( ) . map ( | b | b . name . clone ( ) ) ) ;
2026-08-03 02:01:47 +03:00
let mut arrow_opts : Vec < String > = vec! [ " Closed filled " . to_string ( ) ] ;
arrow_opts . extend ( doc . block_records . iter ( ) . map ( | b | b . name . clone ( ) ) ) ;
let mut lt_opts : Vec < String > = vec! [ " ByBlock " . to_string ( ) ] ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
lt_opts . extend ( doc . line_types . iter ( ) . map ( | lt | lt . name . clone ( ) ) ) ;
let mut textstyle_opts : Vec < String > = vec! [ " None " . to_string ( ) ] ;
textstyle_opts . extend ( doc . text_styles . iter ( ) . map ( | t | t . name . clone ( ) ) ) ;
let opt_block = | h : Option < acadrust ::types ::Handle > | -> String {
match h {
Some ( h ) = > doc
. block_records
. iter ( )
. find ( | b | b . handle = = h )
. map ( | b | b . name . clone ( ) )
. unwrap_or_else ( | | " None " . to_string ( ) ) ,
None = > " None " . to_string ( ) ,
}
} ;
let opt_lt = | h : Option < acadrust ::types ::Handle > | -> String {
match h {
Some ( h ) = > doc
. line_types
. iter ( )
. find ( | lt | lt . handle = = h )
. map ( | lt | lt . name . clone ( ) )
2026-08-03 02:01:47 +03:00
. unwrap_or_else ( | | " ByBlock " . to_string ( ) ) ,
None = > " ByBlock " . to_string ( ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
} ;
let opt_ts = | h : Option < acadrust ::types ::Handle > | -> String {
match h {
Some ( h ) = > doc
. text_styles
. iter ( )
. find ( | t | t . handle = = h )
. map ( | t | t . name . clone ( ) )
. unwrap_or_else ( | | " None " . to_string ( ) ) ,
None = > " None " . to_string ( ) ,
}
} ;
let ( line_type_name , arrowhead_name , text_style_name , block_content_name ) =
match selected_style {
Some ( s ) = > (
opt_lt ( s . line_type_handle ) ,
2026-08-03 02:01:47 +03:00
s . arrowhead_handle
. and_then ( | handle | {
doc . block_records
. iter ( )
. find ( | record | record . handle = = handle )
. map ( | record | record . name . clone ( ) )
} )
. unwrap_or_else ( | | " Closed filled " . to_string ( ) ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
opt_ts ( s . text_style_handle ) ,
opt_block ( s . block_content_handle ) ,
) ,
None = > Default ::default ( ) ,
} ;
2026-08-03 02:01:47 +03:00
let compare_opts : Vec < String > = styles
. iter ( )
. filter ( | name | ! name . eq_ignore_ascii_case ( & self . mleaderstyle_selected ) )
. cloned ( )
. collect ( ) ;
let compare_name = compare_opts
. iter ( )
. find ( | name | name . eq_ignore_ascii_case ( & self . mleaderstyle_compare ) )
. cloned ( )
. or_else ( | | compare_opts . first ( ) . cloned ( ) )
. unwrap_or_default ( ) ;
let compare_style = doc . objects . values ( ) . find_map ( | object | match object {
ObjectType ::MultiLeaderStyle ( style ) if style . name = = compare_name = > Some ( style ) ,
_ = > None ,
} ) ;
let mut comparison_sections = Vec ::new ( ) ;
if let ( Some ( a ) , Some ( b ) ) = ( selected_style , compare_style ) {
if (
& a . description ,
a . path_type ,
a . line_color ,
a . line_type_handle ,
a . line_weight ,
a . arrowhead_handle ,
a . arrowhead_size ,
a . break_gap_size ,
) ! = (
& b . description ,
b . path_type ,
b . line_color ,
b . line_type_handle ,
b . line_weight ,
b . arrowhead_handle ,
b . arrowhead_size ,
b . break_gap_size ,
) {
comparison_sections . push ( crate ::i18n ::translate ( " Leader Format " ) . into_owned ( ) ) ;
}
if (
a . enable_landing ,
a . enable_dogleg ,
a . landing_distance ,
a . landing_gap ,
a . scale_factor ,
a . align_space ,
a . max_leader_points ,
a . first_segment_angle ,
a . second_segment_angle ,
a . leader_draw_order ,
a . multileader_draw_order ,
a . is_annotative ,
) ! = (
b . enable_landing ,
b . enable_dogleg ,
b . landing_distance ,
b . landing_gap ,
b . scale_factor ,
b . align_space ,
b . max_leader_points ,
b . first_segment_angle ,
b . second_segment_angle ,
b . leader_draw_order ,
b . multileader_draw_order ,
b . is_annotative ,
) {
comparison_sections . push ( crate ::i18n ::translate ( " Leader Structure " ) . into_owned ( ) ) ;
}
if (
a . content_type ,
& a . default_text ,
a . text_style_handle ,
a . text_height ,
a . text_color ,
a . text_angle_type ,
a . text_alignment ,
) ! = (
b . content_type ,
& b . default_text ,
b . text_style_handle ,
b . text_height ,
b . text_color ,
b . text_angle_type ,
b . text_alignment ,
) | | (
a . text_left_attachment ,
a . text_right_attachment ,
a . text_top_attachment ,
a . text_bottom_attachment ,
a . text_attachment_direction ,
a . text_frame ,
a . text_always_left ,
) ! = (
b . text_left_attachment ,
b . text_right_attachment ,
b . text_top_attachment ,
b . text_bottom_attachment ,
b . text_attachment_direction ,
b . text_frame ,
b . text_always_left ,
) {
comparison_sections . push ( crate ::i18n ::translate ( " Content " ) . into_owned ( ) ) ;
}
if (
a . block_content_handle ,
a . block_content_color ,
a . block_content_connection ,
a . block_content_rotation ,
a . block_content_scale_x ,
a . block_content_scale_y ,
a . block_content_scale_z ,
a . enable_block_scale ,
a . enable_block_rotation ,
) ! = (
b . block_content_handle ,
b . block_content_color ,
b . block_content_connection ,
b . block_content_rotation ,
b . block_content_scale_x ,
b . block_content_scale_y ,
b . block_content_scale_z ,
b . enable_block_scale ,
b . enable_block_rotation ,
) {
comparison_sections . push ( crate ::i18n ::translate ( " Block Content " ) . into_owned ( ) ) ;
}
}
let in_use = self . style_in_use (
crate ::app ::StyleKind ::MLeader ,
& self . mleaderstyle_selected ,
) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
2026-08-03 02:01:47 +03:00
960 ,
680 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::mleaderstyle ::view_window (
crate ::ui ::style ::mleaderstyle ::MLeaderStyleView {
styles : styles . clone ( ) ,
selected : & self . mleaderstyle_selected ,
style : selected_style ,
current : tab . active_mleader_style . clone ( ) ,
2026-08-03 02:01:47 +03:00
tab : self . mleaderstyle_tab ,
compare_name : compare_name . clone ( ) ,
compare_opts : compare_opts . clone ( ) ,
comparison_sections : comparison_sections . clone ( ) ,
in_use ,
2026-07-30 14:47:28 +03:00
landing_distance : & self . mls_landing_distance ,
landing_gap : & self . mls_landing_gap ,
arrowhead_size : & self . mls_arrowhead_size ,
text_height : & self . mls_text_height ,
scale_factor : & self . mls_scale_factor ,
break_gap : & self . mls_break_gap ,
first_seg_angle : & self . mls_first_seg_angle ,
second_seg_angle : & self . mls_second_seg_angle ,
max_points : & self . mls_max_points ,
default_text : & self . mls_default_text ,
line_color : & self . mls_line_color ,
text_color : & self . mls_text_color ,
description : & self . mls_description ,
align_space : & self . mls_align_space ,
block_color : & self . mls_block_color ,
block_rotation : & self . mls_block_rotation ,
block_scale_x : & self . mls_block_scale_x ,
block_scale_y : & self . mls_block_scale_y ,
block_scale_z : & self . mls_block_scale_z ,
block_opts : block_opts . clone ( ) ,
2026-08-03 02:01:47 +03:00
arrow_opts : arrow_opts . clone ( ) ,
2026-07-30 14:47:28 +03:00
lt_opts : lt_opts . clone ( ) ,
textstyle_opts : textstyle_opts . clone ( ) ,
line_type_name : line_type_name . clone ( ) ,
arrowhead_name : arrowhead_name . clone ( ) ,
text_style_name : text_style_name . clone ( ) ,
block_content_name : block_content_name . clone ( ) ,
rename_active : self . style_rename . as_deref ( ) ,
rename_buf : & self . style_rename_buf ,
color_open : self . mls_color_open ,
} ,
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
)
}
super ::super ::ModalKind ::DimStyle = > {
let tab = & self . tabs [ self . active_tab ] ;
let styles : Vec < String > = tab
. scene
. document
. dim_styles
. iter ( )
. map ( | s | s . name . clone ( ) )
. collect ( ) ;
let doc = & tab . scene . document ;
// Dropdown options (names must match the records exactly so the
// selection can be resolved back to a handle on the update side).
let mut block_opts : Vec < String > = vec! [ " Default " . to_string ( ) ] ;
2026-08-02 16:06:37 +03:00
block_opts . extend (
doc . block_records
. iter ( )
. filter ( | b | {
! b . is_layout ( )
& & ! b . is_model_space ( )
& & ! b . is_paper_space ( )
& & ! b . flags . is_xref
& & ! b . flags . is_xref_overlay
& & ! b . flags . is_external
& & ! b . name . starts_with ( '*' )
} )
. map ( | b | b . name . clone ( ) ) ,
) ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
let mut lt_opts : Vec < String > = vec! [ " ByBlock " . to_string ( ) ] ;
lt_opts . extend ( doc . line_types . iter ( ) . map ( | lt | lt . name . clone ( ) ) ) ;
2026-08-03 02:01:47 +03:00
let text_style_opts : Vec < String > =
doc . text_styles . iter ( ) . map ( | style | style . name . clone ( ) ) . collect ( ) ;
let text_style_fixed_height = doc
. text_styles
. get ( & self . ds_dimtxsty )
. map ( | style | style . height )
. filter ( | height | * height > 0.0 ) ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
let blk_name = | h : acadrust ::types ::Handle | -> String {
if h . is_null ( ) {
" Default " . to_string ( )
} else {
doc . block_records
. iter ( )
. find ( | b | b . handle = = h )
. map ( | b | b . name . clone ( ) )
. unwrap_or_else ( | | " Default " . to_string ( ) )
}
} ;
let lt_name = | h : acadrust ::types ::Handle | -> String {
if h . is_null ( ) {
" ByBlock " . to_string ( )
} else {
doc . line_types
. iter ( )
. find ( | lt | lt . handle = = h )
. map ( | lt | lt . name . clone ( ) )
. unwrap_or_else ( | | " ByBlock " . to_string ( ) )
}
} ;
let ds_sel = doc . dim_styles . get ( & self . dimstyle_selected ) ;
2026-08-03 02:01:47 +03:00
let read_only = ds_sel . is_some_and ( | style | {
style . xref_reference | | style . xref_dependent | | ! style . xref_handle . is_null ( )
} ) ;
let in_use = doc . entities ( ) . any ( | entity | {
matches! ( entity , acadrust ::EntityType ::Dimension ( dimension )
if dimension . base ( ) . style_name . eq_ignore_ascii_case ( & self . dimstyle_selected ) )
} ) ;
let compare_opts : Vec < String > = styles
. iter ( )
. filter ( | name | ! name . eq_ignore_ascii_case ( & self . dimstyle_selected ) )
. cloned ( )
. collect ( ) ;
let compare_name = compare_opts
. iter ( )
. find ( | name | name . eq_ignore_ascii_case ( & self . dimstyle_compare ) )
. cloned ( )
. or_else ( | | compare_opts . first ( ) . cloned ( ) )
. unwrap_or_default ( ) ;
let mut comparison_sections = Vec ::new ( ) ;
if let ( Some ( a ) , Some ( b ) ) = ( ds_sel , doc . dim_styles . get ( & compare_name ) ) {
if ( a . dimdle , a . dimdli , a . dimgap , a . dimclrd , a . dimlwd , a . dimsd1 , a . dimsd2 )
! = ( b . dimdle , b . dimdli , b . dimgap , b . dimclrd , b . dimlwd , b . dimsd1 , b . dimsd2 )
| | ( a . dimexe , a . dimexo , a . dimclre , a . dimlwe , a . dimse1 , a . dimse2 , a . dimfxl , a . dimfxlon )
! = ( b . dimexe , b . dimexo , b . dimclre , b . dimlwe , b . dimse1 , b . dimse2 , b . dimfxl , b . dimfxlon )
| | ( a . dimltex_handle , a . dimltex1_handle , a . dimltex2_handle )
! = ( b . dimltex_handle , b . dimltex1_handle , b . dimltex2_handle )
{
comparison_sections . push ( crate ::i18n ::translate ( " Lines " ) . into_owned ( ) ) ;
}
if ( a . dimasz , a . dimblk , a . dimblk1 , a . dimblk2 , a . dimldrblk , a . dimsah , a . dimcen , a . dimtsz )
! = ( b . dimasz , b . dimblk , b . dimblk1 , b . dimblk2 , b . dimldrblk , b . dimsah , b . dimcen , b . dimtsz )
| | ( a . dimarcsym , a . dimjogang ) ! = ( b . dimarcsym , b . dimjogang )
{
comparison_sections . push ( crate ::i18n ::translate ( " Symbols and Arrows " ) . into_owned ( ) ) ;
}
if ( a . dimclrt , a . dimtxt , & a . dimtxsty , a . dimjust , a . dimtad , a . dimtvp )
! = ( b . dimclrt , b . dimtxt , & b . dimtxsty , b . dimjust , b . dimtad , b . dimtvp )
| | ( a . dimtih , a . dimtoh , a . dimtfill , a . dimtfillclr , a . dimtxtdirection )
! = ( b . dimtih , b . dimtoh , b . dimtfill , b . dimtfillclr , b . dimtxtdirection )
{
comparison_sections . push ( crate ::i18n ::translate ( " Text " ) . into_owned ( ) ) ;
}
if ( a . dimatfit , a . dimtix , a . dimsoxd , a . dimtmove , a . dimupt , a . dimtofl , a . dimscale , a . annotative )
! = ( b . dimatfit , b . dimtix , b . dimsoxd , b . dimtmove , b . dimupt , b . dimtofl , b . dimscale , b . annotative )
{
comparison_sections . push ( crate ::i18n ::translate ( " Fit " ) . into_owned ( ) ) ;
}
if ( a . dimlfac , a . dimlunit , a . dimdec , & a . dimpost , a . dimdsep , a . dimrnd , a . dimzin , a . dimfrac )
! = ( b . dimlfac , b . dimlunit , b . dimdec , & b . dimpost , b . dimdsep , b . dimrnd , b . dimzin , b . dimfrac )
| | ( a . dimaunit , a . dimadec , a . dimazin ) ! = ( b . dimaunit , b . dimadec , b . dimazin )
{
comparison_sections . push ( crate ::i18n ::translate ( " Primary Units " ) . into_owned ( ) ) ;
}
if ( a . dimalt , a . dimaltf , a . dimaltd , a . dimaltu , a . dimalttd , a . dimaltrnd , & a . dimapost , a . dimaltz , a . dimalttz )
! = ( b . dimalt , b . dimaltf , b . dimaltd , b . dimaltu , b . dimalttd , b . dimaltrnd , & b . dimapost , b . dimaltz , b . dimalttz )
{
comparison_sections . push ( crate ::i18n ::translate ( " Alternate Units " ) . into_owned ( ) ) ;
}
if ( a . dimtol , a . dimlim , a . dimtp , a . dimtm , a . dimtdec , a . dimtfac , a . dimtolj , a . dimtzin )
! = ( b . dimtol , b . dimlim , b . dimtp , b . dimtm , b . dimtdec , b . dimtfac , b . dimtolj , b . dimtzin )
{
comparison_sections . push ( crate ::i18n ::translate ( " Tolerances " ) . into_owned ( ) ) ;
}
}
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
let (
dimblk_name ,
dimblk1_name ,
dimblk2_name ,
dimldrblk_name ,
dimltex_name ,
dimltex1_name ,
dimltex2_name ,
) = match ds_sel {
Some ( d ) = > (
blk_name ( d . dimblk ) ,
blk_name ( d . dimblk1 ) ,
blk_name ( d . dimblk2 ) ,
blk_name ( d . dimldrblk ) ,
lt_name ( d . dimltex_handle ) ,
lt_name ( d . dimltex1_handle ) ,
lt_name ( d . dimltex2_handle ) ,
) ,
None = > Default ::default ( ) ,
} ;
2026-08-03 02:01:47 +03:00
sized_flow ( ex , 960 , 680 , | flow | {
2026-07-30 14:47:28 +03:00
crate ::ui ::style ::dimstyle ::view_window (
styles . clone ( ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
& self . dimstyle_selected ,
& self . tabs [ self . active_tab ]
. scene
. document
. header
. current_dimstyle_name ,
self . dimstyle_tab ,
refactor: group ui/ style+popup dirs, rename cmd_result driver
- Group the flat src/ui/ dir: move the 9 style editors into ui/style/
(dimstyle, mleaderstyle, mlstyle, plotstyle, textstyle, tablestyle,
point_style, style_list, style_manager) and the 6 popups into
ui/popup/ (cycle, isolate, scale, selection_filter, snap, units).
Call sites repointed to crate::ui::style::/crate::ui::popup::; no
compat re-exports. ui/ root drops from 36 to 21 files.
- Rename app/cmd_result.rs -> app/command_driver.rs: the file is the
StepInput->feed_command driver, not the CmdResult type (which lives
in command.rs). Name now matches contents.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 23:34:10 +03:00
crate ::ui ::style ::dimstyle ::DimStyleValues {
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
dimdle : & self . ds_dimdle ,
dimdli : & self . ds_dimdli ,
dimgap : & self . ds_dimgap ,
dimexe : & self . ds_dimexe ,
dimexo : & self . ds_dimexo ,
dimsd1 : self . ds_dimsd1 ,
dimsd2 : self . ds_dimsd2 ,
dimse1 : self . ds_dimse1 ,
dimse2 : self . ds_dimse2 ,
dimasz : & self . ds_dimasz ,
dimcen : & self . ds_dimcen ,
dimtsz : & self . ds_dimtsz ,
dimtxt : & self . ds_dimtxt ,
dimtxsty : & self . ds_dimtxsty ,
dimtad : & self . ds_dimtad ,
dimtih : self . ds_dimtih ,
dimtoh : self . ds_dimtoh ,
dimscale : & self . ds_dimscale ,
dimlfac : & self . ds_dimlfac ,
dimlunit : & self . ds_dimlunit ,
dimdec : & self . ds_dimdec ,
dimpost : & self . ds_dimpost ,
dimtol : self . ds_dimtol ,
dimlim : self . ds_dimlim ,
dimtp : & self . ds_dimtp ,
dimtm : & self . ds_dimtm ,
dimtdec : & self . ds_dimtdec ,
dimtfac : & self . ds_dimtfac ,
annotative : self . ds_annotative ,
dimclrd : & self . ds_dimclrd ,
dimlwd : & self . ds_dimlwd ,
dimclre : & self . ds_dimclre ,
dimlwe : & self . ds_dimlwe ,
dimfxl : & self . ds_dimfxl ,
dimfxlon : self . ds_dimfxlon ,
dimsah : self . ds_dimsah ,
dimarcsym : & self . ds_dimarcsym ,
dimjogang : & self . ds_dimjogang ,
dimclrt : & self . ds_dimclrt ,
dimjust : & self . ds_dimjust ,
dimtvp : & self . ds_dimtvp ,
dimtfill : & self . ds_dimtfill ,
dimtfillclr : & self . ds_dimtfillclr ,
dimtxtdirection : self . ds_dimtxtdirection ,
dimatfit : & self . ds_dimatfit ,
dimtix : self . ds_dimtix ,
dimsoxd : self . ds_dimsoxd ,
dimtmove : & self . ds_dimtmove ,
dimupt : self . ds_dimupt ,
dimtofl : self . ds_dimtofl ,
dimdsep : & self . ds_dimdsep ,
dimrnd : & self . ds_dimrnd ,
dimzin : & self . ds_dimzin ,
dimfrac : & self . ds_dimfrac ,
dimaunit : & self . ds_dimaunit ,
dimadec : & self . ds_dimadec ,
dimazin : & self . ds_dimazin ,
dimalt : self . ds_dimalt ,
dimaltf : & self . ds_dimaltf ,
dimaltd : & self . ds_dimaltd ,
dimaltu : & self . ds_dimaltu ,
dimalttd : & self . ds_dimalttd ,
dimaltrnd : & self . ds_dimaltrnd ,
dimapost : & self . ds_dimapost ,
dimaltz : & self . ds_dimaltz ,
dimalttz : & self . ds_dimalttz ,
dimtolj : & self . ds_dimtolj ,
dimtzin : & self . ds_dimtzin ,
2026-07-30 14:47:28 +03:00
dimblk_name : dimblk_name . clone ( ) ,
dimblk1_name : dimblk1_name . clone ( ) ,
dimblk2_name : dimblk2_name . clone ( ) ,
dimldrblk_name : dimldrblk_name . clone ( ) ,
dimltex_name : dimltex_name . clone ( ) ,
dimltex1_name : dimltex1_name . clone ( ) ,
dimltex2_name : dimltex2_name . clone ( ) ,
block_opts : block_opts . clone ( ) ,
lt_opts : lt_opts . clone ( ) ,
2026-08-03 02:01:47 +03:00
text_style_opts : text_style_opts . clone ( ) ,
text_style_fixed_height ,
compare_name : compare_name . clone ( ) ,
compare_opts : compare_opts . clone ( ) ,
comparison_sections : comparison_sections . clone ( ) ,
read_only ,
in_use ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
color_open : self . ds_color_open . clone ( ) ,
} ,
self . style_rename . as_deref ( ) ,
& self . style_rename_buf ,
2026-07-30 14:47:28 +03:00
flow ,
)
} )
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
2026-08-01 18:24:05 +03:00
super ::super ::ModalKind ::AssocPrompt = > {
automatic_flow ( ex , default_assoc_dialog_window )
}
2026-06-29 11:47:37 +03:00
super ::super ::ModalKind ::AecDropWarning = > {
let src_label = self
. tabs
. get ( self . active_tab )
2026-07-27 22:37:47 +03:00
. map ( | t | {
let is_dxf = t
. current_path
. as_ref ( )
. and_then ( | path | path . extension ( ) )
. and_then ( | extension | extension . to_str ( ) )
. map ( | extension | extension . eq_ignore_ascii_case ( " dxf " ) )
. unwrap_or ( false ) ;
let version = if is_dxf {
t . scene . document . version
} else {
t . scene
. document
. dwg_source_version
. unwrap_or ( t . scene . document . version )
} ;
crate ::io ::format_for_version ( version , is_dxf )
} )
2026-06-29 11:47:37 +03:00
. unwrap_or_else ( | | " DWG " . to_string ( ) ) ;
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | {
2026-06-29 11:47:37 +03:00
aec_drop_dialog_window (
self . aec_drop_count ,
& self . save_dialog_format ,
& src_label ,
2026-08-01 18:24:05 +03:00
flow ,
)
} )
2026-06-29 11:47:37 +03:00
}
2026-07-27 13:13:58 +03:00
#[ cfg(not(target_arch = " wasm32 " )) ]
super ::super ::ModalKind ::FileInUse = > {
let ( path , error ) = self
. pending_save_failure
. as_ref ( )
. map ( | failure | {
(
failure . path . display ( ) . to_string ( ) ,
failure . error . clone ( ) ,
)
} )
. unwrap_or_default ( ) ;
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | file_in_use_dialog_window ( & path , & error , flow ) )
2026-07-27 13:13:58 +03:00
}
#[ cfg(not(target_arch = " wasm32 " )) ]
super ::super ::ModalKind ::ExternalChange = > {
let path = self
. pending_external_change
. as_ref ( )
. map ( | conflict | conflict . path . display ( ) . to_string ( ) )
. unwrap_or_default ( ) ;
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | external_change_dialog_window ( & path , flow ) )
2026-07-27 13:13:58 +03:00
}
2026-07-01 17:23:32 +03:00
super ::super ::ModalKind ::LayerDeleteWarning = > {
2026-07-01 17:44:19 +03:00
let ( names , count ) = self
2026-07-01 17:23:32 +03:00
. layer_delete_pending
. clone ( )
2026-07-01 17:44:19 +03:00
. unwrap_or_else ( | | ( Vec ::new ( ) , 0 ) ) ;
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | layer_delete_warning_window ( & names , count , flow ) )
2026-07-01 17:23:32 +03:00
}
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
super ::super ::ModalKind ::Unsaved = > {
let tab_name = match & self . pending_close {
Some ( super ::super ::PendingClose ::Tab ( idx ) ) = > self
. tabs
. get ( * idx )
. map ( | t | t . tab_display_name ( ) )
. unwrap_or_default ( ) ,
Some ( super ::super ::PendingClose ::Quit ) = > self
. tabs
. iter ( )
. find ( | t | t . dirty )
. map ( | t | t . tab_display_name ( ) )
. unwrap_or_default ( ) ,
None = > String ::new ( ) ,
} ;
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | unsaved_changes_dialog_window ( & tab_name , flow ) )
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
2026-07-30 14:47:28 +03:00
super ::super ::ModalKind ::PointStyle = > sized_flow (
ex ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
360 ,
470 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::style ::point_style ::view_window (
self . tabs [ self . active_tab ]
. scene
. document
. header
. point_display_mode ,
self . point_size_relative ,
& self . point_size_buf ,
flow ,
)
} ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
) ,
feat(attedit): enhanced attribute editor with 3 tabs
Grow the attribute editor into a three-tab enhanced editor:
- Attribute: the tag/prompt/value list; click a row to select it, edit
its value below.
- Text Options: the selected attribute's Text Style, Justification,
Height, Rotation, Width Factor, Oblique Angle, Backwards, Upside down.
- Properties: the selected attribute's Layer, Linetype, Color,
Lineweight (the colour list also surfaces a non-standard current
colour so it displays and round-trips).
Applying writes value, text-formatting and common-property edits back to
each attribute positionally (guarded on block name + count), with undo
and a repaint. OK/Cancel are replaced by a single Apply button in a top
toolbar that commits but keeps the dialog open, matching the other modal
windows — the frame ✕ closes and discards un-applied edits. The frame
adopts the shared style-window palette, tab styling and sizing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:06:03 +03:00
super ::super ::ModalKind ::AttributeEditor = > {
let doc = & self . tabs [ self . active_tab ] . scene . document ;
let layers : Vec < String > = doc . layers . iter ( ) . map ( | l | l . name . clone ( ) ) . collect ( ) ;
let mut linetypes : Vec < String > = vec! [ " ByLayer " . to_string ( ) ] ;
linetypes . extend (
doc . line_types
. iter ( )
. map ( | lt | lt . name . clone ( ) )
. filter ( | n | ! n . is_empty ( ) & & n ! = " ByLayer " ) ,
) ;
let styles : Vec < String > = doc
. text_styles
. iter ( )
. map ( | s | s . name . trim ( ) . to_string ( ) )
. filter ( | n | ! n . is_empty ( ) )
. collect ( ) ;
2026-07-30 14:47:28 +03:00
sized_flow (
ex ,
feat(attedit): enhanced attribute editor with 3 tabs
Grow the attribute editor into a three-tab enhanced editor:
- Attribute: the tag/prompt/value list; click a row to select it, edit
its value below.
- Text Options: the selected attribute's Text Style, Justification,
Height, Rotation, Width Factor, Oblique Angle, Backwards, Upside down.
- Properties: the selected attribute's Layer, Linetype, Color,
Lineweight (the colour list also surfaces a non-standard current
colour so it displays and round-trips).
Applying writes value, text-formatting and common-property edits back to
each attribute positionally (guarded on block name + count), with undo
and a repaint. OK/Cancel are replaced by a single Apply button in a top
toolbar that commits but keeps the dialog open, matching the other modal
windows — the frame ✕ closes and discards un-applied edits. The frame
adopts the shared style-window palette, tab styling and sizing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:06:03 +03:00
640 ,
500 ,
2026-07-30 14:47:28 +03:00
| flow | {
crate ::ui ::window ::attribute_editor ::view_window (
& self . attr_editor_block ,
& self . attr_editor_rows ,
self . attr_editor_selected ,
self . attr_editor_tab ,
layers . clone ( ) ,
linetypes . clone ( ) ,
styles . clone ( ) ,
flow ,
)
} ,
feat(attedit): enhanced attribute editor with 3 tabs
Grow the attribute editor into a three-tab enhanced editor:
- Attribute: the tag/prompt/value list; click a row to select it, edit
its value below.
- Text Options: the selected attribute's Text Style, Justification,
Height, Rotation, Width Factor, Oblique Angle, Backwards, Upside down.
- Properties: the selected attribute's Layer, Linetype, Color,
Lineweight (the colour list also surfaces a non-standard current
colour so it displays and round-trips).
Applying writes value, text-formatting and common-property edits back to
each attribute positionally (guarded on block name + count), with undo
and a repaint. OK/Cancel are replaced by a single Apply button in a top
toolbar that commits but keeps the dialog open, matching the other modal
windows — the frame ✕ closes and discards un-applied edits. The frame
adopts the shared style-window palette, tab styling and sizing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:06:03 +03:00
)
}
2026-07-11 09:12:36 +03:00
super ::super ::ModalKind ::SaveDialog = > {
2026-08-01 18:24:05 +03:00
automatic_flow ( ex , | flow | {
save_as_dialog_window (
& self . save_dialog_filename ,
& self . save_dialog_format ,
flow ,
)
} )
2026-07-11 09:12:36 +03:00
}
2026-08-03 12:47:48 +03:00
super ::super ::ModalKind ::Recovery = > {
let report = self . recovery_report . as_ref ( ) ? ;
sized_flow ( ex , 680 , 460 , | flow | {
crate ::ui ::window ::recovery ::view_window (
report ,
self . pending_opens . is_empty ( ) ,
flow ,
)
} )
}
super ::super ::ModalKind ::RecoveryPrompt = > {
let opening = self . opening . as_ref ( ) ? ;
let error = opening . recovery_error . as_deref ( ) ? ;
automatic_flow ( ex , | flow | {
crate ::ui ::window ::recovery ::view_prompt (
& opening . name ,
error ,
flow ,
)
} )
}
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
} )
}
}
2026-07-30 14:47:28 +03:00
fn sized_flow < ' a > (
extra : iced ::Vector ,
max_width : u16 ,
max_height : u16 ,
mut build : impl FnMut ( crate ::ui ::modal ::ModalSizing ) -> Element < ' a , Message > ,
) -> Element < ' a , Message > {
crate ::ui ::modal ::intrinsic (
build ( crate ::ui ::modal ::ModalSizing ::INTRINSIC ) ,
build ( crate ::ui ::modal ::ModalSizing ::FILL ) ,
iced ::Size ::new ( max_width as f32 , max_height as f32 ) ,
extra ,
)
}
2026-08-01 18:24:05 +03:00
fn automatic_flow < ' a > (
extra : iced ::Vector ,
mut build : impl FnMut ( crate ::ui ::modal ::ModalSizing ) -> Element < ' a , Message > ,
) -> Element < ' a , Message > {
crate ::ui ::modal ::intrinsic (
build ( crate ::ui ::modal ::ModalSizing ::INTRINSIC ) ,
build ( crate ::ui ::modal ::ModalSizing ::FILL ) ,
iced ::Size ::new ( f32 ::INFINITY , f32 ::INFINITY ) ,
extra ,
)
}
2026-08-02 22:09:25 +03:00
fn dialog_button < ' a > (
label : impl Into < Cow < ' a , str > > ,
2026-07-28 09:33:12 +03:00
message : Message ,
style : fn ( & Theme , button ::Status ) -> button ::Style ,
2026-08-02 22:09:25 +03:00
) -> Element < ' a , Message > {
button ( text ( label . into ( ) ) . size ( 13 ) )
2026-07-28 09:33:12 +03:00
. on_press ( message )
. style ( style )
. padding ( [ 6 , 18 ] )
. into ( )
}
fn dialog_body_style ( theme : & Theme ) -> container ::Style {
2026-07-30 14:47:28 +03:00
let palette = theme . palette ( ) ;
2026-07-28 09:33:12 +03:00
container ::Style {
background : Some ( Background ::Color ( palette . background . base . color ) ) ,
text_color : Some ( palette . background . base . text ) ,
.. Default ::default ( )
}
}
fn dialog_muted_text_style ( theme : & Theme ) -> iced ::widget ::text ::Style {
iced ::widget ::text ::Style {
2026-07-30 14:47:28 +03:00
color : Some ( theme . palette ( ) . background . base . text . scale_alpha ( 0.68 ) ) ,
2026-07-28 09:33:12 +03:00
}
}
2026-07-11 09:12:36 +03:00
/// Compact Save-As options dialog: pick the format/version and a default file
/// name. The destination folder and overwrite confirmation come from the
/// native OS save dialog (native) or the browser download (web) that follows.
2026-08-01 18:24:05 +03:00
fn save_as_dialog_window < ' a > (
filename : & ' a str ,
format : & ' a str ,
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < ' a , Message > {
2026-07-27 22:37:47 +03:00
let sel_fmt = crate ::io ::SAVE_FORMAT_OPTIONS
. iter ( )
. copied ( )
. find ( | & s | s = = format ) ;
2026-08-02 22:09:25 +03:00
let label = | s : Cow < 'static , str > | text ( s ) . size ( 11 ) . style ( dialog_muted_text_style ) ;
2026-08-01 18:24:05 +03:00
let field_width = if matches! ( sizing . width , iced ::Length ::Fill ) {
Fill
} else {
iced ::Length ::Shrink
} ;
2026-07-11 09:12:36 +03:00
let mut items : Vec < Element < ' a , Message > > = Vec ::new ( ) ;
2026-08-02 22:09:25 +03:00
items . push ( text ( t! ( " Save Drawing As " ) ) . size ( 14 ) . into ( ) ) ;
2026-07-11 09:12:36 +03:00
items . push ( Space ::new ( ) . height ( 12 ) . into ( ) ) ;
// Web has no native file dialog, so the file name is typed here. On native
// the OS save dialog collects the name, so this field is omitted.
#[ cfg(target_arch = " wasm32 " ) ]
{
items . push (
row! [
2026-08-02 22:09:25 +03:00
label ( t! ( " File name: " ) ) . width ( 70 ) ,
2026-07-11 09:12:36 +03:00
iced ::widget ::text_input ( " drawing.dwg " , filename )
. on_input ( Message ::SaveDialogFilenameChanged )
. size ( 13 )
. padding ( [ 5 , 8 ] )
2026-08-01 18:24:05 +03:00
. width ( field_width ) ,
2026-07-11 09:12:36 +03:00
]
. align_y ( iced ::Alignment ::Center )
. spacing ( 6 )
2026-08-01 18:24:05 +03:00
. width ( sizing . width )
2026-07-11 09:12:36 +03:00
. into ( ) ,
) ;
items . push ( Space ::new ( ) . height ( 8 ) . into ( ) ) ;
}
#[ cfg(not(target_arch = " wasm32 " )) ]
let _ = filename ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
2026-07-11 09:12:36 +03:00
items . push (
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
row! [
2026-08-02 22:09:25 +03:00
label ( t! ( " Format: " ) ) . width ( 70 ) ,
2026-07-30 15:19:58 +03:00
iced ::widget ::pick_list (
sel_fmt ,
crate ::io ::SAVE_FORMAT_OPTIONS ,
| value | value . to_string ( ) ,
)
. on_select ( | s : & str | Message ::SaveDialogFormatChanged ( s . to_string ( ) ) )
2026-08-01 18:24:05 +03:00
. width ( field_width ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
]
. align_y ( iced ::Alignment ::Center )
2026-07-11 09:12:36 +03:00
. spacing ( 6 )
2026-08-01 18:24:05 +03:00
. width ( sizing . width )
2026-07-11 09:12:36 +03:00
. into ( ) ,
) ;
items . push ( Space ::new ( ) . height ( 16 ) . into ( ) ) ;
items . push (
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
row! [
2026-07-30 14:47:28 +03:00
Space ::new ( ) . width ( Fit ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Save as... " ) , Message ::SaveDialogConfirm , button ::primary ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
Space ::new ( ) . width ( 8 ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Cancel " ) , Message ::SaveDialogCancel , button ::secondary ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
]
2026-07-11 09:12:36 +03:00
. into ( ) ,
) ;
2026-08-01 18:24:05 +03:00
let body = column ( items )
. spacing ( 0 )
. width ( sizing . width )
. height ( sizing . height ) ;
2026-07-11 09:12:36 +03:00
container ( body )
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-07-11 09:12:36 +03:00
. padding ( [ 14 , 16 ] )
2026-08-01 18:24:05 +03:00
. width ( sizing . width )
. height ( sizing . height )
2026-07-11 09:12:36 +03:00
. into ( )
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
}
2026-08-01 18:24:05 +03:00
fn unsaved_changes_dialog_window (
name : & str ,
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < 'static , Message > {
2026-08-02 22:09:25 +03:00
let body_text = t! (
" Do you want to save changes to \" %{name} \" ? " ,
name = name
) ;
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
container (
column! [
2026-07-28 09:33:12 +03:00
text ( body_text ) . size ( 13 ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
iced ::widget ::Space ::new ( ) . height ( 20 ) ,
row! [
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Save " ) , Message ::UnsavedDialogSave , button ::primary ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
iced ::widget ::Space ::new ( ) . width ( 8 ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Discard " ) , Message ::UnsavedDialogDiscard , button ::danger ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
iced ::widget ::Space ::new ( ) . width ( 8 ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Cancel " ) , Message ::UnsavedDialogCancel , button ::secondary ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
] ,
]
. spacing ( 0 ) ,
)
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-08-01 18:24:05 +03:00
. center_x ( sizing . width )
. center_y ( sizing . height )
2026-06-29 11:47:37 +03:00
. padding ( [ 24 , 28 ] )
. into ( )
}
2026-07-27 13:13:58 +03:00
#[ cfg(not(target_arch = " wasm32 " )) ]
2026-08-01 18:24:05 +03:00
fn file_in_use_dialog_window (
path : & str ,
error : & str ,
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < 'static , Message > {
2026-07-27 13:13:58 +03:00
let file_name = std ::path ::Path ::new ( path )
. file_name ( )
. map ( | name | name . to_string_lossy ( ) . into_owned ( ) )
2026-08-02 22:09:25 +03:00
. unwrap_or_else ( | | t! ( " Drawing " ) . into_owned ( ) ) ;
let heading = t! ( " \" %{file_name} \" could not be saved. " , file_name = file_name ) ;
let path_line = t! ( " Path: %{path} " , path = path ) ;
let details = t! ( " Details: %{error} " , error = error ) ;
2026-07-27 13:13:58 +03:00
container (
column! [
2026-07-28 09:33:12 +03:00
text ( heading ) . size ( 14 ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 8 ) ,
2026-08-02 22:09:25 +03:00
text ( t! (
" The file is open or being used by another application. Close it there and retry, or save this drawing under a different name. "
) )
2026-07-27 13:13:58 +03:00
. size ( 13 )
2026-07-30 14:47:28 +03:00
. width ( Fit ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 12 ) ,
2026-07-30 14:47:28 +03:00
text ( path_line ) . size ( 11 ) . style ( dialog_muted_text_style ) . width ( Fit ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 4 ) ,
2026-07-30 14:47:28 +03:00
text ( details ) . size ( 11 ) . style ( dialog_muted_text_style ) . width ( Fit ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 18 ) ,
row! [
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Retry " ) ,
2026-07-27 13:13:58 +03:00
Message ::SaveFileInUseRetry ,
2026-07-28 09:33:12 +03:00
button ::primary
2026-07-27 13:13:58 +03:00
) ,
Space ::new ( ) . width ( 8 ) ,
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Save As " ) ,
2026-07-27 13:13:58 +03:00
Message ::SaveFileInUseSaveAs ,
2026-07-28 09:33:12 +03:00
button ::secondary
2026-07-27 13:13:58 +03:00
) ,
Space ::new ( ) . width ( 8 ) ,
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Cancel " ) ,
2026-07-27 13:13:58 +03:00
Message ::SaveFileInUseCancel ,
2026-07-28 09:33:12 +03:00
button ::secondary
2026-07-27 13:13:58 +03:00
) ,
] ,
]
. spacing ( 0 ) ,
)
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-07-27 13:13:58 +03:00
. padding ( [ 18 , 20 ] )
2026-08-01 18:24:05 +03:00
. width ( sizing . width )
. height ( sizing . height )
2026-07-27 13:13:58 +03:00
. into ( )
}
#[ cfg(not(target_arch = " wasm32 " )) ]
2026-08-01 18:24:05 +03:00
fn external_change_dialog_window (
path : & str ,
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < 'static , Message > {
2026-07-27 13:13:58 +03:00
let file_name = std ::path ::Path ::new ( path )
. file_name ( )
. map ( | name | name . to_string_lossy ( ) . into_owned ( ) )
2026-08-02 22:09:25 +03:00
. unwrap_or_else ( | | t! ( " Drawing " ) . into_owned ( ) ) ;
let heading = t! ( " \" %{file_name} \" was changed by another application. " , file_name = file_name ) ;
let path_line = t! ( " Path: %{path} " , path = path ) ;
2026-07-27 13:13:58 +03:00
container (
column! [
2026-07-28 09:33:12 +03:00
text ( heading ) . size ( 14 ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 8 ) ,
2026-08-02 22:09:25 +03:00
text ( t! (
" Saving now could destroy those external changes. Reload the disk copy, save your local work elsewhere, or explicitly overwrite it. "
) )
2026-07-27 13:13:58 +03:00
. size ( 13 )
2026-07-30 14:47:28 +03:00
. width ( Fit ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 12 ) ,
2026-07-30 14:47:28 +03:00
text ( path_line ) . size ( 11 ) . style ( dialog_muted_text_style ) . width ( Fit ) ,
2026-07-27 13:13:58 +03:00
Space ::new ( ) . height ( 18 ) ,
row! [
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Reload from Disk " ) ,
2026-07-27 13:13:58 +03:00
Message ::ExternalChangeReload ,
2026-07-28 09:33:12 +03:00
button ::primary
2026-07-27 13:13:58 +03:00
) ,
Space ::new ( ) . width ( 8 ) ,
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Save As " ) ,
2026-07-27 13:13:58 +03:00
Message ::ExternalChangeSaveAs ,
2026-07-28 09:33:12 +03:00
button ::secondary
2026-07-27 13:13:58 +03:00
) ,
Space ::new ( ) . width ( 8 ) ,
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Overwrite " ) ,
2026-07-27 13:13:58 +03:00
Message ::ExternalChangeOverwrite ,
2026-07-28 09:33:12 +03:00
button ::danger
2026-07-27 13:13:58 +03:00
) ,
Space ::new ( ) . width ( 8 ) ,
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Cancel " ) ,
2026-07-27 13:13:58 +03:00
Message ::ExternalChangeCancel ,
2026-07-28 09:33:12 +03:00
button ::secondary
2026-07-27 13:13:58 +03:00
) ,
] ,
]
. spacing ( 0 ) ,
)
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-07-27 13:13:58 +03:00
. padding ( [ 18 , 20 ] )
2026-08-01 18:24:05 +03:00
. width ( sizing . width )
. height ( sizing . height )
2026-07-27 13:13:58 +03:00
. into ( )
}
2026-06-29 11:47:37 +03:00
/// Warning shown before a lossy Save-As: the drawing carries unsupported
/// (AEC / application) objects that survive only as verbatim source-version
/// bytes, so saving to a different version or to DXF would drop them. Offers to
/// save in the source version (keep them) or proceed (drop them).
2026-08-01 18:24:05 +03:00
fn aec_drop_dialog_window (
count : usize ,
target : & str ,
src_version : & str ,
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < 'static , Message > {
2026-08-02 22:09:25 +03:00
let body_text = t! (
" This drawing contains %{count} AEC/Civil objects that \" %{target} \" cannot store, so they will not be saved. \n \n To keep them, save in the source version (%{src_version}). " ,
count = count ,
target = target ,
src_version = src_version ,
2026-06-29 11:47:37 +03:00
) ;
container (
column! [
2026-07-28 09:33:12 +03:00
text ( body_text ) . size ( 13 ) ,
2026-06-29 11:47:37 +03:00
iced ::widget ::Space ::new ( ) . height ( 20 ) ,
row! [
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Save in source version " ) ,
2026-07-28 09:33:12 +03:00
Message ::AecDropSameVersion ,
button ::primary
) ,
2026-06-29 11:47:37 +03:00
iced ::widget ::Space ::new ( ) . width ( 8 ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Save anyway " ) , Message ::AecDropProceed , button ::warning ) ,
2026-06-29 11:47:37 +03:00
iced ::widget ::Space ::new ( ) . width ( 8 ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Back " ) , Message ::AecDropBack , button ::secondary ) ,
2026-06-29 11:47:37 +03:00
] ,
]
. spacing ( 0 ) ,
)
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-08-01 18:24:05 +03:00
. center_x ( sizing . width )
. center_y ( sizing . height )
2026-06-29 11:47:37 +03:00
. padding ( [ 24 , 28 ] )
. into ( )
}
/// Confirmation shown when the chosen Save-As filename already exists in the
/// target folder. "Replace" overwrites; "Cancel" returns to the Save dialog.
2026-07-01 17:44:19 +03:00
/// Confirm deleting layer(s) that still have objects on them. "Delete Objects"
/// erases them and removes the layers; "Cancel" leaves everything.
2026-08-01 18:24:05 +03:00
fn layer_delete_warning_window (
names : & [ String ] ,
count : usize ,
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < 'static , Message > {
2026-08-02 22:09:25 +03:00
let obj = if count = = 1 { t! ( " object " ) } else { t! ( " objects " ) } ;
let has = if names . len ( ) = = 1 { t! ( " has " ) } else { t! ( " hold " ) } ;
let those = if count = = 1 {
t! ( " that object " )
} else {
t! ( " those objects " )
} ;
2026-07-01 17:44:19 +03:00
let subject = if names . len ( ) = = 1 {
2026-08-02 22:09:25 +03:00
t! ( " Layer \" %{name} \" " , name = names [ 0 ] ) . into_owned ( )
2026-07-01 17:44:19 +03:00
} else {
2026-08-02 22:09:25 +03:00
t! ( " %{count} selected layers " , count = names . len ( ) ) . into_owned ( )
2026-07-01 17:44:19 +03:00
} ;
2026-08-02 22:09:25 +03:00
let body_text = t! (
" %{subject} still %{has} %{count} %{obj}. \n \n Deleting will also remove %{those} from the drawing. Continue? " ,
subject = subject ,
has = has ,
count = count ,
obj = obj ,
those = those ,
2026-07-01 17:23:32 +03:00
) ;
container (
column! [
2026-07-28 09:33:12 +03:00
text ( body_text ) . size ( 13 ) ,
2026-07-01 17:23:32 +03:00
iced ::widget ::Space ::new ( ) . height ( 20 ) ,
row! [
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Delete Objects " ) ,
2026-07-28 09:33:12 +03:00
Message ::LayerDeleteConfirm ,
button ::danger
) ,
2026-07-01 17:23:32 +03:00
iced ::widget ::Space ::new ( ) . width ( 8 ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Cancel " ) , Message ::CloseModal , button ::secondary ) ,
2026-07-01 17:23:32 +03:00
] ,
]
. spacing ( 0 ) ,
)
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-08-01 18:24:05 +03:00
. center_x ( sizing . width )
. center_y ( sizing . height )
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
. padding ( [ 24 , 28 ] )
. into ( )
}
/// First-launch prompt offering to register Open CAD Studio as the default
/// handler for .dwg / .dxf. "Yes" runs the platform association call; "Not now"
/// just dismisses. Either answer flips the persisted `default_assoc_prompted`
/// flag so the dialog never reappears.
2026-08-01 18:24:05 +03:00
fn default_assoc_dialog_window (
sizing : crate ::ui ::modal ::ModalSizing ,
) -> Element < 'static , Message > {
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
container (
column! [
2026-08-02 22:09:25 +03:00
text ( t! ( " Make Open CAD Studio your default CAD app? " ) )
2026-07-28 09:33:12 +03:00
. size ( 15 ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
iced ::widget ::Space ::new ( ) . height ( 10 ) ,
2026-08-02 22:09:25 +03:00
text ( t! ( " Open .dwg and .dxf drawings in Open CAD Studio by default. You can change this later in your system settings. " ) )
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
. size ( 12 )
2026-07-28 09:33:12 +03:00
. style ( dialog_muted_text_style ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
iced ::widget ::Space ::new ( ) . height ( 22 ) ,
row! [
2026-07-30 14:47:28 +03:00
iced ::widget ::Space ::new ( ) . width ( Fit ) ,
2026-08-02 22:09:25 +03:00
dialog_button ( t! ( " Not now " ) , Message ::AssocPromptNo , button ::secondary ) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
iced ::widget ::Space ::new ( ) . width ( 8 ) ,
2026-07-28 09:33:12 +03:00
dialog_button (
2026-08-02 22:09:25 +03:00
t! ( " Yes, set as default " ) ,
2026-07-28 09:33:12 +03:00
Message ::AssocPromptYes ,
button ::primary
) ,
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
]
. align_y ( iced ::Center ) ,
]
. spacing ( 0 ) ,
)
2026-07-28 09:33:12 +03:00
. style ( dialog_body_style )
2026-08-01 18:24:05 +03:00
. center_x ( sizing . width )
. center_y ( sizing . height )
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
. padding ( [ 24 , 28 ] )
. into ( )
}