feat(statusbar): transparency-display toggle (TPY pill)

Add a transparency_enable uniform read by the wire shader: when the new
TPY pill is off, every line is forced opaque; when on, baked entity
transparency shows through. Toggling is a uniform write, no retessellate
(same mechanism as the lineweight-display toggle). Pill is toggleable
from the status-bar customization menu.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-06-04 23:25:09 +03:00
1 parent 28ec360255
commit 66f7d24bc9
9 files changed
+48 -3

No files matched your search

+2
View File
@@ -750,6 +750,8 @@ pub enum Message {
ToggleStatusPill(crate::ui::statusbar_config::StatusPill),
/// Toggle clean-screen mode (hide ribbon + side panels).
ToggleCleanScreen,
/// Toggle whether entity transparency is shown on screen.
ToggleTransparencyDisplay,
/// Toggle the drawing-units picker open/closed.
ToggleUnitsPopup,
/// Close the drawing-units picker.
+8
View File
@@ -3582,6 +3582,14 @@ impl OpenCADStudio {
self.clean_screen ^= true;
Task::none()
}
Message::ToggleTransparencyDisplay => {
let i = self.active_tab;
if i < self.tabs.len() {
// No retessellate — the wire shader reads the flag from uniforms.
self.tabs[i].scene.transparency_display ^= true;
}
Task::none()
}
Message::ToggleUnitsPopup => {
self.units_popup_open ^= true;
Task::none()
+1
View File
@@ -1162,6 +1162,7 @@ impl OpenCADStudio {
tab.scene.document.header.insertion_units,
self.units_popup_open,
tab.scene.is_isolation_active(),
tab.scene.transparency_display,
&self.statusbar_config,
)
})
+4
View File
@@ -553,6 +553,9 @@ pub struct Scene {
/// `tessellate_block`'s visibility test skips these, so they neither
/// render nor hit-test until isolation ends.
pub hidden: HashSet<Handle>,
/// 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,
/// In-progress preview wires while a command is active (rubber-band + object ghosts).
pub preview_wires: Vec<WireModel>,
/// Committed-segment wire drawn during multi-point commands (normal colour).
@@ -698,6 +701,7 @@ impl Scene {
document: CadDocument::new(),
selected: HashSet::new(),
hidden: HashSet::new(),
transparency_display: true,
preview_wires: vec![],
interim_wire: None,
camera_generation: 0,
+7 -2
View File
@@ -19,9 +19,13 @@ pub struct Uniforms {
/// triangle gets a uniform shade (FlatShaded mode); 0.0 → keeps the
/// per-vertex normal interpolation (GouraudShaded-style).
pub flat_shade: f32,
/// Transparency-display toggle (1.0 = honour entity transparency,
/// 0.0 = force opaque). Read by the wire shader so the toggle does not
/// require a retessellate.
pub transparency_enable: f32,
/// Pads the struct to 112 B (next multiple of 16) so wgpu's uniform
/// alignment rules are satisfied.
pub _pad: [f32; 3],
pub _pad: [f32; 2],
}
impl Uniforms {
@@ -39,7 +43,8 @@ impl Uniforms {
world_per_pixel,
lwdisplay_enable: if lwdisplay_enable { 1.0 } else { 0.0 },
flat_shade: 0.0,
_pad: [0.0; 3],
transparency_enable: 1.0,
_pad: [0.0; 2],
}
}
}
+1
View File
@@ -636,6 +636,7 @@ impl Scene {
uniforms.view_proj = crop_view_proj(uniforms.view_proj, uo, vo, us, vs);
uniforms.viewport_size = [visible_w, visible_h];
uniforms.flat_shade = if flags.flat_shade { 1.0 } else { 0.0 };
uniforms.transparency_enable = if self.transparency_display { 1.0 } else { 0.0 };
// `screen_rect` carries the *visible* sub-rectangle in normalized
// canvas coords — that's what `Pipeline::prepare` uses to size
+9 -1
View File
@@ -22,6 +22,12 @@ struct Uniforms {
// per-instance baked half_width. Lets the LWT button switch without
// retessellating.
lwdisplay_enable: f32,
// Mesh flat-shade flag (unused here; kept so the field offsets match
// the shared Uniforms buffer layout).
flat_shade: f32,
// Transparency-display toggle: 1.0 = honour baked alpha, 0.0 = force
// every line opaque.
transparency_enable: f32,
}
@group(0) @binding(0) var<uniform> u: Uniforms;
@@ -156,5 +162,7 @@ fn in_dash(dist: f32, pat_len: f32, p0: vec4<f32>, p1: vec4<f32>) -> bool {
}
}
}
return in.color;
// Transparency display off → force the line opaque.
let alpha = select(1.0, in.color.a, u.transparency_enable > 0.5);
return vec4<f32>(in.color.rgb, alpha);
}
+12
View File
@@ -61,6 +61,8 @@ impl StatusBar {
units_popup_open: bool,
// True when objects are hidden by Isolate / Hide.
isolation_active: bool,
// Whether entity transparency is shown (Transparency pill state).
transparency_display: bool,
// Which pills the user has chosen to show on the bar.
config: &'a StatusBarConfig,
) -> Element<'a, Message> {
@@ -175,6 +177,16 @@ impl StatusBar {
"Drawing Units (INSUNITS)\nClick to change",
));
}
if vis(StatusPill::Transparency) {
right_status = right_status.push(tip(
toggle_pill(
"TPY",
transparency_display,
Message::ToggleTransparencyDisplay,
),
"Show Transparency\nForce opaque when off",
));
}
if vis(StatusPill::Isolate) {
right_status = right_status.push(tip(
toggle_pill("ISO", isolation_active, Message::ToggleIsolatePopup),
+4
View File
@@ -23,6 +23,7 @@ pub enum StatusPill {
Space,
Scale,
Units,
Transparency,
Isolate,
Vp,
CleanScreen,
@@ -44,6 +45,7 @@ impl StatusPill {
StatusPill::Space,
StatusPill::Scale,
StatusPill::Units,
StatusPill::Transparency,
StatusPill::Isolate,
StatusPill::Vp,
StatusPill::CleanScreen,
@@ -64,6 +66,7 @@ impl StatusPill {
StatusPill::Space => "space",
StatusPill::Scale => "scale",
StatusPill::Units => "units",
StatusPill::Transparency => "transparency",
StatusPill::Isolate => "isolate",
StatusPill::Vp => "vp",
StatusPill::CleanScreen => "cleanscreen",
@@ -85,6 +88,7 @@ impl StatusPill {
StatusPill::Space => "Model/Paper Space",
StatusPill::Scale => "Annotation Scale",
StatusPill::Units => "Drawing Units",
StatusPill::Transparency => "Show Transparency",
StatusPill::Isolate => "Isolate Objects",
StatusPill::Vp => "Viewport Count",
StatusPill::CleanScreen => "Clean Screen",