Highlight primitives of selected pins

This commit is contained in:
Mikolaj Wielgus 2026-03-15 00:51:20 +01:00
parent a71df91fc1
commit 2e56d20065
3 changed files with 121 additions and 48 deletions

View File

@ -10,17 +10,17 @@ use topola::Board;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Colors {
pub layers: LayerColors,
pub layers: ColorLayers,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LayerColors {
default: LayerColor,
colors: BTreeMap<String, LayerColor>,
pub struct ColorLayers {
default: LayerColors,
colors: BTreeMap<String, LayerColors>,
}
impl LayerColors {
pub fn color(&self, layer_name: Option<&str>) -> &LayerColor {
impl ColorLayers {
pub fn colors(&self, layer_name: Option<&str>) -> &LayerColors {
layer_name
.map(|layername| self.colors.get(layername).unwrap_or(&self.default))
.unwrap_or(&self.default)
@ -28,7 +28,7 @@ impl LayerColors {
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LayerColor {
pub struct LayerColors {
pub normal: egui::Color32,
pub highlighted: egui::Color32,
}
@ -38,8 +38,8 @@ pub struct AppearancePanel {
// TODO:
// In1.Cu shall be #7fc87f (#d5ecd5 when selected).
// In2.Cu shall be #ce7d2c (#e8c39e when selected).
pub dark_colors: Colors,
pub light_colors: Colors,
dark_colors: Colors,
light_colors: Colors,
#[serde(skip)]
pub visible: Box<[bool]>,
@ -48,50 +48,50 @@ pub struct AppearancePanel {
impl AppearancePanel {
pub fn new(board: &Board) -> Self {
let dark_colors = Colors {
layers: LayerColors {
default: LayerColor {
layers: ColorLayers {
default: LayerColors {
normal: egui::Color32::from_rgb(255, 255, 255),
highlighted: egui::Color32::from_rgb(255, 255, 255),
},
colors: BTreeMap::from([
(
"F.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(255, 52, 52),
highlighted: egui::Color32::from_rgb(255, 100, 100),
},
),
(
"1".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(255, 52, 52),
highlighted: egui::Color32::from_rgb(255, 100, 100),
},
),
(
"B.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(52, 52, 255),
highlighted: egui::Color32::from_rgb(100, 100, 255),
},
),
(
"2".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(52, 52, 255),
highlighted: egui::Color32::from_rgb(100, 100, 255),
},
),
(
"In1.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(127, 200, 127),
highlighted: egui::Color32::from_rgb(213, 236, 213),
},
),
(
"In2.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(206, 125, 44),
highlighted: egui::Color32::from_rgb(232, 195, 158),
},
@ -100,50 +100,50 @@ impl AppearancePanel {
},
};
let light_colors = Colors {
layers: LayerColors {
default: LayerColor {
layers: ColorLayers {
default: LayerColors {
normal: egui::Color32::from_rgb(0, 0, 0),
highlighted: egui::Color32::from_rgb(0, 0, 0),
},
colors: BTreeMap::from([
(
"F.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(255, 27, 27),
highlighted: egui::Color32::from_rgb(255, 52, 52),
},
),
(
"1".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(255, 27, 27),
highlighted: egui::Color32::from_rgb(255, 52, 52),
},
),
(
"B.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(27, 27, 255),
highlighted: egui::Color32::from_rgb(52, 52, 255),
},
),
(
"2".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(27, 27, 255),
highlighted: egui::Color32::from_rgb(52, 52, 255),
},
),
(
"In1.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(76, 169, 76),
highlighted: egui::Color32::from_rgb(127, 200, 127),
},
),
(
"In2.Cu".to_string(),
LayerColor {
LayerColors {
normal: egui::Color32::from_rgb(183, 80, 12),
highlighted: egui::Color32::from_rgb(206, 125, 44),
},
@ -214,4 +214,21 @@ impl AppearancePanel {
egui::Theme::Light => &self.light_colors,
}
}
pub fn layer_colors(&self, ctx: &Context, layer_name: Option<&str>) -> &LayerColors {
self.colors(ctx).layers.colors(layer_name)
}
pub fn layer_color(
&self,
ctx: &Context,
layer_name: Option<&str>,
highlight: bool,
) -> egui::Color32 {
if highlight {
self.colors(ctx).layers.colors(layer_name).highlighted
} else {
self.colors(ctx).layers.colors(layer_name).normal
}
}
}

View File

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use crate::{viewport::Viewport, workspace::Workspace};
use topola::{Joint, Polygon, Segment, SegmentId, Vector2};
use topola::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Vector2};
pub struct Display {}
@ -48,7 +48,7 @@ impl Display {
egui::Stroke::new(5.0 / viewport.scale_factor(), egui::Color32::WHITE),
);
for (_, joint) in workspace
for (joint_index, joint) in workspace
.navmesher_board
.board()
.layout()
@ -61,17 +61,22 @@ impl Display {
ui,
viewport,
joint,
workspace
.appearance_panel
.colors(ctx)
.layers
.color(workspace.navmesher_board.board().layer_name(joint.layer))
.normal,
workspace.appearance_panel.layer_color(
ctx,
workspace.navmesher_board.board().layer_name(joint.layer),
workspace
.navmesher_board
.board()
.pin_selection_contains_joint(
&workspace.pin_selection,
JointId::new(joint_index),
),
),
);
}
}
for (i, segment) in workspace
for (segment_index, segment) in workspace
.navmesher_board
.board()
.layout()
@ -88,18 +93,25 @@ impl Display {
.navmesher_board
.board()
.layout()
.segment_endpoints(SegmentId::new(i)),
workspace
.appearance_panel
.colors(ctx)
.layers
.color(workspace.navmesher_board.board().layer_name(segment.layer))
.normal,
.segment_endpoints(SegmentId::new(segment_index)),
workspace.appearance_panel.layer_color(
ctx,
workspace.navmesher_board.board().layer_name(segment.layer),
workspace
.navmesher_board
.board()
.pin_selection_contains_segment(
&workspace.pin_selection,
SegmentId::new(segment_index),
),
),
);
}
}
for (_, polygon) in workspace
// TODO: Vias.
for (polygon_index, polygon) in workspace
.navmesher_board
.board()
.layout()
@ -112,12 +124,17 @@ impl Display {
ui,
viewport,
polygon,
workspace
.appearance_panel
.colors(ctx)
.layers
.color(workspace.navmesher_board.board().layer_name(polygon.layer))
.normal,
workspace.appearance_panel.layer_color(
ctx,
workspace.navmesher_board.board().layer_name(polygon.layer),
workspace
.navmesher_board
.board()
.pin_selection_contains_polygon(
&workspace.pin_selection,
PolygonId::new(polygon_index),
),
),
);
}
}

View File

@ -10,6 +10,7 @@ use crate::{
layout::{Layout, LayoutHalfDelta, NetId, PinId},
math::Vector2,
primitives::{Joint, JointId, Polygon, PolygonId, Segment, SegmentId, Via, ViaId},
selection::PinSelection,
selection::PinSelector,
};
@ -122,6 +123,44 @@ impl Board {
None
}
pub fn pin_selection_contains_joint(
&self,
pin_selection: &PinSelection,
joint_id: JointId,
) -> bool {
let Some(pin_selector) = self.joint_pin_selector(joint_id) else {
return false;
};
pin_selection.0.contains(&pin_selector)
}
pub fn pin_selection_contains_segment(
&self,
pin_selection: &PinSelection,
segment_id: SegmentId,
) -> bool {
let Some(pin_selector) = self.segment_pin_selector(segment_id) else {
return false;
};
pin_selection.0.contains(&pin_selector)
}
// TODO: Vias.
pub fn pin_selection_contains_polygon(
&self,
pin_selection: &PinSelection,
polygon_id: PolygonId,
) -> bool {
let Some(pin_selector) = self.polygon_pin_selector(polygon_id) else {
return false;
};
pin_selection.0.contains(&pin_selector)
}
pub fn pin_name(&self, pin: PinId) -> Option<&str> {
self.pin_names.get_by_left(&pin).map(String::as_str)
}