diff --git a/topola-egui/src/appearance_panel.rs b/topola-egui/src/appearance_panel.rs index f79c048..c2e1390 100644 --- a/topola-egui/src/appearance_panel.rs +++ b/topola-egui/src/appearance_panel.rs @@ -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, +pub struct ColorLayers { + default: LayerColors, + colors: BTreeMap, } -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 + } + } } diff --git a/topola-egui/src/display.rs b/topola-egui/src/display.rs index aa6f7eb..9ebd53d 100644 --- a/topola-egui/src/display.rs +++ b/topola-egui/src/display.rs @@ -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), + ), + ), ); } } diff --git a/topola/src/board.rs b/topola/src/board.rs index 315307a..536d576 100644 --- a/topola/src/board.rs +++ b/topola/src/board.rs @@ -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) }