forked from 1b-agent/opencadstudio-upstream
feat(display): add model lineweight scale
This commit is contained in:
1 parent
edbc4d8ff8
commit
76bdab1e5b
11 files changed
+66
-19
No files matched your search
@@ -492,6 +492,8 @@ pub(super) struct OpenCADStudio {
|
||||
crosshair_color: Option<[u8; 3]>,
|
||||
/// Editable Options buffer for the crosshair colour.
|
||||
crosshair_color_input: String,
|
||||
/// Model-space lineweight preview scale, in percent (25..=200).
|
||||
lineweight_display_scale: i32,
|
||||
/// Isometric drafting state and active axis pair.
|
||||
isometric_drafting: bool,
|
||||
iso_plane: settings::IsoPlane,
|
||||
@@ -1910,6 +1912,8 @@ pub enum Message {
|
||||
PickBoxChanged(i32),
|
||||
/// Set CURSORTYPE from Options.
|
||||
CursorTypeChanged(settings::CursorType),
|
||||
/// Set the model-space lineweight preview scale from Options.
|
||||
LineweightDisplayScaleChanged(i32),
|
||||
/// Edit the optional crosshair RGB value; blank restores automatic contrast.
|
||||
CrosshairColorChanged(String),
|
||||
/// Set the default type/version used when first saving a new drawing.
|
||||
@@ -3280,6 +3284,7 @@ impl OpenCADStudio {
|
||||
cursor_type: settings::CursorType::Crosshair,
|
||||
crosshair_color: None,
|
||||
crosshair_color_input: String::new(),
|
||||
lineweight_display_scale: 100,
|
||||
isometric_drafting: false,
|
||||
iso_plane: settings::IsoPlane::Left,
|
||||
snap_angle_deg: 0.0,
|
||||
|
||||
@@ -164,6 +164,8 @@ pub struct UserSettings {
|
||||
pub cursor_type: CursorType,
|
||||
/// Explicit crosshair RGB. `None` keeps automatic background contrast.
|
||||
pub crosshair_color: Option<[u8; 3]>,
|
||||
/// Model-space lineweight preview scale as a percentage.
|
||||
pub lineweight_display_scale: i32,
|
||||
/// Isometric drafting changes the grid and crosshair to the active axis pair.
|
||||
pub isometric_drafting: bool,
|
||||
pub iso_plane: IsoPlane,
|
||||
@@ -282,6 +284,7 @@ impl Default for UserSettings {
|
||||
pick_box: 3,
|
||||
cursor_type: CursorType::Crosshair,
|
||||
crosshair_color: None,
|
||||
lineweight_display_scale: 100,
|
||||
isometric_drafting: false,
|
||||
iso_plane: IsoPlane::Left,
|
||||
snap_angle_deg: 0.0,
|
||||
|
||||
@@ -124,7 +124,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
||||
self.tab_counter += 1;
|
||||
self.tabs[0] = crate::app::document::DocumentTab::new_drawing(self.tab_counter);
|
||||
self.active_tab = 0;
|
||||
self.apply_bg_default(0);
|
||||
self.apply_display_defaults(0);
|
||||
} else {
|
||||
self.tabs.remove(idx);
|
||||
if self.active_tab >= self.tabs.len() {
|
||||
|
||||
@@ -210,7 +210,7 @@ pub(super) fn on_ribbon_tool_click(&mut self, tool_id: String, event: ModuleEven
|
||||
self.tabs[0] =
|
||||
crate::app::document::DocumentTab::new_drawing(self.tab_counter);
|
||||
self.active_tab = 0;
|
||||
self.apply_bg_default(0);
|
||||
self.apply_display_defaults(0);
|
||||
} else {
|
||||
self.tabs.remove(idx);
|
||||
if self.active_tab >= self.tabs.len() {
|
||||
|
||||
+13
-13
@@ -364,6 +364,7 @@ impl OpenCADStudio {
|
||||
pick_box: self.pick_box,
|
||||
cursor_type: self.cursor_type,
|
||||
crosshair_color: self.crosshair_color,
|
||||
lineweight_display_scale: self.lineweight_display_scale,
|
||||
isometric_drafting: self.isometric_drafting,
|
||||
iso_plane: self.iso_plane,
|
||||
snap_angle_deg: self.snap_angle_deg,
|
||||
@@ -416,6 +417,7 @@ impl OpenCADStudio {
|
||||
.crosshair_color
|
||||
.map(crate::app::config::rgb_to_hex)
|
||||
.unwrap_or_default();
|
||||
self.lineweight_display_scale = s.lineweight_display_scale.clamp(25, 200);
|
||||
self.isometric_drafting = s.isometric_drafting;
|
||||
self.iso_plane = s.iso_plane;
|
||||
self.snap_angle_deg = if s.snap_angle_deg.is_finite() {
|
||||
@@ -469,11 +471,10 @@ impl OpenCADStudio {
|
||||
.take(200)
|
||||
.map(|(k, v)| (k.clone(), *v))
|
||||
.collect();
|
||||
// Push the restored background onto every drawing tab that exists now
|
||||
// (the start tab and any initial drawing). Tabs created later pick it
|
||||
// up via `apply_bg_default` at their construction site.
|
||||
// Push restored display defaults onto every drawing tab that exists now.
|
||||
// Tabs created later pick them up at their construction site.
|
||||
for idx in 0..self.tabs.len() {
|
||||
self.apply_bg_default(idx);
|
||||
self.apply_display_defaults(idx);
|
||||
}
|
||||
self.rebuild_ribbon_modules();
|
||||
}
|
||||
@@ -596,19 +597,18 @@ impl OpenCADStudio {
|
||||
h.object_snap_mode = osmode;
|
||||
}
|
||||
|
||||
/// Apply the persisted default background(s) to tab `idx`. No-op for the
|
||||
/// start tab or when no default is set. Refreshes the tab's cached wires
|
||||
/// and meshes so background-adaptive colours pick up the change.
|
||||
pub(in crate::app) fn apply_bg_default(&mut self, idx: usize) {
|
||||
/// Apply persisted viewport display defaults to tab `idx`.
|
||||
pub(in crate::app) fn apply_display_defaults(&mut self, idx: usize) {
|
||||
let bg = self.default_bg_color;
|
||||
let paper_bg = self.default_paper_bg_color;
|
||||
if bg.is_none() && paper_bg.is_none() {
|
||||
return;
|
||||
}
|
||||
let tab = &mut self.tabs[idx];
|
||||
if tab.is_start {
|
||||
return;
|
||||
}
|
||||
tab.scene.model_lineweight_scale = self.lineweight_display_scale as f32 / 100.0;
|
||||
if bg.is_none() && paper_bg.is_none() {
|
||||
return;
|
||||
}
|
||||
if let Some(c) = bg {
|
||||
tab.bg_color = Some(c);
|
||||
tab.scene.bg_color = c;
|
||||
@@ -1286,7 +1286,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
self.tabs.push(new_tab);
|
||||
let idx = self.tabs.len() - 1;
|
||||
self.active_tab = idx;
|
||||
self.apply_bg_default(idx);
|
||||
self.apply_display_defaults(idx);
|
||||
idx
|
||||
};
|
||||
|
||||
@@ -2381,7 +2381,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
||||
self.tab_counter += 1;
|
||||
self.tabs[i] = crate::app::document::DocumentTab::new_drawing(self.tab_counter);
|
||||
self.active_tab = i;
|
||||
self.apply_bg_default(i);
|
||||
self.apply_display_defaults(i);
|
||||
self.update(Message::OpenPathPicked(Some((
|
||||
conflict.path,
|
||||
metadata.len(),
|
||||
|
||||
+11
-1
@@ -1271,7 +1271,7 @@ impl OpenCADStudio {
|
||||
// creating one doesn't silently reset them (its header default is
|
||||
// 0 = no snaps); saving then persists them into the file.
|
||||
self.stamp_header_sysvars(idx);
|
||||
self.apply_bg_default(idx);
|
||||
self.apply_display_defaults(idx);
|
||||
self.sync_ribbon_layers();
|
||||
self.sync_ribbon_styles();
|
||||
// #21: reset ribbon Color / Linetype / Lineweight to the
|
||||
@@ -5787,6 +5787,16 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::LineweightDisplayScaleChanged(value) => {
|
||||
self.lineweight_display_scale = value.clamp(25, 200);
|
||||
let scale = self.lineweight_display_scale as f32 / 100.0;
|
||||
for tab in &mut self.tabs {
|
||||
tab.scene.model_lineweight_scale = scale;
|
||||
}
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::CrosshairColorChanged(value) => {
|
||||
self.crosshair_color_input = value.clone();
|
||||
if value.trim().is_empty() {
|
||||
|
||||
@@ -189,6 +189,7 @@ impl OpenCADStudio {
|
||||
self.cursor_type,
|
||||
self.crosshair_color,
|
||||
&self.crosshair_color_input,
|
||||
self.lineweight_display_scale,
|
||||
flow,
|
||||
)
|
||||
},
|
||||
|
||||
@@ -1469,6 +1469,8 @@ pub struct Scene {
|
||||
/// Whether entity transparency is honoured on screen. When false the
|
||||
/// wire shader forces every line opaque (a uniform toggle, no retessellate).
|
||||
pub transparency_display: bool,
|
||||
/// User-adjustable model-space lineweight preview multiplier.
|
||||
pub model_lineweight_scale: f32,
|
||||
/// Selection filter: entity-type names excluded from interactive picking.
|
||||
/// Empty = every type is selectable.
|
||||
pub selection_filter: HashSet<String>,
|
||||
@@ -1878,6 +1880,7 @@ impl Scene {
|
||||
refedit_keep: None,
|
||||
hover_highlight: None,
|
||||
transparency_display: true,
|
||||
model_lineweight_scale: 1.0,
|
||||
selection_filter: HashSet::default(),
|
||||
preview_wires: vec![],
|
||||
preview_hatches: Arc::new(Vec::new()),
|
||||
|
||||
@@ -25,8 +25,8 @@ pub struct Uniforms {
|
||||
/// zooming inside MSPACE changes one scalar instead of re-tessellating and
|
||||
/// re-uploading every dashed wire.
|
||||
pub linetype_scale: f32,
|
||||
/// Multiplier for screen-space lineweights. Model space keeps `1.0`;
|
||||
/// paper layouts derive it from the current paper zoom.
|
||||
/// Multiplier for screen-space lineweights. Model space uses the user's
|
||||
/// preview scale; paper layouts derive it from the current paper zoom.
|
||||
pub lineweight_scale: f32,
|
||||
|
||||
// ── Relative-to-eye (double-single) additions ───────────────────────────
|
||||
|
||||
@@ -3847,7 +3847,9 @@ impl Scene {
|
||||
full_bounds,
|
||||
self.document.header.lineweight_display || display_plot_lineweights,
|
||||
);
|
||||
if self.current_layout != "Model" {
|
||||
if self.current_layout == "Model" {
|
||||
uniforms.lineweight_scale = self.model_lineweight_scale;
|
||||
} else {
|
||||
let paper_per_pixel = 2.0 * self.camera.borrow().ortho_size() / canvas.1.max(1.0);
|
||||
let paper_units_per_mm = self.paper_space_unit_factor() as f32;
|
||||
uniforms.lineweight_scale = paper_units_per_mm / paper_per_pixel / MM_TO_PX;
|
||||
|
||||
@@ -39,6 +39,7 @@ pub fn view_window<'a>(
|
||||
cursor_type: CursorType,
|
||||
crosshair_color: Option<[u8; 3]>,
|
||||
crosshair_color_input: &'a str,
|
||||
lineweight_display_scale: i32,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'a, Message> {
|
||||
let selected_format = crate::io::SAVE_FORMAT_OPTIONS
|
||||
@@ -265,6 +266,28 @@ pub fn view_window<'a>(
|
||||
text(crate::t!("Leave the color blank to keep automatic viewport contrast."))
|
||||
.size(11)
|
||||
.width(sizing.width),
|
||||
Space::new().height(24),
|
||||
text(crate::t!("Lineweight")).size(15),
|
||||
Space::new().height(10),
|
||||
row![
|
||||
text(crate::t!("Model display scale")).size(12).width(140),
|
||||
slider(
|
||||
25..=200,
|
||||
lineweight_display_scale.clamp(25, 200),
|
||||
Message::LineweightDisplayScaleChanged,
|
||||
)
|
||||
.step(1)
|
||||
.width(Fill),
|
||||
text(format!("{}%", lineweight_display_scale.clamp(25, 200)))
|
||||
.size(11)
|
||||
.width(44),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(iced::Center),
|
||||
Space::new().height(6),
|
||||
text(crate::t!("Changes the on-screen width in Model without affecting plotted output."))
|
||||
.size(11)
|
||||
.width(sizing.width),
|
||||
]
|
||||
.spacing(0)
|
||||
.width(sizing.width);
|
||||
|
||||
Reference in new issue
Block a user