diff --git a/common/bitmap_info.cpp b/common/bitmap_info.cpp index df8fe83299..42173d3867 100644 --- a/common/bitmap_info.cpp +++ b/common/bitmap_info.cpp @@ -5023,5 +5023,79 @@ void BuildBitmapInfo( std::unordered_map>& aBi aBitmapInfoCache[BITMAPS::stroke_none].emplace_back( BITMAPS::stroke_none, wxT( "stroke_none_dark.png" ), -1, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::twistedpair].emplace_back( BITMAPS::twistedpair, wxT( "twistedpair_dark.png" ), -1, wxT( "dark" ) ); aBitmapInfoCache[BITMAPS::viacalc].emplace_back( BITMAPS::viacalc, wxT( "viacalc_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_absolute_length_2].emplace_back( BITMAPS::constraint_absolute_length_2, wxT( "constraint_absolute_length_2.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_allowed_orientation].emplace_back( BITMAPS::constraint_allowed_orientation, wxT( "constraint_allowed_orientation.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_basic_clearance].emplace_back( BITMAPS::constraint_basic_clearance, wxT( "constraint_basic_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_board_outline_clearance].emplace_back( BITMAPS::constraint_board_outline_clearance, wxT( "constraint_board_outline_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_clearance].emplace_back( BITMAPS::constraint_clearance, wxT( "constraint_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_copper_to_edge_clearance].emplace_back( BITMAPS::constraint_copper_to_edge_clearance, wxT( "constraint_copper_to_edge_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_copper_to_hole_clearance].emplace_back( BITMAPS::constraint_copper_to_hole_clearance, wxT( "constraint_copper_to_hole_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_creepage_distance].emplace_back( BITMAPS::constraint_creepage_distance, wxT( "constraint_creepage_distance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_hole_size].emplace_back( BITMAPS::constraint_hole_size, wxT( "constraint_hole_size.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_hole_to_hole_clearance].emplace_back( BITMAPS::constraint_hole_to_hole_clearance, wxT( "constraint_hole_to_hole_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_hole_to_hole_distance].emplace_back( BITMAPS::constraint_hole_to_hole_distance, wxT( "constraint_hole_to_hole_distance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_length].emplace_back( BITMAPS::constraint_length, wxT( "constraint_length.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_matched_length_diff_pair].emplace_back( BITMAPS::constraint_matched_length_diff_pair, wxT( "constraint_matched_length_diff_pair.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_maximum_allowed_deviation].emplace_back( BITMAPS::constraint_maximum_allowed_deviation, wxT( "constraint_maximum_allowed_deviation.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_maximum_via_count].emplace_back( BITMAPS::constraint_maximum_via_count, wxT( "constraint_maximum_via_count.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_angular_ring].emplace_back( BITMAPS::constraint_minimum_angular_ring, wxT( "constraint_minimum_angular_ring.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_annular_width].emplace_back( BITMAPS::constraint_minimum_annular_width, wxT( "constraint_minimum_annular_width.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_clearance].emplace_back( BITMAPS::constraint_minimum_clearance, wxT( "constraint_minimum_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_connection_width].emplace_back( BITMAPS::constraint_minimum_connection_width, wxT( "constraint_minimum_connection_width.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_item_clearance].emplace_back( BITMAPS::constraint_minimum_item_clearance, wxT( "constraint_minimum_item_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_soldermask_silver].emplace_back( BITMAPS::constraint_minimum_soldermask_silver, wxT( "constraint_minimum_soldermask_silver.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_text_height_and_thickness].emplace_back( BITMAPS::constraint_minimum_text_height_and_thickness, wxT( "constraint_minimum_text_height_and_thickness.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_thermal_relief_spoke_count].emplace_back( BITMAPS::constraint_minimum_thermal_relief_spoke_count, wxT( "constraint_minimum_thermal_relief_spoke_count.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_through_hole].emplace_back( BITMAPS::constraint_minimum_through_hole, wxT( "constraint_minimum_through_hole.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_track_width].emplace_back( BITMAPS::constraint_minimum_track_width, wxT( "constraint_minimum_track_width.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_uvia_diameter].emplace_back( BITMAPS::constraint_minimum_uvia_diameter, wxT( "constraint_minimum_uvia_diameter.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_uvia_hole].emplace_back( BITMAPS::constraint_minimum_uvia_hole, wxT( "constraint_minimum_uvia_hole.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_via_diameter].emplace_back( BITMAPS::constraint_minimum_via_diameter, wxT( "constraint_minimum_via_diameter.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_permitted_layers].emplace_back( BITMAPS::constraint_permitted_layers, wxT( "constraint_permitted_layers.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_routing_diff_pair].emplace_back( BITMAPS::constraint_routing_diff_pair, wxT( "constraint_routing_diff_pair.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_routing_width].emplace_back( BITMAPS::constraint_routing_width, wxT( "constraint_routing_width.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_silk_clearance].emplace_back( BITMAPS::constraint_silk_clearance, wxT( "constraint_silk_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_silk_to_soldermask_clearance].emplace_back( BITMAPS::constraint_silk_to_soldermask_clearance, wxT( "constraint_silk_to_soldermask_clearance.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_soldermask_expansion].emplace_back( BITMAPS::constraint_soldermask_expansion, wxT( "constraint_soldermask_expansion.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_solderpaste_expansion].emplace_back( BITMAPS::constraint_solderpaste_expansion, wxT( "constraint_solderpaste_expansion.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_via_style].emplace_back( BITMAPS::constraint_via_style, wxT( "constraint_via_style.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_vias_under_smd].emplace_back( BITMAPS::constraint_vias_under_smd, wxT( "constraint_vias_under_smd.png" ), -1, wxT( "light" ) ); + aBitmapInfoCache[BITMAPS::constraint_absolute_length_2].emplace_back( BITMAPS::constraint_absolute_length_2, wxT( "constraint_absolute_length_2_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_allowed_orientation].emplace_back( BITMAPS::constraint_allowed_orientation, wxT( "constraint_allowed_orientation_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_basic_clearance].emplace_back( BITMAPS::constraint_basic_clearance, wxT( "constraint_basic_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_board_outline_clearance].emplace_back( BITMAPS::constraint_board_outline_clearance, wxT( "constraint_board_outline_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_clearance].emplace_back( BITMAPS::constraint_clearance, wxT( "constraint_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_copper_to_edge_clearance].emplace_back( BITMAPS::constraint_copper_to_edge_clearance, wxT( "constraint_copper_to_edge_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_copper_to_hole_clearance].emplace_back( BITMAPS::constraint_copper_to_hole_clearance, wxT( "constraint_copper_to_hole_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_creepage_distance].emplace_back( BITMAPS::constraint_creepage_distance, wxT( "constraint_creepage_distance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_hole_size].emplace_back( BITMAPS::constraint_hole_size, wxT( "constraint_hole_size_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_hole_to_hole_clearance].emplace_back( BITMAPS::constraint_hole_to_hole_clearance, wxT( "constraint_hole_to_hole_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_hole_to_hole_distance].emplace_back( BITMAPS::constraint_hole_to_hole_distance, wxT( "constraint_hole_to_hole_distance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_length].emplace_back( BITMAPS::constraint_length, wxT( "constraint_length_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_matched_length_diff_pair].emplace_back( BITMAPS::constraint_matched_length_diff_pair, wxT( "constraint_matched_length_diff_pair_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_maximum_allowed_deviation].emplace_back( BITMAPS::constraint_maximum_allowed_deviation, wxT( "constraint_maximum_allowed_deviation_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_maximum_via_count].emplace_back( BITMAPS::constraint_maximum_via_count, wxT( "constraint_maximum_via_count_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_angular_ring].emplace_back( BITMAPS::constraint_minimum_angular_ring, wxT( "constraint_minimum_angular_ring_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_annular_width].emplace_back( BITMAPS::constraint_minimum_annular_width, wxT( "constraint_minimum_annular_width_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_clearance].emplace_back( BITMAPS::constraint_minimum_clearance, wxT( "constraint_minimum_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_connection_width].emplace_back( BITMAPS::constraint_minimum_connection_width, wxT( "constraint_minimum_connection_width_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_item_clearance].emplace_back( BITMAPS::constraint_minimum_item_clearance, wxT( "constraint_minimum_item_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_soldermask_silver].emplace_back( BITMAPS::constraint_minimum_soldermask_silver, wxT( "constraint_minimum_soldermask_silver_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_text_height_and_thickness].emplace_back( BITMAPS::constraint_minimum_text_height_and_thickness, wxT( "constraint_minimum_text_height_and_thickness_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_thermal_relief_spoke_count].emplace_back( BITMAPS::constraint_minimum_thermal_relief_spoke_count, wxT( "constraint_minimum_thermal_relief_spoke_count_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_through_hole].emplace_back( BITMAPS::constraint_minimum_through_hole, wxT( "constraint_minimum_through_hole_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_track_width].emplace_back( BITMAPS::constraint_minimum_track_width, wxT( "constraint_minimum_track_width_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_uvia_diameter].emplace_back( BITMAPS::constraint_minimum_uvia_diameter, wxT( "constraint_minimum_uvia_diameter_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_uvia_hole].emplace_back( BITMAPS::constraint_minimum_uvia_hole, wxT( "constraint_minimum_uvia_hole_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_minimum_via_diameter].emplace_back( BITMAPS::constraint_minimum_via_diameter, wxT( "constraint_minimum_via_diameter_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_permitted_layers].emplace_back( BITMAPS::constraint_permitted_layers, wxT( "constraint_permitted_layers_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_routing_diff_pair].emplace_back( BITMAPS::constraint_routing_diff_pair, wxT( "constraint_routing_diff_pair_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_routing_width].emplace_back( BITMAPS::constraint_routing_width, wxT( "constraint_routing_width_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_silk_clearance].emplace_back( BITMAPS::constraint_silk_clearance, wxT( "constraint_silk_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_silk_to_soldermask_clearance].emplace_back( BITMAPS::constraint_silk_to_soldermask_clearance, wxT( "constraint_silk_to_soldermask_clearance_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_soldermask_expansion].emplace_back( BITMAPS::constraint_soldermask_expansion, wxT( "constraint_soldermask_expansion_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_solderpaste_expansion].emplace_back( BITMAPS::constraint_solderpaste_expansion, wxT( "constraint_solderpaste_expansion_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_via_style].emplace_back( BITMAPS::constraint_via_style, wxT( "constraint_via_style_dark.png" ), -1, wxT( "dark" ) ); + aBitmapInfoCache[BITMAPS::constraint_vias_under_smd].emplace_back( BITMAPS::constraint_vias_under_smd, wxT( "constraint_vias_under_smd_dark.png" ), -1, wxT( "dark" ) ); }; diff --git a/include/bitmaps/bitmaps_list.h b/include/bitmaps/bitmaps_list.h index cfc8e9f355..fcd538fdaf 100644 --- a/include/bitmaps/bitmaps_list.h +++ b/include/bitmaps/bitmaps_list.h @@ -693,7 +693,7 @@ enum class BITMAPS : unsigned int zoom_selection, constraint_basic_clearance, - constraint_outline_clearance, + constraint_board_outline_clearance, constraint_minimum_clearance, constraint_net_antenna, constraint_short_circuit, @@ -727,7 +727,10 @@ enum class BITMAPS : unsigned int constraint_matched_length_diff_pair, constraint_routing_diff_pair, constraint_routing_width, + constraint_clearance, + constraint_length, constraint_maximum_via_count, + constraint_silk_clearance, constraint_matched_length_all_traces_in_group, constraint_absolute_length, constraint_absolute_length_2, diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 34bde75b54..b79694f708 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -338,7 +338,19 @@ set( PCBNEW_DRC_SRCS drc/rule_editor/drc_re_permitted_layers_panel.cpp drc/rule_editor/drc_re_allowed_orientation_panel_base.cpp drc/rule_editor/drc_re_allowed_orientation_panel.cpp + drc/rule_editor/drc_re_bitmap_overlay_panel.cpp drc/rule_editor/drc_re_object_selector_panel.cpp + drc/rule_editor/drc_re_overlay_field.cpp + drc/rule_editor/drc_re_routing_width_overlay_panel.cpp + drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.cpp + drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.cpp + drc/rule_editor/drc_re_abs_length_two_overlay_panel.cpp + drc/rule_editor/drc_re_via_style_overlay_panel.cpp + drc/rule_editor/drc_re_numeric_input_overlay_panel.cpp + drc/rule_editor/drc_re_bool_input_overlay_panel.cpp + drc/rule_editor/drc_re_permitted_layers_overlay_panel.cpp + drc/rule_editor/drc_re_allowed_orientation_overlay_panel.cpp + drc/rule_editor/drc_re_overlay_panel_factory.cpp drc/rule_editor/drc_re_condition_row_panel.cpp drc/rule_editor/drc_re_condition_group_panel.cpp drc/rule_editor/drc_re_custom_rule_panel.cpp diff --git a/pcbnew/drc/rule_editor/drc_re_abs_length_two_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_abs_length_two_constraint_data.h index 5e7f88ce8f..c299591b0c 100644 --- a/pcbnew/drc/rule_editor/drc_re_abs_length_two_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_abs_length_two_constraint_data.h @@ -52,6 +52,19 @@ public: virtual ~DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_absolute_length_2; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_absolute_lenght_2.png (~340x130) + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 35, 95, 30, 1 }, // min_length (left arrow) + { 165, 225, 85, 2 }, // opt_length (bottom center arrow) + { 290, 350, 30, 3 }, // max_length (right arrow) + }; + } + double GetMinimumLength() const { return m_minLength; } void SetMinimumLength( double aLength ) { m_minLength = aLength; } diff --git a/pcbnew/drc/rule_editor/drc_re_abs_length_two_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_abs_length_two_overlay_panel.cpp new file mode 100644 index 0000000000..3f6c0dc9bd --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_abs_length_two_overlay_panel.cpp @@ -0,0 +1,117 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_abs_length_two_overlay_panel.h" +#include "drc_re_abs_length_two_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include +#include + +#include + + +DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL::DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA* aData, EDA_UNITS aUnits ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_unitsProvider( pcbIUScale, aUnits ) +{ + SetBackgroundBitmap( BITMAPS::constraint_absolute_length_2 ); + + std::vector positions = m_data->GetFieldPositions(); + + m_minLengthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_length" ), positions[0], m_minLengthBinder.get() ); + + m_optLengthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "opt_length" ), positions[1], m_optLengthBinder.get() ); + + m_maxLengthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_length" ), positions[2], m_maxLengthBinder.get() ); + + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data ) + return false; + + m_minLengthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinimumLength() ) ); + m_optLengthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetOptimumLength() ) ); + m_maxLengthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaximumLength() ) ); + + return true; +} + + +bool DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data ) + return false; + + m_data->SetMinimumLength( pcbIUScale.IUTomm( m_minLengthBinder->GetDoubleValue() ) ); + m_data->SetOptimumLength( pcbIUScale.IUTomm( m_optLengthBinder->GetDoubleValue() ) ); + m_data->SetMaximumLength( pcbIUScale.IUTomm( m_maxLengthBinder->GetDoubleValue() ) ); + + return true; +} + + +bool DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_abs_length_two_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_abs_length_two_overlay_panel.h new file mode 100644 index 0000000000..57e6970149 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_abs_length_two_overlay_panel.h @@ -0,0 +1,68 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL_H +#define DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL_H + +#include + +#include + +#include "drc_re_bitmap_overlay_panel.h" + +enum class EDA_UNITS; + +class DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA; +class UNIT_BINDER; + + +/** + * Overlay panel for absolute length constraints showing min, opt, and max length fields + * positioned over a diagram. + */ +class DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); + + ~DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_ABSOLUTE_LENGTH_TWO_CONSTRAINT_DATA* m_data; + + UNITS_PROVIDER m_unitsProvider; + + std::unique_ptr m_minLengthBinder; + std::unique_ptr m_optLengthBinder; + std::unique_ptr m_maxLengthBinder; +}; + +#endif // DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_allowed_orientation_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_allowed_orientation_constraint_data.h index 9a2bf10606..b064d0d87e 100644 --- a/pcbnew/drc/rule_editor/drc_re_allowed_orientation_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_allowed_orientation_constraint_data.h @@ -52,6 +52,22 @@ public: virtual ~DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_allowed_orientation; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_allowed_orientation.png (~280x180) + // Format: { xStart, xEnd, yTop, tabOrder } + // Checkboxes stacked vertically on the right side + return { + { 230, 270, 20, 1 }, // 0 degrees checkbox + { 230, 270, 50, 2 }, // 90 degrees checkbox + { 230, 270, 80, 3 }, // 180 degrees checkbox + { 230, 270, 110, 4 }, // 270 degrees checkbox + { 230, 270, 140, 5 }, // all degrees checkbox + }; + } + VALIDATION_RESULT Validate() const override { VALIDATION_RESULT result; diff --git a/pcbnew/drc/rule_editor/drc_re_allowed_orientation_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_allowed_orientation_overlay_panel.cpp new file mode 100644 index 0000000000..ed6527dc15 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_allowed_orientation_overlay_panel.cpp @@ -0,0 +1,128 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_allowed_orientation_overlay_panel.h" +#include "drc_re_allowed_orientation_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include + + +DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL::DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA* aData ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_zeroDegreesCheckbox( nullptr ), + m_ninetyDegreesCheckbox( nullptr ), + m_oneEightyDegreesCheckbox( nullptr ), + m_twoSeventyDegreesCheckbox( nullptr ), + m_allDegreesCheckbox( nullptr ) +{ + SetBackgroundBitmap( m_data->GetOverlayBitmap() ); + + std::vector positions = m_data->GetFieldPositions(); + + DRC_RE_OVERLAY_FIELD* field = AddCheckbox( wxS( "zero_degrees" ), positions[0] ); + m_zeroDegreesCheckbox = static_cast( field->GetControl() ); + + field = AddCheckbox( wxS( "ninety_degrees" ), positions[1] ); + m_ninetyDegreesCheckbox = static_cast( field->GetControl() ); + + field = AddCheckbox( wxS( "one_eighty_degrees" ), positions[2] ); + m_oneEightyDegreesCheckbox = static_cast( field->GetControl() ); + + field = AddCheckbox( wxS( "two_seventy_degrees" ), positions[3] ); + m_twoSeventyDegreesCheckbox = static_cast( field->GetControl() ); + + field = AddCheckbox( wxS( "all_degrees" ), positions[4] ); + m_allDegreesCheckbox = static_cast( field->GetControl() ); + + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data || !m_zeroDegreesCheckbox || !m_ninetyDegreesCheckbox || !m_oneEightyDegreesCheckbox + || !m_twoSeventyDegreesCheckbox || !m_allDegreesCheckbox ) + { + return false; + } + + m_zeroDegreesCheckbox->SetValue( m_data->GetIsZeroDegreesAllowed() ); + m_ninetyDegreesCheckbox->SetValue( m_data->GetIsNinetyDegreesAllowed() ); + m_oneEightyDegreesCheckbox->SetValue( m_data->GetIsOneEightyDegreesAllowed() ); + m_twoSeventyDegreesCheckbox->SetValue( m_data->GetIsTwoSeventyDegreesAllowed() ); + m_allDegreesCheckbox->SetValue( m_data->GetIsAllDegreesAllowed() ); + + return true; +} + + +bool DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data || !m_zeroDegreesCheckbox || !m_ninetyDegreesCheckbox || !m_oneEightyDegreesCheckbox + || !m_twoSeventyDegreesCheckbox || !m_allDegreesCheckbox ) + { + return false; + } + + m_data->SetIsZeroDegreesAllowed( m_zeroDegreesCheckbox->GetValue() ); + m_data->SetIsNinetyDegreesAllowed( m_ninetyDegreesCheckbox->GetValue() ); + m_data->SetIsOneEightyDegreesAllowed( m_oneEightyDegreesCheckbox->GetValue() ); + m_data->SetIsTwoSeventyDegreesAllowed( m_twoSeventyDegreesCheckbox->GetValue() ); + m_data->SetIsAllDegreesAllowed( m_allDegreesCheckbox->GetValue() ); + + return true; +} + + +bool DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_allowed_orientation_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_allowed_orientation_overlay_panel.h new file mode 100644 index 0000000000..739841e9f1 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_allowed_orientation_overlay_panel.h @@ -0,0 +1,61 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL_H +#define DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL_H + +#include "drc_re_bitmap_overlay_panel.h" + +class DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA; +class wxCheckBox; + + +/** + * Overlay panel for allowed orientation constraints showing checkboxes + * for each orientation angle positioned over a diagram. + */ +class DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA* aData ); + + ~DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA* m_data; + + wxCheckBox* m_zeroDegreesCheckbox; + wxCheckBox* m_ninetyDegreesCheckbox; + wxCheckBox* m_oneEightyDegreesCheckbox; + wxCheckBox* m_twoSeventyDegreesCheckbox; + wxCheckBox* m_allDegreesCheckbox; +}; + +#endif // DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_base_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_base_constraint_data.h index 1348f9e1d4..05f872c5f4 100644 --- a/pcbnew/drc/rule_editor/drc_re_base_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_base_constraint_data.h @@ -24,11 +24,15 @@ #ifndef DRC_RE_BASE_CONSTRAINT_DATA_H_ #define DRC_RE_BASE_CONSTRAINT_DATA_H_ +#include #include +#include "drc_re_overlay_types.h" #include "drc_rule_editor_enums.h" #include #include +#include + class DRC_RE_BASE_CONSTRAINT_DATA : public RULE_EDITOR_DATA_BASE { @@ -52,6 +56,23 @@ public: virtual wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) { return wxEmptyString; } + /** + * Returns the bitmap to use for the overlay panel background. + * Override in derived classes to provide constraint-specific artwork. + * + * @return BITMAPS enum value for the overlay bitmap, or BITMAPS::INVALID_BITMAP if none. + */ + virtual BITMAPS GetOverlayBitmap() const { return BITMAPS::INVALID_BITMAP; } + + /** + * Returns the field positions for controls overlaid on the constraint bitmap. + * Override in derived classes to specify where input fields should be placed. + * Each position includes X range, Y coordinate, and tab order for navigation. + * + * @return Vector of field position specifications, empty if no overlay fields. + */ + virtual std::vector GetFieldPositions() const { return {}; } + /** * Returns just the constraint clauses without the rule wrapper. * Used for merging multiple constraint panels into a single rule. diff --git a/pcbnew/drc/rule_editor/drc_re_bitmap_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_bitmap_overlay_panel.cpp new file mode 100644 index 0000000000..d86e787e7a --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_bitmap_overlay_panel.cpp @@ -0,0 +1,299 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_bitmap_overlay_panel.h" +#include "drc_re_overlay_field.h" + +#include + +#include +#include +#include +#include +#include + + +DRC_RE_BITMAP_OVERLAY_PANEL::DRC_RE_BITMAP_OVERLAY_PANEL( wxWindow* aParent, wxWindowID aId ) : + wxPanel(), + m_bitmapId( BITMAPS::INVALID_BITMAP ), + m_baseBitmapSize( 0, 0 ) +{ + // Must set background style BEFORE creating the window + SetBackgroundStyle( wxBG_STYLE_PAINT ); + Create( aParent, aId ); + + Bind( wxEVT_PAINT, &DRC_RE_BITMAP_OVERLAY_PANEL::OnPaint, this ); + Bind( wxEVT_DPI_CHANGED, &DRC_RE_BITMAP_OVERLAY_PANEL::OnDPIChanged, this ); + Bind( wxEVT_SYS_COLOUR_CHANGED, &DRC_RE_BITMAP_OVERLAY_PANEL::OnThemeChange, this ); +} + + +DRC_RE_BITMAP_OVERLAY_PANEL::~DRC_RE_BITMAP_OVERLAY_PANEL() +{ +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::OnPaint( wxPaintEvent& aEvent ) +{ + wxPaintDC dc( this ); + + if( !m_bitmap.IsOk() ) + return; + + dc.DrawBitmap( m_bitmap, 0, 0, true ); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::OnDPIChanged( wxDPIChangedEvent& aEvent ) +{ + LoadBitmap(); + PositionFields(); + Refresh(); + aEvent.Skip(); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::OnThemeChange( wxSysColourChangedEvent& aEvent ) +{ + LoadBitmap(); + Refresh(); + aEvent.Skip(); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldFocus( wxFocusEvent& aEvent ) +{ + // Platform handles focus ring automatically. + // Could add custom highlighting here if needed. + aEvent.Skip(); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldBlur( wxFocusEvent& aEvent ) +{ + // Platform handles focus ring automatically. + aEvent.Skip(); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::SetupFieldStyling( wxControl* aControl ) +{ + if( !aControl ) + return; + + // Bind focus events to track active field + aControl->Bind( wxEVT_SET_FOCUS, &DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldFocus, this ); + aControl->Bind( wxEVT_KILL_FOCUS, &DRC_RE_BITMAP_OVERLAY_PANEL::OnFieldBlur, this ); +} + + +double DRC_RE_BITMAP_OVERLAY_PANEL::GetScaleFactor() const +{ + double scale = GetContentScaleFactor(); + + // Round to nearest supported bitmap resolution (1.0, 1.5, or 2.0) + if( scale < 1.25 ) + return 1.0; + else if( scale < 1.75 ) + return 1.5; + else + return 2.0; +} + + +wxPoint DRC_RE_BITMAP_OVERLAY_PANEL::ScalePosition( int aX, int aY ) const +{ + double scale = GetScaleFactor(); + return wxPoint( static_cast( aX * scale ), static_cast( aY * scale ) ); +} + + +wxSize DRC_RE_BITMAP_OVERLAY_PANEL::ScaleSize( int aWidth, int aHeight ) const +{ + double scale = GetScaleFactor(); + return wxSize( static_cast( aWidth * scale ), static_cast( aHeight * scale ) ); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::LoadBitmap() +{ + if( m_bitmapId == BITMAPS::INVALID_BITMAP ) + return; + + wxBitmapBundle bundle = KiBitmapBundle( m_bitmapId ); + + m_bitmap = bundle.GetBitmapFor( this ); + m_baseBitmapSize = bundle.GetDefaultSize(); + + Refresh(); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::SetBackgroundBitmap( BITMAPS aBitmap ) +{ + m_bitmapId = aBitmap; + LoadBitmap(); + + if( m_bitmap.IsOk() ) + SetMinSize( m_bitmap.GetSize() ); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::PositionFields() +{ + for( const auto& field : m_fields ) + { + const DRC_RE_FIELD_POSITION& pos = field->GetPosition(); + wxControl* ctrl = field->GetControl(); + + if( !ctrl ) + continue; + + // Calculate scaled position and size + wxPoint scaledPos = ScalePosition( pos.xStart, pos.yTop ); + int width = pos.xEnd - pos.xStart; + wxSize scaledSize = ScaleSize( width, ctrl->GetBestSize().GetHeight() ); + + // Check bounds + if( m_bitmap.IsOk() ) + { + wxSize bmpSize = m_bitmap.GetSize(); + + if( scaledPos.x + scaledSize.GetWidth() > bmpSize.GetWidth() || + scaledPos.y + scaledSize.GetHeight() > bmpSize.GetHeight() ) + { + wxLogWarning( "Field '%s' position exceeds bitmap bounds", field->GetFieldId() ); + } + } + + ctrl->SetPosition( scaledPos ); + ctrl->SetSize( scaledSize ); + + // Position label if present + if( field->HasLabel() ) + PositionLabel( field.get() ); + } +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::PositionLabel( DRC_RE_OVERLAY_FIELD* aField ) +{ + wxStaticText* label = aField->GetLabel(); + wxControl* ctrl = aField->GetControl(); + + if( !label || !ctrl ) + return; + + const DRC_RE_FIELD_POSITION& pos = aField->GetPosition(); + wxPoint ctrlPos = ctrl->GetPosition(); + wxSize ctrlSize = ctrl->GetSize(); + wxSize labelSize = label->GetBestSize(); + + wxPoint labelPos; + constexpr int GAP = 4; + + switch( pos.labelPosition ) + { + case LABEL_POSITION::LEFT: + labelPos.x = ctrlPos.x - labelSize.GetWidth() - GAP; + labelPos.y = ctrlPos.y + ( ctrlSize.GetHeight() - labelSize.GetHeight() ) / 2; + break; + + case LABEL_POSITION::RIGHT: + labelPos.x = ctrlPos.x + ctrlSize.GetWidth() + GAP; + labelPos.y = ctrlPos.y + ( ctrlSize.GetHeight() - labelSize.GetHeight() ) / 2; + break; + + case LABEL_POSITION::TOP: + labelPos.x = ctrlPos.x + ( ctrlSize.GetWidth() - labelSize.GetWidth() ) / 2; + labelPos.y = ctrlPos.y - labelSize.GetHeight() - GAP; + break; + + case LABEL_POSITION::BOTTOM: + labelPos.x = ctrlPos.x + ( ctrlSize.GetWidth() - labelSize.GetWidth() ) / 2; + labelPos.y = ctrlPos.y + ctrlSize.GetHeight() + GAP; + break; + + case LABEL_POSITION::NONE: + default: + return; + } + + label->SetPosition( labelPos ); +} + + +bool DRC_RE_BITMAP_OVERLAY_PANEL::TransferDataToWindow() +{ + // Base implementation does nothing; derived classes override to populate fields + return true; +} + + +bool DRC_RE_BITMAP_OVERLAY_PANEL::TransferDataFromWindow() +{ + // Base implementation does nothing; derived classes override to read fields + return true; +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::ClearFieldErrors() +{ + for( const auto& field : m_fields ) + field->ShowError( false ); +} + + +void DRC_RE_BITMAP_OVERLAY_PANEL::ShowFieldError( const wxString& aFieldId ) +{ + auto it = m_fieldIdMap.find( aFieldId ); + + if( it != m_fieldIdMap.end() ) + it->second->ShowError( true ); +} + + +DRC_RE_OVERLAY_FIELD* DRC_RE_BITMAP_OVERLAY_PANEL::AddCheckbox( const wxString& aId, + const DRC_RE_FIELD_POSITION& aPosition ) +{ + wxCheckBox* checkbox = new wxCheckBox( this, wxID_ANY, wxEmptyString ); + + auto field = std::make_unique( this, aId, checkbox, aPosition ); + DRC_RE_OVERLAY_FIELD* fieldPtr = field.get(); + + SetupFieldStyling( checkbox ); + + wxPoint pos = ScalePosition( aPosition.xStart, aPosition.yTop ); + checkbox->SetPosition( pos ); + + // Create label if specified + fieldPtr->CreateLabel(); + + if( fieldPtr->HasLabel() ) + PositionLabel( fieldPtr ); + + m_fieldIdMap[aId] = fieldPtr; + m_fields.push_back( std::move( field ) ); + + return fieldPtr; +} diff --git a/pcbnew/drc/rule_editor/drc_re_bitmap_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_bitmap_overlay_panel.h new file mode 100644 index 0000000000..d684a3e83c --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_bitmap_overlay_panel.h @@ -0,0 +1,238 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_BITMAP_OVERLAY_PANEL_H +#define DRC_RE_BITMAP_OVERLAY_PANEL_H + +#include +#include +#include + +#include +#include + +#include +#include "drc_re_content_panel_base.h" +#include "drc_re_overlay_field.h" +#include "drc_re_overlay_types.h" + +class wxControl; +class wxCheckBox; +class wxPaintEvent; +class wxDPIChangedEvent; +class wxSysColourChangedEvent; +class wxFocusEvent; +class UNIT_BINDER; + + +/** + * Base class for DRC rule editor panels that display input fields overlaid on a bitmap. + * + * This class provides infrastructure for creating constraint editor panels where input fields + * are precisely positioned over explanatory constraint diagrams. The bitmap serves as a visual + * guide showing what each field value represents. + * + * Derived classes should: + * - Call SetBackgroundBitmap() in their constructor to set the diagram + * - Create fields using AddField(), AddFieldWithUnits(), or AddCheckbox() + * - Override TransferDataToWindow/FromWindow to populate/read field values + */ +class DRC_RE_BITMAP_OVERLAY_PANEL : public wxPanel, + public DRC_RULE_EDITOR_CONTENT_PANEL_BASE +{ +public: + DRC_RE_BITMAP_OVERLAY_PANEL( wxWindow* aParent, wxWindowID aId = wxID_ANY ); + + virtual ~DRC_RE_BITMAP_OVERLAY_PANEL(); + + /** + * Set the background bitmap for this panel. + * + * @param aBitmap The BITMAPS enum value identifying the constraint diagram. + */ + void SetBackgroundBitmap( BITMAPS aBitmap ); + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + /** + * Clear error indicators from all fields. + */ + void ClearFieldErrors(); + + /** + * Show an error indicator on the specified field. + * + * @param aFieldId The string identifier of the field to highlight. + */ + void ShowFieldError( const wxString& aFieldId ); + +protected: + /** + * Create and position a field control on the bitmap overlay. + * + * @tparam T The wxWindow-derived control type to create. + * @param aId String identifier for this field (used for error display and lookup). + * @param aPosition Position specification in 1x bitmap coordinates. + * @return Pointer to the created field wrapper. + */ + template + DRC_RE_OVERLAY_FIELD* AddField( const wxString& aId, const DRC_RE_FIELD_POSITION& aPosition ); + + /** + * Create and position a field control with unit binding. + * + * @tparam T The wxWindow-derived control type to create. + * @param aId String identifier for this field. + * @param aPosition Position specification in 1x bitmap coordinates. + * @param aUnitBinder UNIT_BINDER to associate with this field for unit conversion. + * @return Pointer to the created field wrapper. + */ + template + DRC_RE_OVERLAY_FIELD* AddFieldWithUnits( const wxString& aId, + const DRC_RE_FIELD_POSITION& aPosition, + UNIT_BINDER* aUnitBinder ); + + /** + * Create and position a checkbox control on the bitmap overlay. + * + * @param aId String identifier for this checkbox. + * @param aPosition Position specification in 1x bitmap coordinates. + * @return Pointer to the created field wrapper. + */ + DRC_RE_OVERLAY_FIELD* AddCheckbox( const wxString& aId, const DRC_RE_FIELD_POSITION& aPosition ); + + /** + * Load the appropriate bitmap variant for the current theme and DPI. + */ + void LoadBitmap(); + + /** + * Position all fields based on the current scale factor. + */ + void PositionFields(); + + /** + * Get the current DPI scale factor. + * + * @return Scale factor (1.0, 1.5, or 2.0). + */ + double GetScaleFactor() const; + + /** + * Scale pixel coordinates from 1x bitmap space to current display space. + * + * @param aX X coordinate in 1x bitmap pixels. + * @param aY Y coordinate in 1x bitmap pixels. + * @return Scaled position as wxPoint. + */ + wxPoint ScalePosition( int aX, int aY ) const; + + /** + * Scale pixel dimensions from 1x bitmap space to current display space. + * + * @param aWidth Width in 1x bitmap pixels. + * @param aHeight Height in 1x bitmap pixels. + * @return Scaled size as wxSize. + */ + wxSize ScaleSize( int aWidth, int aHeight ) const; + + /** + * Apply transparent styling to a field control. + * + * @param aControl The control to style. + */ + void SetupFieldStyling( wxControl* aControl ); + +private: + void OnPaint( wxPaintEvent& aEvent ); + void OnDPIChanged( wxDPIChangedEvent& aEvent ); + void OnThemeChange( wxSysColourChangedEvent& aEvent ); + void OnFieldFocus( wxFocusEvent& aEvent ); + void OnFieldBlur( wxFocusEvent& aEvent ); + + /** + * Position a label relative to its field control based on the label position setting. + * + * @param aField The overlay field containing the label to position. + */ + void PositionLabel( DRC_RE_OVERLAY_FIELD* aField ); + + wxBitmap m_bitmap; ///< Current background bitmap + BITMAPS m_bitmapId; ///< BITMAPS enum value + wxSize m_baseBitmapSize; ///< Bitmap size at 1x scale + std::vector> m_fields; ///< All overlay fields + std::map m_fieldIdMap; ///< Field ID to field lookup +}; + + +template +DRC_RE_OVERLAY_FIELD* DRC_RE_BITMAP_OVERLAY_PANEL::AddField( const wxString& aId, + const DRC_RE_FIELD_POSITION& aPosition ) +{ + // Create the control + T* control = new T( this, wxID_ANY ); + + // Create the overlay field wrapper + auto field = std::make_unique( this, aId, control, aPosition ); + DRC_RE_OVERLAY_FIELD* fieldPtr = field.get(); + + // Set up styling + SetupFieldStyling( control ); + + // Position the field + wxPoint pos = ScalePosition( aPosition.xStart, aPosition.yTop ); + int width = aPosition.xEnd - aPosition.xStart; + wxSize size = ScaleSize( width, control->GetBestSize().GetHeight() ); + control->SetPosition( pos ); + control->SetSize( size ); + + // Create label if specified + fieldPtr->CreateLabel(); + + if( fieldPtr->HasLabel() ) + PositionLabel( fieldPtr ); + + // Store in collections + m_fieldIdMap[aId] = fieldPtr; + m_fields.push_back( std::move( field ) ); + + return fieldPtr; +} + + +template +DRC_RE_OVERLAY_FIELD* DRC_RE_BITMAP_OVERLAY_PANEL::AddFieldWithUnits( const wxString& aId, + const DRC_RE_FIELD_POSITION& aPosition, + UNIT_BINDER* aUnitBinder ) +{ + // Create the field using the base AddField method + DRC_RE_OVERLAY_FIELD* field = AddField( aId, aPosition ); + + // Associate the unit binder for value conversion + field->SetUnitBinder( aUnitBinder ); + + return field; +} + +#endif // DRC_RE_BITMAP_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_bool_input_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_bool_input_constraint_data.h index 78d6fc1d89..944f86242a 100644 --- a/pcbnew/drc/rule_editor/drc_re_bool_input_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_bool_input_constraint_data.h @@ -46,6 +46,17 @@ public: virtual ~DRC_RE_BOOL_INPUT_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_vias_under_smd; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_vias_under_SMD.png (~280x160) + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 20, 40, 130, 1 }, // checkbox (bottom left corner) + }; + } + VALIDATION_RESULT Validate() const override { // Boolean inputs are always valid - any true/false value is acceptable diff --git a/pcbnew/drc/rule_editor/drc_re_bool_input_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_bool_input_overlay_panel.cpp new file mode 100644 index 0000000000..7b996f852f --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_bool_input_overlay_panel.cpp @@ -0,0 +1,98 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_bool_input_overlay_panel.h" +#include "drc_re_bool_input_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include + + +DRC_RE_BOOL_INPUT_OVERLAY_PANEL::DRC_RE_BOOL_INPUT_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_BOOL_INPUT_CONSTRAINT_DATA* aData ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_boolInputCheckbox( nullptr ) +{ + SetBackgroundBitmap( m_data->GetOverlayBitmap() ); + + std::vector positions = m_data->GetFieldPositions(); + + DRC_RE_OVERLAY_FIELD* field = AddCheckbox( wxS( "bool_input" ), positions[0] ); + m_boolInputCheckbox = static_cast( field->GetControl() ); + + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_BOOL_INPUT_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data || !m_boolInputCheckbox ) + return false; + + m_boolInputCheckbox->SetValue( m_data->GetBoolInputValue() ); + + return true; +} + + +bool DRC_RE_BOOL_INPUT_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data || !m_boolInputCheckbox ) + return false; + + m_data->SetBoolInputValue( m_boolInputCheckbox->GetValue() ); + + return true; +} + + +bool DRC_RE_BOOL_INPUT_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_BOOL_INPUT_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_bool_input_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_bool_input_overlay_panel.h new file mode 100644 index 0000000000..52a227cf45 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_bool_input_overlay_panel.h @@ -0,0 +1,57 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_BOOL_INPUT_OVERLAY_PANEL_H +#define DRC_RE_BOOL_INPUT_OVERLAY_PANEL_H + +#include "drc_re_bitmap_overlay_panel.h" + +class DRC_RE_BOOL_INPUT_CONSTRAINT_DATA; +class wxCheckBox; + + +/** + * Overlay panel for boolean input constraints showing a single checkbox + * positioned over a diagram. + */ +class DRC_RE_BOOL_INPUT_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_BOOL_INPUT_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_BOOL_INPUT_CONSTRAINT_DATA* aData ); + + ~DRC_RE_BOOL_INPUT_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_BOOL_INPUT_CONSTRAINT_DATA* m_data; + + wxCheckBox* m_boolInputCheckbox; +}; + +#endif // DRC_RE_BOOL_INPUT_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_content_panel_base.h b/pcbnew/drc/rule_editor/drc_re_content_panel_base.h index e89908edc1..ed48c68cd3 100644 --- a/pcbnew/drc/rule_editor/drc_re_content_panel_base.h +++ b/pcbnew/drc/rule_editor/drc_re_content_panel_base.h @@ -54,6 +54,9 @@ public: virtual ~DRC_RULE_EDITOR_CONTENT_PANEL_BASE() = default; + virtual bool TransferDataToWindow() = 0; + virtual bool TransferDataFromWindow() = 0; + virtual bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) = 0; virtual wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) = 0; diff --git a/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_constraint_data.h index a6cf67e03c..33823ebc3a 100644 --- a/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_constraint_data.h @@ -49,6 +49,21 @@ public: virtual ~DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override + { + return BITMAPS::constraint_minimum_text_height_and_thickness; + } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_minimum_text_height_and_thickness.png (~300x200) + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 230, 310, 55, 1 }, // min_text_height (right side, vertical dimension) + { 140, 220, 165, 2 }, // min_text_thickness (bottom, horizontal dimension) + }; + } + double GetMinTextHeight() { return m_minTextHeight; } void SetMinTextHeight( double aMinTextHeight ) { m_minTextHeight = aMinTextHeight; } diff --git a/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.cpp new file mode 100644 index 0000000000..b6035ec6d8 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.cpp @@ -0,0 +1,113 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_min_txt_ht_th_overlay_panel.h" +#include "drc_re_min_txt_ht_th_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include +#include + +#include + + +DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL::DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_unitsProvider( pcbIUScale, aUnits ) +{ + SetBackgroundBitmap( BITMAPS::constraint_minimum_text_height_and_thickness ); + + std::vector positions = m_data->GetFieldPositions(); + + m_minTextHeightBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_text_height" ), positions[0], + m_minTextHeightBinder.get() ); + + m_minTextThicknessBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_text_thickness" ), positions[1], + m_minTextThicknessBinder.get() ); + + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data ) + return false; + + m_minTextHeightBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinTextHeight() ) ); + m_minTextThicknessBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinTextThickness() ) ); + + return true; +} + + +bool DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data ) + return false; + + m_data->SetMinTextHeight( pcbIUScale.IUTomm( m_minTextHeightBinder->GetDoubleValue() ) ); + m_data->SetMinTextThickness( pcbIUScale.IUTomm( m_minTextThicknessBinder->GetDoubleValue() ) ); + + return true; +} + + +bool DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.h new file mode 100644 index 0000000000..53e995602c --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_min_txt_ht_th_overlay_panel.h @@ -0,0 +1,67 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL_H +#define DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL_H + +#include + +#include + +#include "drc_re_bitmap_overlay_panel.h" + +enum class EDA_UNITS; + +class DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA; +class UNIT_BINDER; + + +/** + * Overlay panel for minimum text height and thickness constraints showing text dimension fields + * positioned over a diagram. + */ +class DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); + + ~DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA* m_data; + + UNITS_PROVIDER m_unitsProvider; + + std::unique_ptr m_minTextHeightBinder; + std::unique_ptr m_minTextThicknessBinder; +}; + +#endif // DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_numeric_input_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_numeric_input_constraint_data.h index 76ae91590c..8372044b72 100644 --- a/pcbnew/drc/rule_editor/drc_re_numeric_input_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_numeric_input_constraint_data.h @@ -46,6 +46,17 @@ public: virtual ~DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_minimum_track_width; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_minimum_track_width.png (~280x140) + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 220, 300, 50, 1 }, // value (right side, near dimension arrow) + }; + } + std::vector GetConstraintClauses( const RULE_GENERATION_CONTEXT& aContext ) const override { wxString code = GetConstraintCode(); diff --git a/pcbnew/drc/rule_editor/drc_re_numeric_input_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_numeric_input_overlay_panel.cpp new file mode 100644 index 0000000000..0fc677fdc8 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_numeric_input_overlay_panel.cpp @@ -0,0 +1,103 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_numeric_input_overlay_panel.h" +#include "drc_re_numeric_input_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include +#include + +#include + + +DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL::DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA* aData, EDA_UNITS aUnits ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_unitsProvider( pcbIUScale, aUnits ) +{ + SetBackgroundBitmap( m_data->GetOverlayBitmap() ); + + std::vector positions = m_data->GetFieldPositions(); + + m_valueBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "value" ), positions[0], m_valueBinder.get() ); + + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data ) + return false; + + m_valueBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetNumericInputValue() ) ); + + return true; +} + + +bool DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data ) + return false; + + m_data->SetNumericInputValue( pcbIUScale.IUTomm( m_valueBinder->GetDoubleValue() ) ); + + return true; +} + + +bool DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_numeric_input_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_numeric_input_overlay_panel.h new file mode 100644 index 0000000000..3f92def32b --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_numeric_input_overlay_panel.h @@ -0,0 +1,66 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL_H +#define DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL_H + +#include + +#include + +#include "drc_re_bitmap_overlay_panel.h" + +enum class EDA_UNITS; + +class DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA; +class UNIT_BINDER; + + +/** + * Overlay panel for numeric input constraints showing a single numeric value field + * positioned over a diagram. + */ +class DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); + + ~DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA* m_data; + + UNITS_PROVIDER m_unitsProvider; + + std::unique_ptr m_valueBinder; +}; + +#endif // DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_numeric_input_panel.cpp b/pcbnew/drc/rule_editor/drc_re_numeric_input_panel.cpp index 02eca59517..2d1d10db0f 100644 --- a/pcbnew/drc/rule_editor/drc_re_numeric_input_panel.cpp +++ b/pcbnew/drc/rule_editor/drc_re_numeric_input_panel.cpp @@ -31,7 +31,7 @@ const std::map NumericConstraintBitMapPairs = { { BASIC_CLEARANCE, BITMAPS::constraint_basic_clearance }, - { BOARD_OUTLINE_CLEARANCE, BITMAPS::constraint_outline_clearance }, + { BOARD_OUTLINE_CLEARANCE, BITMAPS::constraint_board_outline_clearance }, { MINIMUM_CLEARANCE, BITMAPS::constraint_minimum_clearance }, { MINIMUM_ITEM_CLEARANCE, BITMAPS::constraint_minimum_item_clearance }, { CREEPAGE_DISTANCE, BITMAPS::constraint_creepage_distance}, @@ -47,7 +47,7 @@ const std::map NumericConstraintBitMap { MINIMUM_UVIA_HOLE, BITMAPS::constraint_minimum_uvia_hole }, { MINIMUM_UVIA_DIAMETER, BITMAPS::constraint_minimum_uvia_diameter }, { MINIMUM_VIA_DIAMETER, BITMAPS::constraint_minimum_via_diameter }, - { SILK_TO_SILK_CLEARANCE, BITMAPS::constraint_silk_to_silk_clearance }, + { SILK_TO_SILK_CLEARANCE, BITMAPS::constraint_silk_clearance }, { SILK_TO_SOLDERMASK_CLEARANCE, BITMAPS::constraint_silk_to_soldermask_clearance }, { MINIMUM_SOLDERMASK_SILVER, BITMAPS::constraint_minimum_soldermask_silver }, { SOLDERMASK_EXPANSION, BITMAPS::constraint_soldermask_expansion }, @@ -56,7 +56,7 @@ const std::map NumericConstraintBitMap { MINIMUM_ANGULAR_RING, BITMAPS::constraint_minimum_angular_ring }, { MINIMUM_THERMAL_RELIEF_SPOKE_COUNT, BITMAPS::constraint_minimum_thermal_relief_spoke_count }, { MAXIMUM_VIA_COUNT, BITMAPS::constraint_maximum_via_count }, - { ABSOLUTE_LENGTH, BITMAPS::constraint_absolute_length }, + { ABSOLUTE_LENGTH, BITMAPS::constraint_length }, { MATCHED_LENGTH_DIFF_PAIR, BITMAPS::constraint_matched_length_diff_pair } }; diff --git a/pcbnew/drc/rule_editor/drc_re_overlay_field.cpp b/pcbnew/drc/rule_editor/drc_re_overlay_field.cpp new file mode 100644 index 0000000000..99e96ddecc --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_overlay_field.cpp @@ -0,0 +1,154 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_overlay_field.h" + +#include +#include + +#include +#include +#include +#include + + +DRC_RE_OVERLAY_FIELD::DRC_RE_OVERLAY_FIELD( wxWindow* aParent, const wxString& aFieldId, + wxControl* aControl, + const DRC_RE_FIELD_POSITION& aPosition ) : + m_parent( aParent ), + m_fieldId( aFieldId ), + m_control( aControl ), + m_position( aPosition ), + m_getter( nullptr ), + m_setter( nullptr ), + m_unitBinder( nullptr ), + m_errorIcon( nullptr ), + m_showingError( false ), + m_label( nullptr ) +{ +} + + +DRC_RE_OVERLAY_FIELD::~DRC_RE_OVERLAY_FIELD() +{ + if( m_errorIcon ) + { + m_errorIcon->Destroy(); + m_errorIcon = nullptr; + } + + if( m_label ) + { + m_label->Destroy(); + m_label = nullptr; + } +} + + +void DRC_RE_OVERLAY_FIELD::createErrorIcon() +{ + if( m_errorIcon ) + return; + + m_errorIcon = new wxStaticBitmap( m_parent, wxID_ANY, KiBitmapBundle( BITMAPS::small_warning ) ); + + // Position the icon to the right of the control with a small gap + wxPoint controlPos = m_control->GetPosition(); + wxSize controlSize = m_control->GetSize(); + wxSize iconSize = m_errorIcon->GetSize(); + + int iconX = controlPos.x + controlSize.GetWidth() + 4; + int iconY = controlPos.y + ( controlSize.GetHeight() - iconSize.GetHeight() ) / 2; + + m_errorIcon->SetPosition( wxPoint( iconX, iconY ) ); + m_errorIcon->Hide(); +} + + +void DRC_RE_OVERLAY_FIELD::ShowError( bool aShow ) +{ + if( aShow && !m_errorIcon ) + createErrorIcon(); + + if( m_errorIcon ) + m_errorIcon->Show( aShow ); + + m_showingError = aShow; +} + + +bool DRC_RE_OVERLAY_FIELD::TransferToWindow() +{ + if( !m_getter ) + return true; + + try + { + double value = m_getter(); + + if( m_unitBinder ) + { + m_unitBinder->SetDoubleValue( value ); + } + + return true; + } + catch( ... ) + { + return false; + } +} + + +bool DRC_RE_OVERLAY_FIELD::TransferFromWindow() +{ + if( !m_setter ) + return true; + + try + { + if( m_unitBinder ) + { + double value = m_unitBinder->GetDoubleValue(); + m_setter( value ); + } + + return true; + } + catch( ... ) + { + return false; + } +} + + +void DRC_RE_OVERLAY_FIELD::CreateLabel() +{ + if( m_label ) + return; + + if( m_position.labelText.IsEmpty() || m_position.labelPosition == LABEL_POSITION::NONE ) + return; + + m_label = new wxStaticText( m_parent, wxID_ANY, m_position.labelText ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_overlay_field.h b/pcbnew/drc/rule_editor/drc_re_overlay_field.h new file mode 100644 index 0000000000..f8d6c48e75 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_overlay_field.h @@ -0,0 +1,174 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_OVERLAY_FIELD_H +#define DRC_RE_OVERLAY_FIELD_H + +#include +#include + +#include "drc_re_overlay_types.h" + +class wxWindow; +class wxControl; +class wxStaticBitmap; +class wxStaticText; +class UNIT_BINDER; + + +/** + * Wraps a wxControl positioned over a bitmap overlay panel. + * + * Manages the control's position within the overlay, data binding via lambda functions, + * optional UNIT_BINDER integration for unit conversion, and error icon display for + * validation feedback. + */ +class DRC_RE_OVERLAY_FIELD +{ +public: + using Getter = std::function; + using Setter = std::function; + + /** + * Construct an overlay field wrapping an existing control. + * + * @param aParent Parent window (typically the overlay panel) + * @param aFieldId Unique identifier for this field, used for error mapping + * @param aControl The wxControl to wrap and position + * @param aPosition Position specification in 1x bitmap coordinates + */ + DRC_RE_OVERLAY_FIELD( wxWindow* aParent, const wxString& aFieldId, wxControl* aControl, + const DRC_RE_FIELD_POSITION& aPosition ); + + ~DRC_RE_OVERLAY_FIELD(); + + /** + * @return The wrapped wxControl. + */ + wxControl* GetControl() const { return m_control; } + + /** + * @return The unique field identifier string. + */ + const wxString& GetFieldId() const { return m_fieldId; } + + /** + * @return The field's position specification in 1x bitmap coordinates. + */ + const DRC_RE_FIELD_POSITION& GetPosition() const { return m_position; } + + /** + * Transfer data from the model to the control. + * + * Uses the getter lambda if set. If a UNIT_BINDER is associated, the value is + * passed through SetDoubleValue for unit conversion. + * + * @return true on success, false if getter throws or is not set + */ + bool TransferToWindow(); + + /** + * Transfer data from the control to the model. + * + * Reads the control value (via UNIT_BINDER if associated) and calls the setter lambda. + * + * @return true on success, false if setter throws or is not set + */ + bool TransferFromWindow(); + + /** + * Set the getter lambda for reading model data. + * + * @param aGetter Function returning the current model value + */ + void SetGetter( Getter aGetter ) { m_getter = std::move( aGetter ); } + + /** + * Set the setter lambda for writing model data. + * + * @param aSetter Function accepting the new value from the control + */ + void SetSetter( Setter aSetter ) { m_setter = std::move( aSetter ); } + + /** + * Associate a UNIT_BINDER for unit conversion. + * + * When set, TransferToWindow and TransferFromWindow use the UNIT_BINDER's + * SetDoubleValue and GetDoubleValue methods for proper unit handling. + * + * @param aBinder The UNIT_BINDER to associate (ownership remains with caller) + */ + void SetUnitBinder( UNIT_BINDER* aBinder ) { m_unitBinder = aBinder; } + + /** + * @return The associated UNIT_BINDER, or nullptr if none. + */ + UNIT_BINDER* GetUnitBinder() const { return m_unitBinder; } + + /** + * Show or hide the error indicator icon adjacent to this field. + * + * @param aShow true to display the error icon, false to hide it + */ + void ShowError( bool aShow ); + + /** + * @return true if the error icon is currently visible. + */ + bool IsShowingError() const { return m_showingError; } + + /** + * @return The label control, or nullptr if no label was created. + */ + wxStaticText* GetLabel() const { return m_label; } + + /** + * @return true if this field has a label. + */ + bool HasLabel() const { return m_label != nullptr; } + + /** + * Create and associate a label with this field. + * The label is positioned according to the LABEL_POSITION in the field position struct. + */ + void CreateLabel(); + +private: + void createErrorIcon(); + + wxWindow* m_parent; + wxString m_fieldId; + wxControl* m_control; + DRC_RE_FIELD_POSITION m_position; + + Getter m_getter; + Setter m_setter; + UNIT_BINDER* m_unitBinder; + + wxStaticBitmap* m_errorIcon; + bool m_showingError; + + wxStaticText* m_label; +}; + +#endif // DRC_RE_OVERLAY_FIELD_H diff --git a/pcbnew/drc/rule_editor/drc_re_overlay_panel_factory.cpp b/pcbnew/drc/rule_editor/drc_re_overlay_panel_factory.cpp new file mode 100644 index 0000000000..5fd1d2c7e9 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_overlay_panel_factory.cpp @@ -0,0 +1,116 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_overlay_panel_factory.h" + +#include "drc_rule_editor_utils.h" + +#include "drc_re_via_style_overlay_panel.h" +#include "drc_re_routing_width_overlay_panel.h" +#include "drc_re_rtg_diff_pair_overlay_panel.h" +#include "drc_re_min_txt_ht_th_overlay_panel.h" +#include "drc_re_abs_length_two_overlay_panel.h" +#include "drc_re_numeric_input_overlay_panel.h" +#include "drc_re_bool_input_overlay_panel.h" +#include "drc_re_allowed_orientation_overlay_panel.h" +#include "drc_re_permitted_layers_overlay_panel.h" + +#include "drc_re_via_style_constraint_data.h" +#include "drc_re_routing_width_constraint_data.h" +#include "drc_re_rtg_diff_pair_constraint_data.h" +#include "drc_re_min_txt_ht_th_constraint_data.h" +#include "drc_re_abs_length_two_constraint_data.h" +#include "drc_re_numeric_input_constraint_data.h" +#include "drc_re_bool_input_constraint_data.h" +#include "drc_re_allowed_orientation_constraint_data.h" +#include "drc_re_permitted_layers_constraint_data.h" + + +DRC_RE_BITMAP_OVERLAY_PANEL* +DRC_RE_OVERLAY_PANEL_FACTORY::CreateOverlayPanel( wxWindow* aParent, + DRC_RULE_EDITOR_CONSTRAINT_NAME aType, + DRC_RE_BASE_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ) +{ + switch( aType ) + { + case VIA_STYLE: + return new DRC_RE_VIA_STYLE_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ), + aUnits ); + + case ROUTING_WIDTH: + return new DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ), + aUnits ); + + case ROUTING_DIFF_PAIR: + return new DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ), + aUnits ); + + case MINIMUM_TEXT_HEIGHT_AND_THICKNESS: + return new DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ), + aUnits ); + + case ABSOLUTE_LENGTH: + return new DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ), + aUnits ); + + case PERMITTED_LAYERS: + return new DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ) ); + + case ALLOWED_ORIENTATION: + return new DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ) ); + + default: + if( DRC_RULE_EDITOR_UTILS::IsNumericInputType( aType ) ) + { + return new DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ), + aUnits ); + } + else if( DRC_RULE_EDITOR_UTILS::IsBoolInputType( aType ) ) + { + return new DRC_RE_BOOL_INPUT_OVERLAY_PANEL( + aParent, + dynamic_cast( aData ) ); + } + + break; + } + + return nullptr; +} diff --git a/pcbnew/drc/rule_editor/drc_re_overlay_panel_factory.h b/pcbnew/drc/rule_editor/drc_re_overlay_panel_factory.h new file mode 100644 index 0000000000..b857528c1a --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_overlay_panel_factory.h @@ -0,0 +1,67 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_OVERLAY_PANEL_FACTORY_H +#define DRC_RE_OVERLAY_PANEL_FACTORY_H + +#include + +#include "drc_rule_editor_enums.h" + +class wxWindow; +class DRC_RE_BITMAP_OVERLAY_PANEL; +class DRC_RE_BASE_CONSTRAINT_DATA; + + +/** + * Factory for creating overlay panels for DRC constraint editing. + * + * Maps constraint types to their corresponding bitmap overlay panel classes. The overlay + * panels display constraint diagrams with input fields positioned over the artwork. + */ +class DRC_RE_OVERLAY_PANEL_FACTORY +{ +public: + /** + * Create an overlay panel for the given constraint type. + * + * Returns the appropriate overlay panel subclass based on the constraint type. For + * constraints that don't have a specialized overlay panel (e.g., custom rules), + * returns nullptr. + * + * @param aParent The parent window for the overlay panel. + * @param aType The constraint type determining which panel class to create. + * @param aData The constraint data to bind to the panel. The factory will cast this + * to the appropriate derived type based on aType. + * @param aUnits The unit system for displaying values. Ignored for constraint types + * that don't display dimensional values. + * @return The created overlay panel, or nullptr if the constraint type doesn't support + * bitmap overlays. + */ + static DRC_RE_BITMAP_OVERLAY_PANEL* CreateOverlayPanel( wxWindow* aParent, + DRC_RULE_EDITOR_CONSTRAINT_NAME aType, + DRC_RE_BASE_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); +}; + +#endif // DRC_RE_OVERLAY_PANEL_FACTORY_H diff --git a/pcbnew/drc/rule_editor/drc_re_overlay_types.h b/pcbnew/drc/rule_editor/drc_re_overlay_types.h new file mode 100644 index 0000000000..bcea766209 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_overlay_types.h @@ -0,0 +1,82 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_OVERLAY_TYPES_H +#define DRC_RE_OVERLAY_TYPES_H + +#include + + +/** + * Specifies the position of a label relative to its associated field. + */ +enum class LABEL_POSITION +{ + NONE, ///< No label + LEFT, ///< Label to the left of the field + RIGHT, ///< Label to the right of the field + TOP, ///< Label above the field + BOTTOM ///< Label below the field +}; + + +/** + * Specifies the position and size of a field overlaid on a constraint bitmap. + * + * All coordinates are in 1x bitmap pixels. When the system selects a higher-resolution + * bitmap (1.5x or 2x), these values are automatically scaled at runtime. + */ +struct DRC_RE_FIELD_POSITION +{ + int xStart; ///< Left edge X coordinate where the field starts + int xEnd; ///< Right edge X coordinate where the field ends + int yTop; ///< Top edge Y coordinate of the field + int tabOrder; ///< Tab navigation order (1-based, lower numbers receive focus first) + + wxString labelText; ///< Optional label text (empty for no label) + LABEL_POSITION labelPosition; ///< Position of label relative to field + + DRC_RE_FIELD_POSITION() : + xStart( 0 ), + xEnd( 0 ), + yTop( 0 ), + tabOrder( 0 ), + labelText(), + labelPosition( LABEL_POSITION::NONE ) + { + } + + DRC_RE_FIELD_POSITION( int aXStart, int aXEnd, int aYTop, int aTabOrder, + const wxString& aLabelText = wxEmptyString, + LABEL_POSITION aLabelPos = LABEL_POSITION::NONE ) : + xStart( aXStart ), + xEnd( aXEnd ), + yTop( aYTop ), + tabOrder( aTabOrder ), + labelText( aLabelText ), + labelPosition( aLabelPos ) + { + } +}; + +#endif // DRC_RE_OVERLAY_TYPES_H diff --git a/pcbnew/drc/rule_editor/drc_re_permitted_layers_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_permitted_layers_constraint_data.h index bf25916fba..e3c2b5857a 100644 --- a/pcbnew/drc/rule_editor/drc_re_permitted_layers_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_permitted_layers_constraint_data.h @@ -47,6 +47,18 @@ public: virtual ~DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_permitted_layers; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_permitted_layers.png (~300x170) + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 20, 60, 35, 1 }, // top layer checkbox (upper left) + { 20, 60, 120, 2 }, // bottom layer checkbox (lower left) + }; + } + VALIDATION_RESULT Validate() const override { VALIDATION_RESULT result; diff --git a/pcbnew/drc/rule_editor/drc_re_permitted_layers_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_permitted_layers_overlay_panel.cpp new file mode 100644 index 0000000000..2809f6002a --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_permitted_layers_overlay_panel.cpp @@ -0,0 +1,104 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_permitted_layers_overlay_panel.h" +#include "drc_re_permitted_layers_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include + + +DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL::DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA* aData ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_topLayerCheckbox( nullptr ), + m_bottomLayerCheckbox( nullptr ) +{ + SetBackgroundBitmap( m_data->GetOverlayBitmap() ); + + std::vector positions = m_data->GetFieldPositions(); + + DRC_RE_OVERLAY_FIELD* topField = AddCheckbox( wxS( "top_layer" ), positions[0] ); + m_topLayerCheckbox = static_cast( topField->GetControl() ); + + DRC_RE_OVERLAY_FIELD* bottomField = AddCheckbox( wxS( "bottom_layer" ), positions[1] ); + m_bottomLayerCheckbox = static_cast( bottomField->GetControl() ); + + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data || !m_topLayerCheckbox || !m_bottomLayerCheckbox ) + return false; + + m_topLayerCheckbox->SetValue( m_data->GetTopLayerEnabled() ); + m_bottomLayerCheckbox->SetValue( m_data->GetBottomLayerEnabled() ); + + return true; +} + + +bool DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data || !m_topLayerCheckbox || !m_bottomLayerCheckbox ) + return false; + + m_data->SetTopLayerEnabled( m_topLayerCheckbox->GetValue() ); + m_data->SetBottomLayerEnabled( m_bottomLayerCheckbox->GetValue() ); + + return true; +} + + +bool DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_permitted_layers_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_permitted_layers_overlay_panel.h new file mode 100644 index 0000000000..22493d2d3f --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_permitted_layers_overlay_panel.h @@ -0,0 +1,58 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL_H +#define DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL_H + +#include "drc_re_bitmap_overlay_panel.h" + +class DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA; +class wxCheckBox; + + +/** + * Overlay panel for permitted layers constraints showing checkboxes + * for top and bottom layer selection positioned over a diagram. + */ +class DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA* aData ); + + ~DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA* m_data; + + wxCheckBox* m_topLayerCheckbox; + wxCheckBox* m_bottomLayerCheckbox; +}; + +#endif // DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_routing_width_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_routing_width_constraint_data.h index e255d3a53a..6839e3f51a 100644 --- a/pcbnew/drc/rule_editor/drc_re_routing_width_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_routing_width_constraint_data.h @@ -49,6 +49,19 @@ public: virtual ~DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_routing_width; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_routing_width.png bitmap + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 75, 135, 35, 1 }, // min_width (left arrow) + { 145, 205, 85, 2 }, // opt_width (bottom center arrow) + { 215, 275, 35, 3 }, // max_width (right arrow) + }; + } + VALIDATION_RESULT Validate() const override { VALIDATION_RESULT result; diff --git a/pcbnew/drc/rule_editor/drc_re_routing_width_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_routing_width_overlay_panel.cpp new file mode 100644 index 0000000000..a574afa657 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_routing_width_overlay_panel.cpp @@ -0,0 +1,125 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_routing_width_overlay_panel.h" +#include "drc_re_routing_width_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include +#include + +#include + + +DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL::DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL( + wxWindow* aParent, + DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_unitsProvider( pcbIUScale, aUnits ) +{ + SetBackgroundBitmap( BITMAPS::constraint_routing_width ); + + std::vector positions = m_data->GetFieldPositions(); + + // Create min width field + m_minRoutingWidthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_width" ), positions[0], m_minRoutingWidthBinder.get() ); + + // Create preferred width field + m_preferredRoutingWidthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "pref_width" ), positions[1], m_preferredRoutingWidthBinder.get() ); + + // Create max width field + m_maxRoutingWidthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_width" ), positions[2], m_maxRoutingWidthBinder.get() ); + + // Position all fields and update the panel layout + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data ) + return false; + + // Convert mm values to internal units and set them in the binders + m_minRoutingWidthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinRoutingWidth() ) ); + m_preferredRoutingWidthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetPreferredRoutingWidth() ) ); + m_maxRoutingWidthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaxRoutingWidth() ) ); + + return true; +} + + +bool DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data ) + return false; + + // Read values from binders (in internal units) and convert to mm for storage + m_data->SetMinRoutingWidth( pcbIUScale.IUTomm( m_minRoutingWidthBinder->GetDoubleValue() ) ); + m_data->SetPreferredRoutingWidth( pcbIUScale.IUTomm( m_preferredRoutingWidthBinder->GetDoubleValue() ) ); + m_data->SetMaxRoutingWidth( pcbIUScale.IUTomm( m_maxRoutingWidthBinder->GetDoubleValue() ) ); + + return true; +} + + +bool DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_routing_width_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_routing_width_overlay_panel.h new file mode 100644 index 0000000000..58874cc38a --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_routing_width_overlay_panel.h @@ -0,0 +1,68 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL_H +#define DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL_H + +#include + +#include + +#include "drc_re_bitmap_overlay_panel.h" + +enum class EDA_UNITS; + +class DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA; +class UNIT_BINDER; + + +/** + * Overlay panel for routing width constraints showing min/preferred/max width fields + * positioned over a diagram. + */ +class DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); + + ~DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA* m_data; + + UNITS_PROVIDER m_unitsProvider; + + std::unique_ptr m_minRoutingWidthBinder; + std::unique_ptr m_preferredRoutingWidthBinder; + std::unique_ptr m_maxRoutingWidthBinder; +}; + +#endif // DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_constraint_data.h index d5bfd1e2da..cafe858d52 100644 --- a/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_constraint_data.h @@ -52,6 +52,23 @@ public: virtual ~DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_routing_diff_pair; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_routing_diff_pair.png bitmap (~570x160) + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 95, 155, 30, 1 }, // min_width (left side, top arrow) + { 95, 155, 55, 2 }, // opt_width (left side, middle) + { 95, 155, 80, 3 }, // max_width (left side, bottom) + { 195, 255, 30, 4 }, // min_gap (center-left, top) + { 195, 255, 55, 5 }, // opt_gap (center-left, middle) + { 195, 255, 80, 6 }, // max_gap (center-left, bottom) + { 420, 520, 55, 7 }, // max_uncoupled (right side) + }; + } + VALIDATION_RESULT Validate() const override { VALIDATION_RESULT result; diff --git a/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.cpp new file mode 100644 index 0000000000..63e375986d --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.cpp @@ -0,0 +1,157 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_rtg_diff_pair_overlay_panel.h" +#include "drc_re_rtg_diff_pair_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include +#include + +#include + + +DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL::DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL( + wxWindow* aParent, + DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_unitsProvider( pcbIUScale, aUnits ) +{ + SetBackgroundBitmap( BITMAPS::constraint_routing_diff_pair ); + + std::vector positions = m_data->GetFieldPositions(); + + // Create gap fields (min/pref/max) + m_minGapBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_gap" ), positions[0], m_minGapBinder.get() ); + + m_preferredGapBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "pref_gap" ), positions[1], m_preferredGapBinder.get() ); + + m_maxGapBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_gap" ), positions[2], m_maxGapBinder.get() ); + + // Create width fields (min/pref/max) + m_minWidthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_width" ), positions[3], m_minWidthBinder.get() ); + + m_preferredWidthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "pref_width" ), positions[4], m_preferredWidthBinder.get() ); + + m_maxWidthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_width" ), positions[5], m_maxWidthBinder.get() ); + + // Create max uncoupled length field + m_maxUncoupledLengthBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_uncoupled" ), positions[6], m_maxUncoupledLengthBinder.get() ); + + // Position all fields and update the panel layout + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data ) + return false; + + // Convert mm values to internal units and set them in the binders + m_minGapBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinGap() ) ); + m_preferredGapBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetPreferredGap() ) ); + m_maxGapBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaxGap() ) ); + + m_minWidthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinWidth() ) ); + m_preferredWidthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetPreferredWidth() ) ); + m_maxWidthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaxWidth() ) ); + + m_maxUncoupledLengthBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaxUncoupledLength() ) ); + + return true; +} + + +bool DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data ) + return false; + + // Read values from binders (in internal units) and convert to mm for storage + m_data->SetMinGap( pcbIUScale.IUTomm( m_minGapBinder->GetDoubleValue() ) ); + m_data->SetPreferredGap( pcbIUScale.IUTomm( m_preferredGapBinder->GetDoubleValue() ) ); + m_data->SetMaxGap( pcbIUScale.IUTomm( m_maxGapBinder->GetDoubleValue() ) ); + + m_data->SetMinWidth( pcbIUScale.IUTomm( m_minWidthBinder->GetDoubleValue() ) ); + m_data->SetPreferredWidth( pcbIUScale.IUTomm( m_preferredWidthBinder->GetDoubleValue() ) ); + m_data->SetMaxWidth( pcbIUScale.IUTomm( m_maxWidthBinder->GetDoubleValue() ) ); + + m_data->SetMaxUncoupledLength( pcbIUScale.IUTomm( m_maxUncoupledLengthBinder->GetDoubleValue() ) ); + + return true; +} + + +bool DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, + std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.h new file mode 100644 index 0000000000..b04e197229 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_rtg_diff_pair_overlay_panel.h @@ -0,0 +1,71 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_RTG_DIFF_PAIR_OVERLAY_PANEL_H +#define DRC_RE_RTG_DIFF_PAIR_OVERLAY_PANEL_H + +#include + +#include + +#include "drc_re_bitmap_overlay_panel.h" + +enum class EDA_UNITS; + +class DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA; +class UNIT_BINDER; + +/** + * Overlay panel for differential pair routing constraints showing gap, width, + * and uncoupled length fields positioned over a diagram. + */ +class DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); + + ~DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA* m_data; + + UNITS_PROVIDER m_unitsProvider; + + std::unique_ptr m_minGapBinder; + std::unique_ptr m_preferredGapBinder; + std::unique_ptr m_maxGapBinder; + std::unique_ptr m_minWidthBinder; + std::unique_ptr m_preferredWidthBinder; + std::unique_ptr m_maxWidthBinder; + std::unique_ptr m_maxUncoupledLengthBinder; +}; + +#endif // DRC_RE_RTG_DIFF_PAIR_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/drc_re_via_style_constraint_data.h b/pcbnew/drc/rule_editor/drc_re_via_style_constraint_data.h index ae876770c6..907bf1b657 100644 --- a/pcbnew/drc/rule_editor/drc_re_via_style_constraint_data.h +++ b/pcbnew/drc/rule_editor/drc_re_via_style_constraint_data.h @@ -51,6 +51,22 @@ public: virtual ~DRC_RE_VIA_STYLE_CONSTRAINT_DATA() = default; + BITMAPS GetOverlayBitmap() const override { return BITMAPS::constraint_via_style; } + + std::vector GetFieldPositions() const override + { + // Positions measured from constraint_via_style.png bitmap + // Format: { xStart, xEnd, yTop, tabOrder } + return { + { 260, 340, 25, 1 }, // min_via_diameter (right side, top) + { 260, 340, 55, 2 }, // opt_via_diameter (right side, middle) + { 260, 340, 85, 3 }, // max_via_diameter (right side, bottom) + { 260, 340, 115, 4 }, // min_via_hole (right side, below diameter) + { 260, 340, 145, 5 }, // opt_via_hole + { 260, 340, 175, 6 }, // max_via_hole + }; + } + VALIDATION_RESULT Validate() const override { VALIDATION_RESULT result; diff --git a/pcbnew/drc/rule_editor/drc_re_via_style_overlay_panel.cpp b/pcbnew/drc/rule_editor/drc_re_via_style_overlay_panel.cpp new file mode 100644 index 0000000000..3260d6dadc --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_via_style_overlay_panel.cpp @@ -0,0 +1,150 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "drc_re_via_style_overlay_panel.h" +#include "drc_re_via_style_constraint_data.h" +#include "drc_rule_editor_utils.h" + +#include +#include + +#include + + +DRC_RE_VIA_STYLE_OVERLAY_PANEL::DRC_RE_VIA_STYLE_OVERLAY_PANEL( + wxWindow* aParent, DRC_RE_VIA_STYLE_CONSTRAINT_DATA* aData, EDA_UNITS aUnits ) : + DRC_RE_BITMAP_OVERLAY_PANEL( aParent ), + m_data( aData ), + m_unitsProvider( pcbIUScale, aUnits ) +{ + SetBackgroundBitmap( BITMAPS::constraint_via_style ); + + std::vector positions = m_data->GetFieldPositions(); + + // Create via diameter fields (min/pref/max) + m_minViaDiameterBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_via_diameter" ), positions[0], + m_minViaDiameterBinder.get() ); + + m_maxViaDiameterBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_via_diameter" ), positions[1], + m_maxViaDiameterBinder.get() ); + + m_prefViaDiameterBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "pref_via_diameter" ), positions[2], + m_prefViaDiameterBinder.get() ); + + // Create via hole size fields (min/pref/max) + m_minViaHoleSizeBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "min_via_hole" ), positions[3], + m_minViaHoleSizeBinder.get() ); + + m_maxViaHoleSizeBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "max_via_hole" ), positions[4], + m_maxViaHoleSizeBinder.get() ); + + m_prefViaHoleSizeBinder = std::make_unique( + &m_unitsProvider, this, nullptr, nullptr, nullptr, false, false ); + + AddFieldWithUnits( wxS( "pref_via_hole" ), positions[5], + m_prefViaHoleSizeBinder.get() ); + + // Position all fields and update the panel layout + PositionFields(); + TransferDataToWindow(); +} + + +bool DRC_RE_VIA_STYLE_OVERLAY_PANEL::TransferDataToWindow() +{ + if( !m_data ) + return false; + + // Convert mm values to internal units and set them in the unit binders + m_minViaDiameterBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinViaDiameter() ) ); + m_prefViaDiameterBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetPreferredViaDiameter() ) ); + m_maxViaDiameterBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaxViaDiameter() ) ); + + m_minViaHoleSizeBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMinViaHoleSize() ) ); + m_prefViaHoleSizeBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetPreferredViaHoleSize() ) ); + m_maxViaHoleSizeBinder->SetDoubleValue( pcbIUScale.mmToIU( m_data->GetMaxViaHoleSize() ) ); + + return true; +} + + +bool DRC_RE_VIA_STYLE_OVERLAY_PANEL::TransferDataFromWindow() +{ + if( !m_data ) + return false; + + // Read values from unit binders and convert from internal units to mm + m_data->SetMinViaDiameter( pcbIUScale.IUTomm( m_minViaDiameterBinder->GetDoubleValue() ) ); + m_data->SetPreferredViaDiameter( pcbIUScale.IUTomm( m_prefViaDiameterBinder->GetDoubleValue() ) ); + m_data->SetMaxViaDiameter( pcbIUScale.IUTomm( m_maxViaDiameterBinder->GetDoubleValue() ) ); + + m_data->SetMinViaHoleSize( pcbIUScale.IUTomm( m_minViaHoleSizeBinder->GetDoubleValue() ) ); + m_data->SetPreferredViaHoleSize( pcbIUScale.IUTomm( m_prefViaHoleSizeBinder->GetDoubleValue() ) ); + m_data->SetMaxViaHoleSize( pcbIUScale.IUTomm( m_maxViaHoleSizeBinder->GetDoubleValue() ) ); + + return true; +} + + +bool DRC_RE_VIA_STYLE_OVERLAY_PANEL::ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) +{ + TransferDataFromWindow(); + + VALIDATION_RESULT result = m_data->Validate(); + + if( !result.isValid ) + { + *aErrorCount = result.errors.size(); + + for( size_t i = 0; i < result.errors.size(); i++ ) + *aValidationMessage += DRC_RULE_EDITOR_UTILS::FormatErrorMessage( i + 1, result.errors[i] ); + + return false; + } + + return true; +} + + +wxString DRC_RE_VIA_STYLE_OVERLAY_PANEL::GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) +{ + if( !m_data ) + return wxEmptyString; + + return m_data->GenerateRule( aContext ); +} diff --git a/pcbnew/drc/rule_editor/drc_re_via_style_overlay_panel.h b/pcbnew/drc/rule_editor/drc_re_via_style_overlay_panel.h new file mode 100644 index 0000000000..e3a74d23a9 --- /dev/null +++ b/pcbnew/drc/rule_editor/drc_re_via_style_overlay_panel.h @@ -0,0 +1,74 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DRC_RE_VIA_STYLE_OVERLAY_PANEL_H +#define DRC_RE_VIA_STYLE_OVERLAY_PANEL_H + +#include + +#include + +#include "drc_re_bitmap_overlay_panel.h" + +enum class EDA_UNITS; + +class DRC_RE_VIA_STYLE_CONSTRAINT_DATA; +class UNIT_BINDER; + + +/** + * Overlay panel for via style constraints showing via diameter and hole size fields + * positioned over a diagram. + */ +class DRC_RE_VIA_STYLE_OVERLAY_PANEL : public DRC_RE_BITMAP_OVERLAY_PANEL +{ +public: + DRC_RE_VIA_STYLE_OVERLAY_PANEL( wxWindow* aParent, + DRC_RE_VIA_STYLE_CONSTRAINT_DATA* aData, + EDA_UNITS aUnits ); + + ~DRC_RE_VIA_STYLE_OVERLAY_PANEL() override = default; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + + bool ValidateInputs( int* aErrorCount, std::string* aValidationMessage ) override; + wxString GenerateRule( const RULE_GENERATION_CONTEXT& aContext ) override; + +private: + DRC_RE_VIA_STYLE_CONSTRAINT_DATA* m_data; + + UNITS_PROVIDER m_unitsProvider; + + // Unit binders for via diameter fields + std::unique_ptr m_minViaDiameterBinder; + std::unique_ptr m_prefViaDiameterBinder; + std::unique_ptr m_maxViaDiameterBinder; + + // Unit binders for via hole size fields + std::unique_ptr m_minViaHoleSizeBinder; + std::unique_ptr m_prefViaHoleSizeBinder; + std::unique_ptr m_maxViaHoleSizeBinder; +}; + +#endif // DRC_RE_VIA_STYLE_OVERLAY_PANEL_H diff --git a/pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp b/pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp index e34ebb3ebb..3212c3a9af 100644 --- a/pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp +++ b/pcbnew/drc/rule_editor/panel_drc_rule_editor.cpp @@ -61,6 +61,19 @@ #include #include #include "drc_re_condition_group_panel.h" + +// Overlay panels (new bitmap-based implementation) +#include "drc_re_via_style_overlay_panel.h" +#include "drc_re_routing_width_overlay_panel.h" +#include "drc_re_rtg_diff_pair_overlay_panel.h" +#include "drc_re_min_txt_ht_th_overlay_panel.h" +#include "drc_re_abs_length_two_overlay_panel.h" +#include "drc_re_numeric_input_overlay_panel.h" +#include "drc_re_bool_input_overlay_panel.h" +#include "drc_re_allowed_orientation_overlay_panel.h" +#include "drc_re_permitted_layers_overlay_panel.h" + +#include #include "drc_re_numeric_input_constraint_data.h" #include "drc_re_bool_input_constraint_data.h" #include "drc_re_via_style_constraint_data.h" @@ -209,13 +222,17 @@ bool PANEL_DRC_RULE_EDITOR::TransferDataToWindow() m_conditionGroupPanel->ParseCondition( cond ); } - return dynamic_cast( m_constraintPanel )->TransferDataToWindow(); + if( m_constraintPanel ) + return m_constraintPanel->TransferDataToWindow(); + + return true; } bool PANEL_DRC_RULE_EDITOR::TransferDataFromWindow() { - dynamic_cast( m_constraintPanel )->TransferDataFromWindow(); + if( m_constraintPanel ) + m_constraintPanel->TransferDataFromWindow(); m_constraintData->SetRuleName( m_nameCtrl->GetValue() ); m_constraintData->SetComment( m_commentCtrl->GetValue() ); @@ -245,65 +262,68 @@ bool PANEL_DRC_RULE_EDITOR::TransferDataFromWindow() DRC_RULE_EDITOR_CONTENT_PANEL_BASE* PANEL_DRC_RULE_EDITOR::getConstraintPanel( wxWindow* aParent, const DRC_RULE_EDITOR_CONSTRAINT_NAME& aConstraintType ) { + // Use millimeters as default unit since constraint data stores values in mm + EDA_UNITS units = EDA_UNITS::MM; + switch( aConstraintType ) { case VIA_STYLE: - return new DRC_RE_VIA_STYLE_PANEL( aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_VIA_STYLE_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get(), + units ); + case MINIMUM_TEXT_HEIGHT_AND_THICKNESS: - return new DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_PANEL( - aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_MIN_TXT_HT_TH_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get(), + units ); + case ROUTING_DIFF_PAIR: - return new DRC_RE_ROUTING_DIFF_PAIR_PANEL( - aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_ROUTING_DIFF_PAIR_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get(), + units ); + case ROUTING_WIDTH: - return new DRC_RE_ROUTING_WIDTH_PANEL( - aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_ROUTING_WIDTH_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get(), + units ); + case PERMITTED_LAYERS: - return new DRC_RE_PERMITTED_LAYERS_PANEL( - aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_PERMITTED_LAYERS_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get() ); + case ALLOWED_ORIENTATION: - return new DRC_RE_ALLOWED_ORIENTATION_PANEL( - aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_ALLOWED_ORIENTATION_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get() ); + case CUSTOM_RULE: return new DRC_RE_CUSTOM_RULE_PANEL( aParent, dynamic_pointer_cast( m_constraintData ) ); + case ABSOLUTE_LENGTH: - return new DRC_RE_ABSOLUTE_LENGTH_TWO_PANEL( - aParent, m_constraintTitle, - dynamic_pointer_cast( m_constraintData ) ); + return new DRC_RE_ABS_LENGTH_TWO_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get(), + units ); + default: if( DRC_RULE_EDITOR_UTILS::IsNumericInputType( aConstraintType ) ) { - DRC_RE_NUMERIC_INPUT_CONSTRAINT_PANEL_PARAMS numericInputParams( - *m_constraintTitle, dynamic_pointer_cast( m_constraintData ), - aConstraintType, *m_constraintTitle ); - - if( aConstraintType == MINIMUM_THERMAL_RELIEF_SPOKE_COUNT || aConstraintType == MAXIMUM_VIA_COUNT ) - numericInputParams.SetInputIsCount( true ); - - return new DRC_RE_NUMERIC_INPUT_PANEL( aParent, numericInputParams ); + return new DRC_RE_NUMERIC_INPUT_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get(), + units ); } else if( DRC_RULE_EDITOR_UTILS::IsBoolInputType( aConstraintType ) ) { - wxString customLabel; - - switch( aConstraintType ) - { - case VIAS_UNDER_SMD: customLabel = "Allow Vias under SMD Pads"; break; - default: customLabel = *m_constraintTitle; - } - - DRC_RE_BOOL_INPUT_CONSTRAINT_PANEL_PARAMS boolInputParams( - *m_constraintTitle, dynamic_pointer_cast( m_constraintData ), - aConstraintType, customLabel ); - - return new DRC_RE_BOOL_INPUT_PANEL( aParent, boolInputParams ); + return new DRC_RE_BOOL_INPUT_OVERLAY_PANEL( + aParent, + dynamic_pointer_cast( m_constraintData ).get() ); } else { diff --git a/qa/tests/pcbnew/CMakeLists.txt b/qa/tests/pcbnew/CMakeLists.txt index 94c8aa0182..aac398b45f 100644 --- a/qa/tests/pcbnew/CMakeLists.txt +++ b/qa/tests/pcbnew/CMakeLists.txt @@ -96,6 +96,7 @@ set( QA_PCBNEW_SRCS drc/test_drc_tuning_profiles.cpp drc/test_drc_creepage_issue21482.cpp drc/test_drc_rule_editor.cpp + drc/test_drc_bitmap_overlay_panel.cpp pcb_io/altium/test_altium_rule_transformer.cpp pcb_io/altium/test_altium_pcblib_import.cpp diff --git a/qa/tests/pcbnew/drc/test_drc_bitmap_overlay_panel.cpp b/qa/tests/pcbnew/drc/test_drc_bitmap_overlay_panel.cpp new file mode 100644 index 0000000000..a1f75c200e --- /dev/null +++ b/qa/tests/pcbnew/drc/test_drc_bitmap_overlay_panel.cpp @@ -0,0 +1,532 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright The KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include +#include + +#include + + +/** + * Helper functions that mirror the logic from DRC_RE_BITMAP_OVERLAY_PANEL. + * These allow testing the mathematical operations without requiring wxWidgets GUI. + */ +namespace BITMAP_OVERLAY_TEST_HELPERS +{ + +/** + * Compute the scale factor from a raw content scale factor. + * Mirrors GetScaleFactor() logic from DRC_RE_BITMAP_OVERLAY_PANEL. + */ +double ComputeScaleFactor( double aRawScale ) +{ + if( aRawScale < 1.25 ) + return 1.0; + else if( aRawScale < 1.75 ) + return 1.5; + else + return 2.0; +} + + +/** + * Scale a position from 1x bitmap coordinates to display coordinates. + * Mirrors ScalePosition() logic from DRC_RE_BITMAP_OVERLAY_PANEL. + */ +wxPoint ScalePosition( int aX, int aY, double aScaleFactor ) +{ + return wxPoint( static_cast( aX * aScaleFactor ), static_cast( aY * aScaleFactor ) ); +} + + +/** + * Scale a size from 1x bitmap coordinates to display coordinates. + * Mirrors ScaleSize() logic from DRC_RE_BITMAP_OVERLAY_PANEL. + */ +wxSize ScaleSize( int aWidth, int aHeight, double aScaleFactor ) +{ + return wxSize( static_cast( aWidth * aScaleFactor ), static_cast( aHeight * aScaleFactor ) ); +} + + +/** + * Check if a field position exceeds bitmap bounds. + * Mirrors bounds check logic from PositionFields() in DRC_RE_BITMAP_OVERLAY_PANEL. + */ +bool IsOutOfBounds( const wxPoint& aScaledPos, const wxSize& aScaledSize, const wxSize& aBitmapSize ) +{ + return ( aScaledPos.x + aScaledSize.GetWidth() > aBitmapSize.GetWidth() || + aScaledPos.y + aScaledSize.GetHeight() > aBitmapSize.GetHeight() ); +} + + +/** + * Sort field positions by tab order. + * Mirrors expected keyboard navigation order. + */ +void SortByTabOrder( std::vector& aPositions ) +{ + std::sort( aPositions.begin(), aPositions.end(), + []( const DRC_RE_FIELD_POSITION& a, const DRC_RE_FIELD_POSITION& b ) + { + return a.tabOrder < b.tabOrder; + } ); +} + +} // namespace BITMAP_OVERLAY_TEST_HELPERS + + +BOOST_AUTO_TEST_SUITE( DrcBitmapOverlayPanel ) + + +// ============================================================================ +// T025: ScalePosition Tests +// ============================================================================ + +BOOST_AUTO_TEST_CASE( ScalePosition_1x ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + double scale = 1.0; + + // Test various positions at 1x scale + wxPoint result1 = ScalePosition( 0, 0, scale ); + BOOST_CHECK_EQUAL( result1.x, 0 ); + BOOST_CHECK_EQUAL( result1.y, 0 ); + + wxPoint result2 = ScalePosition( 100, 50, scale ); + BOOST_CHECK_EQUAL( result2.x, 100 ); + BOOST_CHECK_EQUAL( result2.y, 50 ); + + wxPoint result3 = ScalePosition( 256, 128, scale ); + BOOST_CHECK_EQUAL( result3.x, 256 ); + BOOST_CHECK_EQUAL( result3.y, 128 ); + + // Test edge case with odd numbers + wxPoint result4 = ScalePosition( 127, 63, scale ); + BOOST_CHECK_EQUAL( result4.x, 127 ); + BOOST_CHECK_EQUAL( result4.y, 63 ); +} + + +BOOST_AUTO_TEST_CASE( ScalePosition_1_5x ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + double scale = 1.5; + + // Test various positions at 1.5x scale + wxPoint result1 = ScalePosition( 0, 0, scale ); + BOOST_CHECK_EQUAL( result1.x, 0 ); + BOOST_CHECK_EQUAL( result1.y, 0 ); + + wxPoint result2 = ScalePosition( 100, 50, scale ); + BOOST_CHECK_EQUAL( result2.x, 150 ); + BOOST_CHECK_EQUAL( result2.y, 75 ); + + wxPoint result3 = ScalePosition( 200, 100, scale ); + BOOST_CHECK_EQUAL( result3.x, 300 ); + BOOST_CHECK_EQUAL( result3.y, 150 ); + + // Test truncation behavior with odd numbers + wxPoint result4 = ScalePosition( 127, 63, scale ); + BOOST_CHECK_EQUAL( result4.x, static_cast( 127 * 1.5 ) ); // 190 + BOOST_CHECK_EQUAL( result4.y, static_cast( 63 * 1.5 ) ); // 94 +} + + +BOOST_AUTO_TEST_CASE( ScalePosition_2x ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + double scale = 2.0; + + // Test various positions at 2x scale + wxPoint result1 = ScalePosition( 0, 0, scale ); + BOOST_CHECK_EQUAL( result1.x, 0 ); + BOOST_CHECK_EQUAL( result1.y, 0 ); + + wxPoint result2 = ScalePosition( 100, 50, scale ); + BOOST_CHECK_EQUAL( result2.x, 200 ); + BOOST_CHECK_EQUAL( result2.y, 100 ); + + wxPoint result3 = ScalePosition( 256, 128, scale ); + BOOST_CHECK_EQUAL( result3.x, 512 ); + BOOST_CHECK_EQUAL( result3.y, 256 ); + + // Test that coordinates double exactly + wxPoint result4 = ScalePosition( 127, 63, scale ); + BOOST_CHECK_EQUAL( result4.x, 254 ); + BOOST_CHECK_EQUAL( result4.y, 126 ); +} + + +BOOST_AUTO_TEST_CASE( ScaleSize_AllFactors ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Test size scaling at all three scale factors + int width = 80; + int height = 24; + + wxSize size1x = ScaleSize( width, height, 1.0 ); + BOOST_CHECK_EQUAL( size1x.GetWidth(), 80 ); + BOOST_CHECK_EQUAL( size1x.GetHeight(), 24 ); + + wxSize size1_5x = ScaleSize( width, height, 1.5 ); + BOOST_CHECK_EQUAL( size1_5x.GetWidth(), 120 ); + BOOST_CHECK_EQUAL( size1_5x.GetHeight(), 36 ); + + wxSize size2x = ScaleSize( width, height, 2.0 ); + BOOST_CHECK_EQUAL( size2x.GetWidth(), 160 ); + BOOST_CHECK_EQUAL( size2x.GetHeight(), 48 ); +} + + +// ============================================================================ +// T026: GetScaleFactor Tests +// ============================================================================ + +BOOST_AUTO_TEST_CASE( GetScaleFactor_Returns1x_ForLowDPI ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Values below 1.25 should return 1.0 + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.0 ), 1.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.1 ), 1.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.24 ), 1.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.249 ), 1.0 ); + + // Edge case at boundary (1.25 should NOT return 1.0) + BOOST_CHECK( ComputeScaleFactor( 1.25 ) != 1.0 ); +} + + +BOOST_AUTO_TEST_CASE( GetScaleFactor_Returns1_5x_ForMediumDPI ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Values at or above 1.25 but below 1.75 should return 1.5 + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.25 ), 1.5 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.5 ), 1.5 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.74 ), 1.5 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.749 ), 1.5 ); + + // Edge case at boundary (1.75 should NOT return 1.5) + BOOST_CHECK( ComputeScaleFactor( 1.75 ) != 1.5 ); +} + + +BOOST_AUTO_TEST_CASE( GetScaleFactor_Returns2x_ForHighDPI ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Values at or above 1.75 should return 2.0 + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.75 ), 2.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 2.0 ), 2.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 2.5 ), 2.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 3.0 ), 2.0 ); +} + + +BOOST_AUTO_TEST_CASE( GetScaleFactor_BoundaryValues ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Test exact boundary values + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.24999 ), 1.0 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.25 ), 1.5 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.74999 ), 1.5 ); + BOOST_CHECK_EQUAL( ComputeScaleFactor( 1.75 ), 2.0 ); +} + + +// ============================================================================ +// T027: Tab Order Sorting Tests +// ============================================================================ + +BOOST_AUTO_TEST_CASE( TabOrderSorting_AlreadySorted ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + std::vector fields = { + { 10, 50, 20, 1 }, // tabOrder = 1 + { 60, 100, 20, 2 }, // tabOrder = 2 + { 110, 150, 20, 3 } // tabOrder = 3 + }; + + SortByTabOrder( fields ); + + BOOST_CHECK_EQUAL( fields[0].tabOrder, 1 ); + BOOST_CHECK_EQUAL( fields[1].tabOrder, 2 ); + BOOST_CHECK_EQUAL( fields[2].tabOrder, 3 ); +} + + +BOOST_AUTO_TEST_CASE( TabOrderSorting_ReversedOrder ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + std::vector fields = { + { 10, 50, 20, 3 }, // tabOrder = 3 + { 60, 100, 20, 2 }, // tabOrder = 2 + { 110, 150, 20, 1 } // tabOrder = 1 + }; + + SortByTabOrder( fields ); + + BOOST_CHECK_EQUAL( fields[0].tabOrder, 1 ); + BOOST_CHECK_EQUAL( fields[1].tabOrder, 2 ); + BOOST_CHECK_EQUAL( fields[2].tabOrder, 3 ); + + // Verify the associated coordinates moved with the tab order + BOOST_CHECK_EQUAL( fields[0].xStart, 110 ); // Was originally tabOrder 1 + BOOST_CHECK_EQUAL( fields[1].xStart, 60 ); // Was originally tabOrder 2 + BOOST_CHECK_EQUAL( fields[2].xStart, 10 ); // Was originally tabOrder 3 +} + + +BOOST_AUTO_TEST_CASE( TabOrderSorting_MixedOrder ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + std::vector fields = { + { 10, 50, 20, 5 }, + { 60, 100, 40, 1 }, + { 110, 150, 60, 3 }, + { 160, 200, 80, 2 }, + { 210, 250, 100, 4 } + }; + + SortByTabOrder( fields ); + + BOOST_CHECK_EQUAL( fields[0].tabOrder, 1 ); + BOOST_CHECK_EQUAL( fields[1].tabOrder, 2 ); + BOOST_CHECK_EQUAL( fields[2].tabOrder, 3 ); + BOOST_CHECK_EQUAL( fields[3].tabOrder, 4 ); + BOOST_CHECK_EQUAL( fields[4].tabOrder, 5 ); +} + + +BOOST_AUTO_TEST_CASE( TabOrderSorting_DuplicateOrders ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Duplicate tab orders should maintain relative position (stable sort behavior) + std::vector fields = { + { 10, 50, 20, 2 }, + { 60, 100, 40, 1 }, + { 110, 150, 60, 2 }, // Duplicate tabOrder = 2 + { 160, 200, 80, 1 } // Duplicate tabOrder = 1 + }; + + SortByTabOrder( fields ); + + // All tabOrder 1 fields should come before tabOrder 2 fields + BOOST_CHECK_EQUAL( fields[0].tabOrder, 1 ); + BOOST_CHECK_EQUAL( fields[1].tabOrder, 1 ); + BOOST_CHECK_EQUAL( fields[2].tabOrder, 2 ); + BOOST_CHECK_EQUAL( fields[3].tabOrder, 2 ); +} + + +BOOST_AUTO_TEST_CASE( TabOrderSorting_SingleField ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + std::vector fields = { { 10, 50, 20, 1 } }; + + SortByTabOrder( fields ); + + BOOST_CHECK_EQUAL( fields.size(), 1 ); + BOOST_CHECK_EQUAL( fields[0].tabOrder, 1 ); +} + + +BOOST_AUTO_TEST_CASE( TabOrderSorting_EmptyVector ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + std::vector fields; + + SortByTabOrder( fields ); + + BOOST_CHECK( fields.empty() ); +} + + +// ============================================================================ +// T028: Bounds Warning Tests +// ============================================================================ + +BOOST_AUTO_TEST_CASE( BoundsWarning_WithinBounds ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Field completely within bounds + wxPoint pos1( 10, 10 ); + wxSize size1( 80, 24 ); + BOOST_CHECK( !IsOutOfBounds( pos1, size1, bitmapSize ) ); + + // Field at edge of bounds (exactly fitting) + wxPoint pos2( 220, 176 ); + wxSize size2( 80, 24 ); + BOOST_CHECK( !IsOutOfBounds( pos2, size2, bitmapSize ) ); + + // Field at origin + wxPoint pos3( 0, 0 ); + wxSize size3( 100, 50 ); + BOOST_CHECK( !IsOutOfBounds( pos3, size3, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_ExceedsWidth ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Field exceeds right edge + wxPoint pos( 250, 10 ); + wxSize size( 80, 24 ); + + BOOST_CHECK( IsOutOfBounds( pos, size, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_ExceedsHeight ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Field exceeds bottom edge + wxPoint pos( 10, 180 ); + wxSize size( 80, 30 ); + + BOOST_CHECK( IsOutOfBounds( pos, size, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_ExceedsBothDimensions ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Field exceeds both edges + wxPoint pos( 250, 180 ); + wxSize size( 80, 30 ); + + BOOST_CHECK( IsOutOfBounds( pos, size, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_FieldLargerThanBitmap ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Field larger than entire bitmap + wxPoint pos( 0, 0 ); + wxSize size( 400, 300 ); + + BOOST_CHECK( IsOutOfBounds( pos, size, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_AtScaledPositions ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + // Simulate a field at 1x coordinates that fits, but may not fit when scaled + int baseX = 250; + int baseY = 180; + int baseWidth = 40; + int baseHeight = 15; + + // At 1x, bitmap is 300x200 + wxSize bitmap1x( 300, 200 ); + wxPoint pos1x = ScalePosition( baseX, baseY, 1.0 ); + wxSize size1x = ScaleSize( baseWidth, baseHeight, 1.0 ); + BOOST_CHECK( !IsOutOfBounds( pos1x, size1x, bitmap1x ) ); + + // At 1.5x, bitmap becomes 450x300 + wxSize bitmap1_5x( 450, 300 ); + wxPoint pos1_5x = ScalePosition( baseX, baseY, 1.5 ); + wxSize size1_5x = ScaleSize( baseWidth, baseHeight, 1.5 ); + BOOST_CHECK( !IsOutOfBounds( pos1_5x, size1_5x, bitmap1_5x ) ); + + // At 2x, bitmap becomes 600x400 + wxSize bitmap2x( 600, 400 ); + wxPoint pos2x = ScalePosition( baseX, baseY, 2.0 ); + wxSize size2x = ScaleSize( baseWidth, baseHeight, 2.0 ); + BOOST_CHECK( !IsOutOfBounds( pos2x, size2x, bitmap2x ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_EdgeCases ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Field exactly at boundary (should be within bounds) + wxPoint posExact( 220, 176 ); + wxSize sizeExact( 80, 24 ); + BOOST_CHECK( !IsOutOfBounds( posExact, sizeExact, bitmapSize ) ); + + // Field 1 pixel over width + wxPoint posOverWidth( 221, 176 ); + BOOST_CHECK( IsOutOfBounds( posOverWidth, sizeExact, bitmapSize ) ); + + // Field 1 pixel over height + wxPoint posOverHeight( 220, 177 ); + BOOST_CHECK( IsOutOfBounds( posOverHeight, sizeExact, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_CASE( BoundsWarning_ZeroSizedField ) +{ + using namespace BITMAP_OVERLAY_TEST_HELPERS; + + wxSize bitmapSize( 300, 200 ); + + // Zero-sized field should never be out of bounds + wxPoint pos( 0, 0 ); + wxSize zeroSize( 0, 0 ); + BOOST_CHECK( !IsOutOfBounds( pos, zeroSize, bitmapSize ) ); + + // Zero-sized field at edge + wxPoint posEdge( 300, 200 ); + BOOST_CHECK( !IsOutOfBounds( posEdge, zeroSize, bitmapSize ) ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/resources/bitmaps_png/CMakeLists.txt b/resources/bitmaps_png/CMakeLists.txt index 6bc5085dbc..e00cb915e5 100644 --- a/resources/bitmaps_png/CMakeLists.txt +++ b/resources/bitmaps_png/CMakeLists.txt @@ -714,6 +714,48 @@ set( BMAPS_256 tune_diff_pair_skew_legend ) +# Constraint bitmaps with light/dark theme variants (for DRC rule editor panels) +# These are in sources/light/constraints/ and sources/dark/constraints/ +set( BMAPS_CONSTRAINTS + absolute-length-2 + allowed-orientation + basic-clearance + board-outline-clearance + clearance + copper_to_edge_clearance + copper-to-hole-clearance + creepage-distance + hole-size + hole-to-hole-clearance + hole-to-hole-distance + length + matched-length-diff-pair + maximum-allowed-deviation + maximum-via-count + minimum-angular-ring + minimum-annular-width + minimum-clearance + minimum-connection-width + minimum-item-clearance + minimum-soldermask-silver + minimum-text-height-and-thickness + minimum_thermal_relief_spoke_count + minimum-through-hole + minimum-track-width + minimum-uvia-diameter + minimum-uvia-hole + minimum-via-diameter + permitted-layers + routing-diff-pair + routing-width + silk_clearance + silk-to-soldermask-clearance + soldermask-expansion + solderpaste-expansion + via-style + vias-under-smd + ) + # Images in this section are generated at whatever resolution is set in the source SVG file # Use Inkscape Document Properties > Custom Size to set (make sure units are pixels) # These are used for images in the UI that are not-square or very large (infographics, etc) @@ -944,6 +986,64 @@ function( bitmap_dir pngWidth pngHeight bmapList ) endfunction() +# Function bitmap_dir_constraints +# Like bitmap_dir but looks for SVGs in sources/${theme}/constraints/ subdirectory. +# Used for DRC rule editor constraint overlay panel images that need light/dark variants. +# Transforms hyphens to underscores in output names to match BITMAPS enum naming convention. +function( bitmap_dir_constraints pngWidth pngHeight bmapList ) + + set( pngDir "${CMAKE_CURRENT_SOURCE_DIR}/png" ) + + file( MAKE_DIRECTORY ${pngDir} ) + file( MAKE_DIRECTORY ${TMP_DIR} ) + + foreach( theme ${THEMES} ) + + if( NOT ${theme} STREQUAL "light" ) + set( themeTag "_${theme}" ) + else() + set( themeTag "" ) + endif() + + if( ${pngHeight} EQUAL -1 ) + set( heightTag "" ) + else() + set( heightTag "_${pngHeight}" ) + endif() + + foreach( bmn ${bmapList} ) + + # Transform hyphens to underscores for the output name to match BITMAPS enum + string( REPLACE "-" "_" bmnNormalized "${bmn}" ) + + set( svgFile "${CMAKE_CURRENT_SOURCE_DIR}/sources/${theme}/constraints/${bmn}.svg" ) + set( pngFile "constraint_${bmnNormalized}${themeTag}${heightTag}.png" ) + set( pngPath "${pngDir}/${pngFile}" ) + set( tmpFile "${TMP_DIR}/${pngFile}" ) + + if( NOT EXISTS ${svgFile} ) + message( "Warning: Source SVG ${svgFile} does not exist!" ) + continue() + endif() + + svg2png( ${svgFile} ${tmpFile} ${pngWidth} ${pngHeight} ) + png2png( ${tmpFile} ${pngPath} ) + + set( bitmapInfo + " aBitmapInfoCache[BITMAPS::constraint_${bmnNormalized}].emplace_back( BITMAPS::constraint_${bmnNormalized}, wxT( \"${pngFile}\" ), ${pngHeight}, wxT( \"${theme}\" ) );\n" + ) + + set( BITMAP_INFO_LIST "${BITMAP_INFO_LIST}${bitmapInfo}" ) + list( APPEND ALL_PNGS ${pngPath} ) + endforeach() + endforeach() + + set( ALL_PNGS ${ALL_PNGS} PARENT_SCOPE ) + set( BITMAP_INFO_LIST ${BITMAP_INFO_LIST} PARENT_SCOPE ) + +endfunction() + + include( FindUnixCommands ) if( TAR STREQUAL "TAR-NOTFOUND" ) @@ -1070,6 +1170,9 @@ if( MAINTAIN_PNGS ) bitmap_dir( -1 -1 "${BMAPS_OTHER}" ) + # Constraint bitmaps with light/dark theme variants (DRC rule editor panels) + bitmap_dir_constraints( -1 -1 "${BMAPS_CONSTRAINTS}" ) + configure_file( ${BITMAP_INFO_TEMPLATE} ${BITMAP_INFO_FILE} NEWLINE_STYLE UNIX ) add_custom_target( generate_pngs ALL diff --git a/resources/bitmaps_png/generate_themed_constraints.py b/resources/bitmaps_png/generate_themed_constraints.py new file mode 100644 index 0000000000..b73dedbcc3 --- /dev/null +++ b/resources/bitmaps_png/generate_themed_constraints.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +""" +Generate themed (light/dark) versions of constraint SVGs for KiCad DRC Rule Editor. + +Color palette from https://dev-docs.kicad.org/en/rules-guidelines/icon-design/ +""" + +import os +import re +import shutil +from pathlib import Path + +# Color transformations from light to dark theme (case-insensitive) +LIGHT_TO_DARK_COLORS = { + '#545454': '#ded3dd', # Primary Gray stroke + '#606060': '#606060', # Dense fills - stays same + '#b9b9b9': '#e0e0e0', # Accent Grey + '#1a81c4': '#42b8eb', # Primary Blue + '#39b4ea': '#1a81c4', # Accent Blue (swap) + '#bf2641': '#f2647e', # Primary Red + '#f3f3f3': '#545454', # Area Fill + '#dcdcdc': '#545454', # Light boundary lines + '#000000': '#ded3dd', # Black strokes become light + '#000fe5': '#42b8eb', # Blue arrows +} + +# Files to process - mapping from source name to output name +# Format: 'source_filename.svg': 'output-name.svg' +CONSTRAINT_FILES = { + # Specialized panels + 'absolute-lenght-2.svg': 'absolute-length-2.svg', + 'allowed-orientation.svg': 'allowed-orientation.svg', + 'vias-under-SMD.svg': 'vias-under-smd.svg', + 'minimum_text_height_and_thickness.svg': 'minimum-text-height-and-thickness.svg', + 'permitted-layers.svg': 'permitted-layers.svg', + 'via-style.svg': 'via-style.svg', + + # Numeric input constraints + 'Basic clearance.svg': 'basic-clearance.svg', + 'board-outline-clearance.svg': 'board-outline-clearance.svg', + 'minimum_clearance.svg': 'minimum-clearance.svg', + 'minimum_item_clearance.svg': 'minimum-item-clearance.svg', + 'minimum_connection_width.svg': 'minimum-connection-width.svg', + 'minimum_track_width.svg': 'minimum-track-width.svg', + 'copper_to_hole_clearance.svg': 'copper-to-hole-clearance.svg', + 'hole_to_hole_clearance.svg': 'hole-to-hole-clearance.svg', + 'minimum_annular_width.svg': 'minimum-annular-width.svg', + 'minimum_through_hole.svg': 'minimum-through-hole.svg', + 'hole-to-hole-distance.svg': 'hole-to-hole-distance.svg', + 'minimum_uvia_hole.svg': 'minimum-uvia-hole.svg', + 'minimum_uvia_diameter.svg': 'minimum-uvia-diameter.svg', + 'minimum_via_diameter.svg': 'minimum-via-diameter.svg', + 'silk-to-soldermask-clearance.svg': 'silk-to-soldermask-clearance.svg', + 'minimum-soldermask-silver.svg': 'minimum-soldermask-silver.svg', + 'solderpaste-expansion.svg': 'solderpaste-expansion.svg', + 'maximum_allowed_deviation.svg': 'maximum-allowed-deviation.svg', + 'minimum-angular-ring.svg': 'minimum-angular-ring.svg', + 'matched-lenght-diff-pair.svg': 'matched-length-diff-pair.svg', +} + + +def transform_colors_to_dark(svg_content: str) -> str: + """Transform light theme colors to dark theme colors.""" + result = svg_content + + for light_color, dark_color in LIGHT_TO_DARK_COLORS.items(): + # Case-insensitive replacement for hex colors + pattern = re.compile(re.escape(light_color), re.IGNORECASE) + result = pattern.sub(dark_color, result) + + return result + + +def process_svg_files(): + """Process all constraint SVGs and create themed versions.""" + script_dir = Path(__file__).parent + source_dir = script_dir / 'sources' / 'constraints' + light_dir = script_dir / 'sources' / 'light' / 'constraints' + dark_dir = script_dir / 'sources' / 'dark' / 'constraints' + + # Create output directories if they don't exist + light_dir.mkdir(parents=True, exist_ok=True) + dark_dir.mkdir(parents=True, exist_ok=True) + + processed = 0 + skipped = 0 + + for source_name, output_name in CONSTRAINT_FILES.items(): + source_path = source_dir / source_name + + if not source_path.exists(): + print(f"WARNING: Source file not found: {source_name}") + skipped += 1 + continue + + # Read source SVG + with open(source_path, 'r', encoding='utf-8') as f: + svg_content = f.read() + + # Write light version (copy as-is, since originals use light theme colors) + light_path = light_dir / output_name + with open(light_path, 'w', encoding='utf-8') as f: + f.write(svg_content) + print(f"Created light: {output_name}") + + # Transform and write dark version + dark_content = transform_colors_to_dark(svg_content) + dark_path = dark_dir / output_name + with open(dark_path, 'w', encoding='utf-8') as f: + f.write(dark_content) + print(f"Created dark: {output_name}") + + processed += 1 + + print(f"\nProcessed {processed} files, skipped {skipped}") + return processed, skipped + + +if __name__ == '__main__': + process_svg_files() diff --git a/resources/bitmaps_png/png/constraint_absolute_length_2.png b/resources/bitmaps_png/png/constraint_absolute_length_2.png new file mode 100644 index 0000000000..52add57423 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_absolute_length_2.png differ diff --git a/resources/bitmaps_png/png/constraint_absolute_length_2_dark.png b/resources/bitmaps_png/png/constraint_absolute_length_2_dark.png new file mode 100644 index 0000000000..818d83e100 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_absolute_length_2_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_allowed_orientation.png b/resources/bitmaps_png/png/constraint_allowed_orientation.png index b7fde1c17e..0b95435e05 100644 Binary files a/resources/bitmaps_png/png/constraint_allowed_orientation.png and b/resources/bitmaps_png/png/constraint_allowed_orientation.png differ diff --git a/resources/bitmaps_png/png/constraint_allowed_orientation_dark.png b/resources/bitmaps_png/png/constraint_allowed_orientation_dark.png new file mode 100644 index 0000000000..29502771af Binary files /dev/null and b/resources/bitmaps_png/png/constraint_allowed_orientation_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_basic_clearance.png b/resources/bitmaps_png/png/constraint_basic_clearance.png index ed539673f1..e28abc55eb 100644 Binary files a/resources/bitmaps_png/png/constraint_basic_clearance.png and b/resources/bitmaps_png/png/constraint_basic_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_basic_clearance_dark.png b/resources/bitmaps_png/png/constraint_basic_clearance_dark.png new file mode 100644 index 0000000000..24f4babcca Binary files /dev/null and b/resources/bitmaps_png/png/constraint_basic_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_board_outline_clearance.png b/resources/bitmaps_png/png/constraint_board_outline_clearance.png index b018565f54..ad35f1c18c 100644 Binary files a/resources/bitmaps_png/png/constraint_board_outline_clearance.png and b/resources/bitmaps_png/png/constraint_board_outline_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_board_outline_clearance_dark.png b/resources/bitmaps_png/png/constraint_board_outline_clearance_dark.png new file mode 100644 index 0000000000..f929a6dda3 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_board_outline_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_clearance.png b/resources/bitmaps_png/png/constraint_clearance.png new file mode 100644 index 0000000000..b6978ee8e0 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_clearance_dark.png b/resources/bitmaps_png/png/constraint_clearance_dark.png new file mode 100644 index 0000000000..b0931e38d2 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_copper_to_edge_clearance.png b/resources/bitmaps_png/png/constraint_copper_to_edge_clearance.png index bc6740aa43..7fd3a4ab75 100644 Binary files a/resources/bitmaps_png/png/constraint_copper_to_edge_clearance.png and b/resources/bitmaps_png/png/constraint_copper_to_edge_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_copper_to_edge_clearance_dark.png b/resources/bitmaps_png/png/constraint_copper_to_edge_clearance_dark.png new file mode 100644 index 0000000000..2917c7b9ef Binary files /dev/null and b/resources/bitmaps_png/png/constraint_copper_to_edge_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_copper_to_hole_clearance.png b/resources/bitmaps_png/png/constraint_copper_to_hole_clearance.png index e9eacd8252..2c060cbf91 100644 Binary files a/resources/bitmaps_png/png/constraint_copper_to_hole_clearance.png and b/resources/bitmaps_png/png/constraint_copper_to_hole_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_copper_to_hole_clearance_dark.png b/resources/bitmaps_png/png/constraint_copper_to_hole_clearance_dark.png new file mode 100644 index 0000000000..bf5c9cc1e3 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_copper_to_hole_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_creepage_distance.png b/resources/bitmaps_png/png/constraint_creepage_distance.png index 4644574ffa..42ca8dbaf7 100644 Binary files a/resources/bitmaps_png/png/constraint_creepage_distance.png and b/resources/bitmaps_png/png/constraint_creepage_distance.png differ diff --git a/resources/bitmaps_png/png/constraint_creepage_distance_dark.png b/resources/bitmaps_png/png/constraint_creepage_distance_dark.png new file mode 100644 index 0000000000..e389343d33 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_creepage_distance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_hole_size.png b/resources/bitmaps_png/png/constraint_hole_size.png index d40fd92f8f..7855bc5c71 100644 Binary files a/resources/bitmaps_png/png/constraint_hole_size.png and b/resources/bitmaps_png/png/constraint_hole_size.png differ diff --git a/resources/bitmaps_png/png/constraint_hole_size_dark.png b/resources/bitmaps_png/png/constraint_hole_size_dark.png new file mode 100644 index 0000000000..c7a1f1422a Binary files /dev/null and b/resources/bitmaps_png/png/constraint_hole_size_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_hole_to_hole_clearance.png b/resources/bitmaps_png/png/constraint_hole_to_hole_clearance.png index 0b655a764f..894a456d23 100644 Binary files a/resources/bitmaps_png/png/constraint_hole_to_hole_clearance.png and b/resources/bitmaps_png/png/constraint_hole_to_hole_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_hole_to_hole_clearance_dark.png b/resources/bitmaps_png/png/constraint_hole_to_hole_clearance_dark.png new file mode 100644 index 0000000000..d865e320e0 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_hole_to_hole_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_hole_to_hole_distance.png b/resources/bitmaps_png/png/constraint_hole_to_hole_distance.png index a88936a9cb..c05538b67f 100644 Binary files a/resources/bitmaps_png/png/constraint_hole_to_hole_distance.png and b/resources/bitmaps_png/png/constraint_hole_to_hole_distance.png differ diff --git a/resources/bitmaps_png/png/constraint_hole_to_hole_distance_dark.png b/resources/bitmaps_png/png/constraint_hole_to_hole_distance_dark.png new file mode 100644 index 0000000000..2e33570d25 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_hole_to_hole_distance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_length.png b/resources/bitmaps_png/png/constraint_length.png new file mode 100644 index 0000000000..81f237a6fe Binary files /dev/null and b/resources/bitmaps_png/png/constraint_length.png differ diff --git a/resources/bitmaps_png/png/constraint_length_dark.png b/resources/bitmaps_png/png/constraint_length_dark.png new file mode 100644 index 0000000000..6a83c402a4 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_length_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_matched_length_diff_pair.png b/resources/bitmaps_png/png/constraint_matched_length_diff_pair.png new file mode 100644 index 0000000000..d9cc4a58d9 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_matched_length_diff_pair.png differ diff --git a/resources/bitmaps_png/png/constraint_matched_length_diff_pair_dark.png b/resources/bitmaps_png/png/constraint_matched_length_diff_pair_dark.png new file mode 100644 index 0000000000..d9cc4a58d9 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_matched_length_diff_pair_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_maximum_allowed_deviation.png b/resources/bitmaps_png/png/constraint_maximum_allowed_deviation.png index 8d520de4f0..672c113ea9 100644 Binary files a/resources/bitmaps_png/png/constraint_maximum_allowed_deviation.png and b/resources/bitmaps_png/png/constraint_maximum_allowed_deviation.png differ diff --git a/resources/bitmaps_png/png/constraint_maximum_allowed_deviation_dark.png b/resources/bitmaps_png/png/constraint_maximum_allowed_deviation_dark.png new file mode 100644 index 0000000000..f299315f1b Binary files /dev/null and b/resources/bitmaps_png/png/constraint_maximum_allowed_deviation_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_maximum_via_count.png b/resources/bitmaps_png/png/constraint_maximum_via_count.png index bdd3499f00..db61038ef0 100644 Binary files a/resources/bitmaps_png/png/constraint_maximum_via_count.png and b/resources/bitmaps_png/png/constraint_maximum_via_count.png differ diff --git a/resources/bitmaps_png/png/constraint_maximum_via_count_dark.png b/resources/bitmaps_png/png/constraint_maximum_via_count_dark.png new file mode 100644 index 0000000000..b1923eb31c Binary files /dev/null and b/resources/bitmaps_png/png/constraint_maximum_via_count_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_angular_ring.png b/resources/bitmaps_png/png/constraint_minimum_angular_ring.png index 6441158639..af4686525d 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_angular_ring.png and b/resources/bitmaps_png/png/constraint_minimum_angular_ring.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_angular_ring_dark.png b/resources/bitmaps_png/png/constraint_minimum_angular_ring_dark.png new file mode 100644 index 0000000000..a6483808b6 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_angular_ring_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_annular_width.png b/resources/bitmaps_png/png/constraint_minimum_annular_width.png index 3efebc9bf8..ba2ffd73b3 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_annular_width.png and b/resources/bitmaps_png/png/constraint_minimum_annular_width.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_annular_width_dark.png b/resources/bitmaps_png/png/constraint_minimum_annular_width_dark.png new file mode 100644 index 0000000000..163246c3ee Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_annular_width_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_clearance.png b/resources/bitmaps_png/png/constraint_minimum_clearance.png index 9d04a21403..3c2bdcafe2 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_clearance.png and b/resources/bitmaps_png/png/constraint_minimum_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_clearance_dark.png b/resources/bitmaps_png/png/constraint_minimum_clearance_dark.png new file mode 100644 index 0000000000..c897641d32 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_connection_width.png b/resources/bitmaps_png/png/constraint_minimum_connection_width.png index a112347ab4..48ea8a0c7e 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_connection_width.png and b/resources/bitmaps_png/png/constraint_minimum_connection_width.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_connection_width_dark.png b/resources/bitmaps_png/png/constraint_minimum_connection_width_dark.png new file mode 100644 index 0000000000..17db52bc19 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_connection_width_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_item_clearance.png b/resources/bitmaps_png/png/constraint_minimum_item_clearance.png index 650310414f..510193346e 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_item_clearance.png and b/resources/bitmaps_png/png/constraint_minimum_item_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_item_clearance_dark.png b/resources/bitmaps_png/png/constraint_minimum_item_clearance_dark.png new file mode 100644 index 0000000000..892f882a47 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_item_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_soldermask_silver.png b/resources/bitmaps_png/png/constraint_minimum_soldermask_silver.png index 948fad43ad..3d2ea8a46b 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_soldermask_silver.png and b/resources/bitmaps_png/png/constraint_minimum_soldermask_silver.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_soldermask_silver_dark.png b/resources/bitmaps_png/png/constraint_minimum_soldermask_silver_dark.png new file mode 100644 index 0000000000..9089d360fc Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_soldermask_silver_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness.png b/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness.png index 058cb04a06..9d0b596a11 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness.png and b/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness_dark.png b/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness_dark.png new file mode 100644 index 0000000000..e1e29c7635 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_text_height_and_thickness_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count.png b/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count.png index e0b126ee69..22de0b3b73 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count.png and b/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count_dark.png b/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count_dark.png new file mode 100644 index 0000000000..d625f66378 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_thermal_relief_spoke_count_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_through_hole.png b/resources/bitmaps_png/png/constraint_minimum_through_hole.png index 12f0e4571a..c67a00f1f5 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_through_hole.png and b/resources/bitmaps_png/png/constraint_minimum_through_hole.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_through_hole_dark.png b/resources/bitmaps_png/png/constraint_minimum_through_hole_dark.png new file mode 100644 index 0000000000..02775a5aaa Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_through_hole_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_track_width.png b/resources/bitmaps_png/png/constraint_minimum_track_width.png index 4f87bdca71..d94998b81e 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_track_width.png and b/resources/bitmaps_png/png/constraint_minimum_track_width.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_track_width_dark.png b/resources/bitmaps_png/png/constraint_minimum_track_width_dark.png new file mode 100644 index 0000000000..ddd55aecbd Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_track_width_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_uvia_diameter.png b/resources/bitmaps_png/png/constraint_minimum_uvia_diameter.png index bbcd5ceb8b..95ad82d795 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_uvia_diameter.png and b/resources/bitmaps_png/png/constraint_minimum_uvia_diameter.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_uvia_diameter_dark.png b/resources/bitmaps_png/png/constraint_minimum_uvia_diameter_dark.png new file mode 100644 index 0000000000..fde5d582e3 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_uvia_diameter_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_uvia_hole.png b/resources/bitmaps_png/png/constraint_minimum_uvia_hole.png index e5f8a650d0..246b4a9c42 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_uvia_hole.png and b/resources/bitmaps_png/png/constraint_minimum_uvia_hole.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_uvia_hole_dark.png b/resources/bitmaps_png/png/constraint_minimum_uvia_hole_dark.png new file mode 100644 index 0000000000..74f2be6a5c Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_uvia_hole_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_via_diameter.png b/resources/bitmaps_png/png/constraint_minimum_via_diameter.png index 05c218d0db..decb17303a 100644 Binary files a/resources/bitmaps_png/png/constraint_minimum_via_diameter.png and b/resources/bitmaps_png/png/constraint_minimum_via_diameter.png differ diff --git a/resources/bitmaps_png/png/constraint_minimum_via_diameter_dark.png b/resources/bitmaps_png/png/constraint_minimum_via_diameter_dark.png new file mode 100644 index 0000000000..038a17621a Binary files /dev/null and b/resources/bitmaps_png/png/constraint_minimum_via_diameter_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_permitted_layers.png b/resources/bitmaps_png/png/constraint_permitted_layers.png index fbd8b7d8b7..e39a06acfd 100644 Binary files a/resources/bitmaps_png/png/constraint_permitted_layers.png and b/resources/bitmaps_png/png/constraint_permitted_layers.png differ diff --git a/resources/bitmaps_png/png/constraint_permitted_layers_dark.png b/resources/bitmaps_png/png/constraint_permitted_layers_dark.png new file mode 100644 index 0000000000..ac0aec5253 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_permitted_layers_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_routing_diff_pair.png b/resources/bitmaps_png/png/constraint_routing_diff_pair.png index 45fe0bbae3..c5b688dfda 100644 Binary files a/resources/bitmaps_png/png/constraint_routing_diff_pair.png and b/resources/bitmaps_png/png/constraint_routing_diff_pair.png differ diff --git a/resources/bitmaps_png/png/constraint_routing_diff_pair_dark.png b/resources/bitmaps_png/png/constraint_routing_diff_pair_dark.png new file mode 100644 index 0000000000..2fe62835e8 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_routing_diff_pair_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_routing_width.png b/resources/bitmaps_png/png/constraint_routing_width.png index 0947c01f1c..f4e1ecf6ef 100644 Binary files a/resources/bitmaps_png/png/constraint_routing_width.png and b/resources/bitmaps_png/png/constraint_routing_width.png differ diff --git a/resources/bitmaps_png/png/constraint_routing_width_dark.png b/resources/bitmaps_png/png/constraint_routing_width_dark.png new file mode 100644 index 0000000000..ee21c5f6f9 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_routing_width_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_silk_clearance.png b/resources/bitmaps_png/png/constraint_silk_clearance.png new file mode 100644 index 0000000000..f43b0f4ef9 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_silk_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_silk_clearance_dark.png b/resources/bitmaps_png/png/constraint_silk_clearance_dark.png new file mode 100644 index 0000000000..eeafd46801 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_silk_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance.png b/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance.png index 9b3de4bd55..33ba04451a 100644 Binary files a/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance.png and b/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance.png differ diff --git a/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance_dark.png b/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance_dark.png new file mode 100644 index 0000000000..7cef852c9c Binary files /dev/null and b/resources/bitmaps_png/png/constraint_silk_to_soldermask_clearance_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_soldermask_expansion.png b/resources/bitmaps_png/png/constraint_soldermask_expansion.png index 2b70795b8f..ed43bdf28d 100644 Binary files a/resources/bitmaps_png/png/constraint_soldermask_expansion.png and b/resources/bitmaps_png/png/constraint_soldermask_expansion.png differ diff --git a/resources/bitmaps_png/png/constraint_soldermask_expansion_dark.png b/resources/bitmaps_png/png/constraint_soldermask_expansion_dark.png new file mode 100644 index 0000000000..4b9b3fae35 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_soldermask_expansion_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_solderpaste_expansion.png b/resources/bitmaps_png/png/constraint_solderpaste_expansion.png index d11b6fe6eb..c8bd04f997 100644 Binary files a/resources/bitmaps_png/png/constraint_solderpaste_expansion.png and b/resources/bitmaps_png/png/constraint_solderpaste_expansion.png differ diff --git a/resources/bitmaps_png/png/constraint_solderpaste_expansion_dark.png b/resources/bitmaps_png/png/constraint_solderpaste_expansion_dark.png new file mode 100644 index 0000000000..e0cd865170 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_solderpaste_expansion_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_via_style.png b/resources/bitmaps_png/png/constraint_via_style.png index e49dd2d5d1..5c2302ac86 100644 Binary files a/resources/bitmaps_png/png/constraint_via_style.png and b/resources/bitmaps_png/png/constraint_via_style.png differ diff --git a/resources/bitmaps_png/png/constraint_via_style_dark.png b/resources/bitmaps_png/png/constraint_via_style_dark.png new file mode 100644 index 0000000000..4ad3c4913c Binary files /dev/null and b/resources/bitmaps_png/png/constraint_via_style_dark.png differ diff --git a/resources/bitmaps_png/png/constraint_vias_under_smd.png b/resources/bitmaps_png/png/constraint_vias_under_smd.png new file mode 100644 index 0000000000..3940b618e9 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_vias_under_smd.png differ diff --git a/resources/bitmaps_png/png/constraint_vias_under_smd_dark.png b/resources/bitmaps_png/png/constraint_vias_under_smd_dark.png new file mode 100644 index 0000000000..3940b618e9 Binary files /dev/null and b/resources/bitmaps_png/png/constraint_vias_under_smd_dark.png differ diff --git a/resources/bitmaps_png/sources/constraints/absolute-lenght.svg b/resources/bitmaps_png/sources/constraints/absolute-lenght.svg index ab72c4a3e2..e5604c04cb 100644 --- a/resources/bitmaps_png/sources/constraints/absolute-lenght.svg +++ b/resources/bitmaps_png/sources/constraints/absolute-lenght.svg @@ -2,13 +2,13 @@ - + sodipodi:nodetypes="ccc" /> diff --git a/resources/bitmaps_png/sources/dark/constraints/absolute-length-2.svg b/resources/bitmaps_png/sources/dark/constraints/absolute-length-2.svg new file mode 100644 index 0000000000..0d35f0dbd6 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/absolute-length-2.svg @@ -0,0 +1,138 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/allowed-orientation.svg b/resources/bitmaps_png/sources/dark/constraints/allowed-orientation.svg new file mode 100644 index 0000000000..07d2d57f99 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/allowed-orientation.svg @@ -0,0 +1,239 @@ + + + + + + U2 diff --git a/resources/bitmaps_png/sources/dark/constraints/basic-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/basic-clearance.svg new file mode 100644 index 0000000000..f169576871 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/basic-clearance.svg @@ -0,0 +1,156 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/board-outline-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/board-outline-clearance.svg new file mode 100644 index 0000000000..a277e48020 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/board-outline-clearance.svg @@ -0,0 +1,144 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/clearance.svg b/resources/bitmaps_png/sources/dark/constraints/clearance.svg new file mode 100644 index 0000000000..e9c20b79ad --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/clearance.svg @@ -0,0 +1,159 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/copper-to-hole-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/copper-to-hole-clearance.svg new file mode 100644 index 0000000000..16abc31eef --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/copper-to-hole-clearance.svg @@ -0,0 +1,182 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/copper_to_edge_clearance.svg b/resources/bitmaps_png/sources/dark/constraints/copper_to_edge_clearance.svg new file mode 100644 index 0000000000..1d01533cd9 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/copper_to_edge_clearance.svg @@ -0,0 +1,293 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/creepage-distance.svg b/resources/bitmaps_png/sources/dark/constraints/creepage-distance.svg new file mode 100644 index 0000000000..bc3d8383b5 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/creepage-distance.svg @@ -0,0 +1,295 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/hole-size.svg b/resources/bitmaps_png/sources/dark/constraints/hole-size.svg new file mode 100644 index 0000000000..4c056f0a5c --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/hole-size.svg @@ -0,0 +1,178 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/hole-to-hole-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/hole-to-hole-clearance.svg new file mode 100644 index 0000000000..570c4c4776 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/hole-to-hole-clearance.svg @@ -0,0 +1,210 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/hole-to-hole-distance.svg b/resources/bitmaps_png/sources/dark/constraints/hole-to-hole-distance.svg new file mode 100644 index 0000000000..89ec1f9830 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/hole-to-hole-distance.svg @@ -0,0 +1,119 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/length.svg b/resources/bitmaps_png/sources/dark/constraints/length.svg new file mode 100644 index 0000000000..3773c399f6 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/length.svg @@ -0,0 +1,203 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/matched-length-diff-pair.svg b/resources/bitmaps_png/sources/dark/constraints/matched-length-diff-pair.svg new file mode 100644 index 0000000000..b7687e962b --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/matched-length-diff-pair.svg @@ -0,0 +1,137 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/maximum-allowed-deviation.svg b/resources/bitmaps_png/sources/dark/constraints/maximum-allowed-deviation.svg new file mode 100644 index 0000000000..9b81bec619 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/maximum-allowed-deviation.svg @@ -0,0 +1,175 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/maximum-via-count.svg b/resources/bitmaps_png/sources/dark/constraints/maximum-via-count.svg new file mode 100644 index 0000000000..8a2f8b561d --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/maximum-via-count.svg @@ -0,0 +1,235 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-angular-ring.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-angular-ring.svg new file mode 100644 index 0000000000..afa6c7252f --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-angular-ring.svg @@ -0,0 +1,105 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-annular-width.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-annular-width.svg new file mode 100644 index 0000000000..c569f2c7c4 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-annular-width.svg @@ -0,0 +1,182 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-clearance.svg new file mode 100644 index 0000000000..43727776cc --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-clearance.svg @@ -0,0 +1,195 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-connection-width.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-connection-width.svg new file mode 100644 index 0000000000..b54c30c93a --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-connection-width.svg @@ -0,0 +1,274 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-item-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-item-clearance.svg new file mode 100644 index 0000000000..90db23b657 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-item-clearance.svg @@ -0,0 +1,193 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R1 + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-soldermask-silver.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-soldermask-silver.svg new file mode 100644 index 0000000000..81fa8f5b6f --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-soldermask-silver.svg @@ -0,0 +1,202 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-text-height-and-thickness.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-text-height-and-thickness.svg new file mode 100644 index 0000000000..1e49b70140 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-text-height-and-thickness.svg @@ -0,0 +1,194 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-through-hole.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-through-hole.svg new file mode 100644 index 0000000000..044c088f21 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-through-hole.svg @@ -0,0 +1,182 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-track-width.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-track-width.svg new file mode 100644 index 0000000000..3b40099093 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-track-width.svg @@ -0,0 +1,190 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-uvia-diameter.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-uvia-diameter.svg new file mode 100644 index 0000000000..9d5998a7f6 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-uvia-diameter.svg @@ -0,0 +1,177 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-uvia-hole.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-uvia-hole.svg new file mode 100644 index 0000000000..10a99a6887 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-uvia-hole.svg @@ -0,0 +1,177 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum-via-diameter.svg b/resources/bitmaps_png/sources/dark/constraints/minimum-via-diameter.svg new file mode 100644 index 0000000000..41399e8606 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum-via-diameter.svg @@ -0,0 +1,185 @@ + + + + + + + + + + image/svg+xml + + ps_diff_pair_tune_phase + + + + + + + + + + + + + + + + + + + + + + + + + + + ps_diff_pair_tune_phase + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/minimum_thermal_relief_spoke_count.svg b/resources/bitmaps_png/sources/dark/constraints/minimum_thermal_relief_spoke_count.svg new file mode 100644 index 0000000000..8fbf7b0391 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/minimum_thermal_relief_spoke_count.svg @@ -0,0 +1,457 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/permitted-layers.svg b/resources/bitmaps_png/sources/dark/constraints/permitted-layers.svg new file mode 100644 index 0000000000..2e62f92b04 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/permitted-layers.svg @@ -0,0 +1,409 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/routing-diff-pair.svg b/resources/bitmaps_png/sources/dark/constraints/routing-diff-pair.svg new file mode 100644 index 0000000000..2e0018c9c0 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/routing-diff-pair.svg @@ -0,0 +1,377 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/routing-width.svg b/resources/bitmaps_png/sources/dark/constraints/routing-width.svg new file mode 100644 index 0000000000..116b46f8b3 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/routing-width.svg @@ -0,0 +1,248 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/silk-to-soldermask-clearance.svg b/resources/bitmaps_png/sources/dark/constraints/silk-to-soldermask-clearance.svg new file mode 100644 index 0000000000..99c58932f2 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/silk-to-soldermask-clearance.svg @@ -0,0 +1,190 @@ + + + + + + 123456 diff --git a/resources/bitmaps_png/sources/dark/constraints/silk_clearance.svg b/resources/bitmaps_png/sources/dark/constraints/silk_clearance.svg new file mode 100644 index 0000000000..003b4610e4 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/silk_clearance.svg @@ -0,0 +1,292 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R1 + + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/soldermask-expansion.svg b/resources/bitmaps_png/sources/dark/constraints/soldermask-expansion.svg new file mode 100644 index 0000000000..f9aee9fa78 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/soldermask-expansion.svg @@ -0,0 +1,160 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/solderpaste-expansion.svg b/resources/bitmaps_png/sources/dark/constraints/solderpaste-expansion.svg new file mode 100644 index 0000000000..0858477535 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/solderpaste-expansion.svg @@ -0,0 +1,145 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/via-style.svg b/resources/bitmaps_png/sources/dark/constraints/via-style.svg new file mode 100644 index 0000000000..fe66b54c92 --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/via-style.svg @@ -0,0 +1,123 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/dark/constraints/vias-under-smd.svg b/resources/bitmaps_png/sources/dark/constraints/vias-under-smd.svg new file mode 100644 index 0000000000..d5366f591e --- /dev/null +++ b/resources/bitmaps_png/sources/dark/constraints/vias-under-smd.svg @@ -0,0 +1,102 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/absolute-length-2.svg b/resources/bitmaps_png/sources/light/constraints/absolute-length-2.svg new file mode 100644 index 0000000000..f4ca7b74d9 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/absolute-length-2.svg @@ -0,0 +1,138 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/allowed-orientation.svg b/resources/bitmaps_png/sources/light/constraints/allowed-orientation.svg new file mode 100644 index 0000000000..92cbc1146e --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/allowed-orientation.svg @@ -0,0 +1,239 @@ + + + + + + U2 diff --git a/resources/bitmaps_png/sources/light/constraints/basic-clearance.svg b/resources/bitmaps_png/sources/light/constraints/basic-clearance.svg new file mode 100644 index 0000000000..ae449cfda3 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/basic-clearance.svg @@ -0,0 +1,156 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/board-outline-clearance.svg b/resources/bitmaps_png/sources/light/constraints/board-outline-clearance.svg new file mode 100644 index 0000000000..799b5c95c1 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/board-outline-clearance.svg @@ -0,0 +1,144 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/clearance.svg b/resources/bitmaps_png/sources/light/constraints/clearance.svg new file mode 100644 index 0000000000..99ca9e9473 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/clearance.svg @@ -0,0 +1,157 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/copper-to-hole-clearance.svg b/resources/bitmaps_png/sources/light/constraints/copper-to-hole-clearance.svg new file mode 100644 index 0000000000..879a740fee --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/copper-to-hole-clearance.svg @@ -0,0 +1,182 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/copper_to_edge_clearance.svg b/resources/bitmaps_png/sources/light/constraints/copper_to_edge_clearance.svg new file mode 100644 index 0000000000..fd72d66c4f --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/copper_to_edge_clearance.svg @@ -0,0 +1,293 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/creepage-distance.svg b/resources/bitmaps_png/sources/light/constraints/creepage-distance.svg new file mode 100644 index 0000000000..f284200251 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/creepage-distance.svg @@ -0,0 +1,295 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/hole-size.svg b/resources/bitmaps_png/sources/light/constraints/hole-size.svg new file mode 100644 index 0000000000..25a2fc0525 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/hole-size.svg @@ -0,0 +1,178 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/hole-to-hole-clearance.svg b/resources/bitmaps_png/sources/light/constraints/hole-to-hole-clearance.svg new file mode 100644 index 0000000000..b579912ffc --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/hole-to-hole-clearance.svg @@ -0,0 +1,210 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/hole-to-hole-distance.svg b/resources/bitmaps_png/sources/light/constraints/hole-to-hole-distance.svg new file mode 100644 index 0000000000..3a019a063d --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/hole-to-hole-distance.svg @@ -0,0 +1,119 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/length.svg b/resources/bitmaps_png/sources/light/constraints/length.svg new file mode 100644 index 0000000000..ac29158d95 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/length.svg @@ -0,0 +1,203 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/matched-length-diff-pair.svg b/resources/bitmaps_png/sources/light/constraints/matched-length-diff-pair.svg new file mode 100644 index 0000000000..9825cf70dc --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/matched-length-diff-pair.svg @@ -0,0 +1,137 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/maximum-allowed-deviation.svg b/resources/bitmaps_png/sources/light/constraints/maximum-allowed-deviation.svg new file mode 100644 index 0000000000..76af295345 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/maximum-allowed-deviation.svg @@ -0,0 +1,175 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/maximum-via-count.svg b/resources/bitmaps_png/sources/light/constraints/maximum-via-count.svg new file mode 100644 index 0000000000..ac98e2153c --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/maximum-via-count.svg @@ -0,0 +1,231 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-angular-ring.svg b/resources/bitmaps_png/sources/light/constraints/minimum-angular-ring.svg new file mode 100644 index 0000000000..ec43ad4962 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-angular-ring.svg @@ -0,0 +1,105 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-annular-width.svg b/resources/bitmaps_png/sources/light/constraints/minimum-annular-width.svg new file mode 100644 index 0000000000..75db218dd2 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-annular-width.svg @@ -0,0 +1,182 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-clearance.svg b/resources/bitmaps_png/sources/light/constraints/minimum-clearance.svg new file mode 100644 index 0000000000..3a3fa9505d --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-clearance.svg @@ -0,0 +1,195 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-connection-width.svg b/resources/bitmaps_png/sources/light/constraints/minimum-connection-width.svg new file mode 100644 index 0000000000..73ac015a36 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-connection-width.svg @@ -0,0 +1,274 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-item-clearance.svg b/resources/bitmaps_png/sources/light/constraints/minimum-item-clearance.svg new file mode 100644 index 0000000000..4ee88500ba --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-item-clearance.svg @@ -0,0 +1,193 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R1 + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-soldermask-silver.svg b/resources/bitmaps_png/sources/light/constraints/minimum-soldermask-silver.svg new file mode 100644 index 0000000000..496e4c36c7 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-soldermask-silver.svg @@ -0,0 +1,202 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-text-height-and-thickness.svg b/resources/bitmaps_png/sources/light/constraints/minimum-text-height-and-thickness.svg new file mode 100644 index 0000000000..2173138a69 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-text-height-and-thickness.svg @@ -0,0 +1,194 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-through-hole.svg b/resources/bitmaps_png/sources/light/constraints/minimum-through-hole.svg new file mode 100644 index 0000000000..aebee74aa5 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-through-hole.svg @@ -0,0 +1,182 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-track-width.svg b/resources/bitmaps_png/sources/light/constraints/minimum-track-width.svg new file mode 100644 index 0000000000..b8a8c36684 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-track-width.svg @@ -0,0 +1,190 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-uvia-diameter.svg b/resources/bitmaps_png/sources/light/constraints/minimum-uvia-diameter.svg new file mode 100644 index 0000000000..0b61838483 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-uvia-diameter.svg @@ -0,0 +1,177 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-uvia-hole.svg b/resources/bitmaps_png/sources/light/constraints/minimum-uvia-hole.svg new file mode 100644 index 0000000000..6b245dfd84 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-uvia-hole.svg @@ -0,0 +1,177 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum-via-diameter.svg b/resources/bitmaps_png/sources/light/constraints/minimum-via-diameter.svg new file mode 100644 index 0000000000..96197f8c77 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum-via-diameter.svg @@ -0,0 +1,185 @@ + + + + + + + + + + image/svg+xml + + ps_diff_pair_tune_phase + + + + + + + + + + + + + + + + + + + + + + + + + + + ps_diff_pair_tune_phase + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/minimum_thermal_relief_spoke_count.svg b/resources/bitmaps_png/sources/light/constraints/minimum_thermal_relief_spoke_count.svg new file mode 100644 index 0000000000..225ba45bb6 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/minimum_thermal_relief_spoke_count.svg @@ -0,0 +1,457 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/permitted-layers.svg b/resources/bitmaps_png/sources/light/constraints/permitted-layers.svg new file mode 100644 index 0000000000..a26af52a4a --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/permitted-layers.svg @@ -0,0 +1,409 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/routing-diff-pair.svg b/resources/bitmaps_png/sources/light/constraints/routing-diff-pair.svg new file mode 100644 index 0000000000..7feced25ff --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/routing-diff-pair.svg @@ -0,0 +1,379 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/routing-width.svg b/resources/bitmaps_png/sources/light/constraints/routing-width.svg new file mode 100644 index 0000000000..75d009f7af --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/routing-width.svg @@ -0,0 +1,248 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/silk-to-soldermask-clearance.svg b/resources/bitmaps_png/sources/light/constraints/silk-to-soldermask-clearance.svg new file mode 100644 index 0000000000..702e074214 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/silk-to-soldermask-clearance.svg @@ -0,0 +1,190 @@ + + + + + + 123456 diff --git a/resources/bitmaps_png/sources/light/constraints/silk_clearance.svg b/resources/bitmaps_png/sources/light/constraints/silk_clearance.svg new file mode 100644 index 0000000000..ee95357409 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/silk_clearance.svg @@ -0,0 +1,292 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R1 + + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/soldermask-expansion.svg b/resources/bitmaps_png/sources/light/constraints/soldermask-expansion.svg new file mode 100644 index 0000000000..9dc4324665 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/soldermask-expansion.svg @@ -0,0 +1,160 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/solderpaste-expansion.svg b/resources/bitmaps_png/sources/light/constraints/solderpaste-expansion.svg new file mode 100644 index 0000000000..e5b99fe559 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/solderpaste-expansion.svg @@ -0,0 +1,145 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/via-style.svg b/resources/bitmaps_png/sources/light/constraints/via-style.svg new file mode 100644 index 0000000000..a391d0a258 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/via-style.svg @@ -0,0 +1,123 @@ + + + + + + diff --git a/resources/bitmaps_png/sources/light/constraints/vias-under-smd.svg b/resources/bitmaps_png/sources/light/constraints/vias-under-smd.svg new file mode 100644 index 0000000000..8135f43ef9 --- /dev/null +++ b/resources/bitmaps_png/sources/light/constraints/vias-under-smd.svg @@ -0,0 +1,102 @@ + + + + + +