Eeschema: make bus wire entry properties editable.

CHANGED: Bus to wire entry object properties line color, width, and style
can now be edited.

Fixes: https://gitlab.com/kicad/code/kicad/issues/4591
This commit is contained in:
Wayne Stambaugh 2020-06-19 07:48:00 -04:00
parent b15ee1086f
commit 853cf2c9b9
15 changed files with 188 additions and 92 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2017 Seth Hillbrand <hillbrand@ucdavis.edu> * Copyright (C) 2017 Seth Hillbrand <hillbrand@ucdavis.edu>
* Copyright (C) 2014-2018 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2014-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -53,10 +53,10 @@ const std::map<PLOT_DASH_TYPE, struct lineTypeStruct> lineTypeNames = {
DIALOG_EDIT_LINE_STYLE::DIALOG_EDIT_LINE_STYLE( SCH_EDIT_FRAME* aParent, DIALOG_EDIT_LINE_STYLE::DIALOG_EDIT_LINE_STYLE( SCH_EDIT_FRAME* aParent,
std::deque<SCH_LINE*>& lines ) : std::deque<SCH_ITEM*>& strokeItems ) :
DIALOG_EDIT_LINE_STYLE_BASE( aParent ), DIALOG_EDIT_LINE_STYLE_BASE( aParent ),
m_frame( aParent ), m_frame( aParent ),
m_lines( lines ), m_strokeItems( strokeItems ),
m_width( aParent, m_staticTextWidth, m_lineWidth, m_staticWidthUnits, true ) m_width( aParent, m_staticTextWidth, m_lineWidth, m_staticWidthUnits, true )
{ {
m_sdbSizerApply->SetLabel( _( "Default" ) ); m_sdbSizerApply->SetLabel( _( "Default" ) );
@ -77,41 +77,41 @@ DIALOG_EDIT_LINE_STYLE::DIALOG_EDIT_LINE_STYLE( SCH_EDIT_FRAME* aParent,
bool DIALOG_EDIT_LINE_STYLE::TransferDataToWindow() bool DIALOG_EDIT_LINE_STYLE::TransferDataToWindow()
{ {
auto first_line = m_lines.front(); auto first_stroke_item = m_strokeItems.front();
if( std::all_of( m_lines.begin() + 1, m_lines.end(), if( std::all_of( m_strokeItems.begin() + 1, m_strokeItems.end(),
[&]( const SCH_LINE* r ) [&]( const SCH_ITEM* r )
{ {
return r->GetPenWidth() == first_line->GetPenWidth(); return r->GetPenWidth() == first_stroke_item->GetPenWidth();
} ) ) } ) )
{ {
m_width.SetValue( first_line->GetPenWidth() ); m_width.SetValue( first_stroke_item->GetPenWidth() );
} }
else else
{ {
m_width.SetValue( INDETERMINATE_ACTION ); m_width.SetValue( INDETERMINATE_ACTION );
} }
if( std::all_of( m_lines.begin() + 1, m_lines.end(), if( std::all_of( m_strokeItems.begin() + 1, m_strokeItems.end(),
[&]( const SCH_LINE* r ) [&]( const SCH_ITEM* r )
{ {
return r->GetLineColor() == first_line->GetLineColor(); return r->GetStroke().GetColor() == first_stroke_item->GetStroke().GetColor();
} ) ) } ) )
{ {
setColor( first_line->GetLineColor() ); setColor( first_stroke_item->GetStroke().GetColor() );
} }
else else
{ {
setColor( COLOR4D::UNSPECIFIED ); setColor( COLOR4D::UNSPECIFIED );
} }
if( std::all_of( m_lines.begin() + 1, m_lines.end(), if( std::all_of( m_strokeItems.begin() + 1, m_strokeItems.end(),
[&]( const SCH_LINE* r ) [&]( const SCH_ITEM* r )
{ {
return r->GetLineStyle() == first_line->GetLineStyle(); return r->GetStroke().GetType() == first_stroke_item->GetStroke().GetType();
} ) ) } ) )
{ {
int style = static_cast<int>( first_line->GetLineStyle() ); int style = static_cast<int>( first_stroke_item->GetStroke().GetType() );
wxCHECK_MSG( style < (int)lineTypeNames.size(), false, wxCHECK_MSG( style < (int)lineTypeNames.size(), false,
"Line type for first line is not found in the type lookup map" ); "Line type for first line is not found in the type lookup map" );
m_typeCombo->SetSelection( style ); m_typeCombo->SetSelection( style );
@ -178,7 +178,11 @@ void DIALOG_EDIT_LINE_STYLE::resetDefaults( wxCommandEvent& event )
m_width.SetValue( 0 ); m_width.SetValue( 0 );
setColor( COLOR4D::UNSPECIFIED ); setColor( COLOR4D::UNSPECIFIED );
auto typeIt = lineTypeNames.find( m_lines.front()->GetDefaultStyle() ); SCH_ITEM* item = dynamic_cast<SCH_ITEM*>( m_strokeItems.front() );
wxCHECK( item, /* void */ );
auto typeIt = lineTypeNames.find( item->GetStroke().GetType() );
wxCHECK_RET( typeIt != lineTypeNames.end(), wxCHECK_RET( typeIt != lineTypeNames.end(),
"Default line type not found line dialogs line type lookup map" ); "Default line type not found line dialogs line type lookup map" );
@ -194,7 +198,7 @@ void DIALOG_EDIT_LINE_STYLE::setColor( const COLOR4D& aColor )
if( aColor == COLOR4D::UNSPECIFIED ) if( aColor == COLOR4D::UNSPECIFIED )
{ {
COLOR4D defaultColor = Pgm().GetSettingsManager().GetColorSettings()->GetColor( COLOR4D defaultColor = Pgm().GetSettingsManager().GetColorSettings()->GetColor(
m_lines.front()->GetLayer() ); m_strokeItems.front()->GetLayer() );
updateColorButton( defaultColor ); updateColorButton( defaultColor );
} }
else else
@ -204,17 +208,26 @@ void DIALOG_EDIT_LINE_STYLE::setColor( const COLOR4D& aColor )
bool DIALOG_EDIT_LINE_STYLE::TransferDataFromWindow() bool DIALOG_EDIT_LINE_STYLE::TransferDataFromWindow()
{ {
for( auto& line : m_lines ) PICKED_ITEMS_LIST pickedItems;
{ STROKE_PARAMS stroke;
m_frame->SaveCopyInUndoList( line, UR_CHANGED );
for( auto& strokeItem : m_strokeItems )
pickedItems.PushItem( ITEM_PICKER( strokeItem, UR_CHANGED ) );
m_frame->SaveCopyInUndoList( pickedItems, UR_CHANGED );
for( auto& strokeItem : m_strokeItems )
{
if( !m_width.IsIndeterminate() ) if( !m_width.IsIndeterminate() )
{ {
line->SetLineWidth( m_width.GetValue() ); stroke = strokeItem->GetStroke();
stroke.SetWidth( m_width.GetValue() );
strokeItem->SetStroke( stroke );
} }
if( m_typeCombo->GetSelection() != wxNOT_FOUND ) if( m_typeCombo->GetSelection() != wxNOT_FOUND )
{ {
stroke = strokeItem->GetStroke();
int selection = m_typeCombo->GetSelection(); int selection = m_typeCombo->GetSelection();
wxCHECK_MSG( selection < (int)lineTypeNames.size(), false, wxCHECK_MSG( selection < (int)lineTypeNames.size(), false,
"Selected line type index exceeds size of line type lookup map" ); "Selected line type index exceeds size of line type lookup map" );
@ -222,16 +235,19 @@ bool DIALOG_EDIT_LINE_STYLE::TransferDataFromWindow()
auto it = lineTypeNames.begin(); auto it = lineTypeNames.begin();
std::advance( it, selection ); std::advance( it, selection );
line->SetLineStyle( it->first ); stroke.SetType( it->first );
strokeItem->SetStroke( stroke );
} }
line->SetLineColor( m_selectedColor ); stroke = strokeItem->GetStroke();
stroke.SetColor( m_selectedColor );
strokeItem->SetStroke( stroke );
m_frame->RefreshItem( line ); m_frame->RefreshItem( strokeItem );
} }
m_frame->GetCanvas()->Refresh(); m_frame->GetCanvas()->Refresh();
m_frame->OnModify(); m_frame->OnModify();
return true; return true;
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2017 Seth Hillbrand <hillbrand@ucdavis.edu> * Copyright (C) 2017 Seth Hillbrand <hillbrand@ucdavis.edu>
* Copyright (C) 2014-2018 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2014-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -36,14 +36,14 @@ class SCH_LINE;
class DIALOG_EDIT_LINE_STYLE : public DIALOG_EDIT_LINE_STYLE_BASE class DIALOG_EDIT_LINE_STYLE : public DIALOG_EDIT_LINE_STYLE_BASE
{ {
public: public:
DIALOG_EDIT_LINE_STYLE( SCH_EDIT_FRAME* aParent, std::deque<SCH_LINE*>& lines ); DIALOG_EDIT_LINE_STYLE( SCH_EDIT_FRAME* aParent, std::deque<SCH_ITEM*>& strokeItems );
bool TransferDataToWindow() override; bool TransferDataToWindow() override;
bool TransferDataFromWindow() override; bool TransferDataFromWindow() override;
private: private:
SCH_EDIT_FRAME* m_frame; SCH_EDIT_FRAME* m_frame;
std::deque<SCH_LINE*> m_lines; std::deque<SCH_ITEM*> m_strokeItems;
UNIT_BINDER m_width; UNIT_BINDER m_width;
COLOR4D m_selectedColor; COLOR4D m_selectedColor;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -53,6 +53,7 @@ const KICAD_T EE_COLLECTOR::EditableItems[] = {
SCH_SHEET_T, SCH_SHEET_T,
SCH_BITMAP_T, SCH_BITMAP_T,
SCH_LINE_T, SCH_LINE_T,
SCH_BUS_WIRE_ENTRY_T,
EOT EOT
}; };

View File

@ -29,7 +29,6 @@
#include <trigo.h> #include <trigo.h>
#include <common.h> #include <common.h>
#include <richio.h> #include <richio.h>
#include <plotter.h>
#include <bitmaps.h> #include <bitmaps.h>
#include <eeschema_config.h> #include <eeschema_config.h>
#include <general.h> #include <general.h>
@ -104,6 +103,7 @@ void SCH_BUS_ENTRY_BASE::SwapData( SCH_ITEM* aItem )
std::swap( m_pos, item->m_pos ); std::swap( m_pos, item->m_pos );
std::swap( m_size, item->m_size ); std::swap( m_size, item->m_size );
std::swap( m_stroke, item->m_stroke );
} }
@ -131,7 +131,7 @@ const EDA_RECT SCH_BUS_ENTRY_BASE::GetBoundingBox() const
int SCH_BUS_WIRE_ENTRY::GetPenWidth() const int SCH_BUS_WIRE_ENTRY::GetPenWidth() const
{ {
return 1; return ( m_stroke.GetWidth() == 0 ) ? 1 : m_stroke.GetWidth();
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2004-2020 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -30,6 +30,8 @@
#ifndef _SCH_BUS_ENTRY_H_ #ifndef _SCH_BUS_ENTRY_H_
#define _SCH_BUS_ENTRY_H_ #define _SCH_BUS_ENTRY_H_
#include <gal/color4d.h>
#include <plotter.h>
#include <sch_item.h> #include <sch_item.h>
#define TARGET_BUSENTRY_RADIUS Mils2iu( 12 ) // Circle diameter drawn at the ends #define TARGET_BUSENTRY_RADIUS Mils2iu( 12 ) // Circle diameter drawn at the ends
@ -43,7 +45,9 @@ class SCH_BUS_ENTRY_BASE : public SCH_ITEM
protected: protected:
wxPoint m_pos; wxPoint m_pos;
wxSize m_size; wxSize m_size;
bool m_isDanglingStart, m_isDanglingEnd; bool m_isDanglingStart;
bool m_isDanglingEnd;
STROKE_PARAMS m_stroke;
public: public:
SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos = wxPoint( 0, 0 ), char shape = '\\' ); SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos = wxPoint( 0, 0 ), char shape = '\\' );
@ -78,6 +82,18 @@ public:
void SetSize( const wxSize& aSize ) { m_size = aSize; } void SetSize( const wxSize& aSize ) { m_size = aSize; }
void SetPenWidth( int aWidth ) { m_stroke.SetWidth( aWidth ); }
virtual bool HasLineStroke() const override { return true; }
virtual STROKE_PARAMS GetStroke() const override { return m_stroke; }
virtual void SetStroke( const STROKE_PARAMS& aStroke ) override { m_stroke = aStroke; }
PLOT_DASH_TYPE GetStrokeStyle() const { return m_stroke.GetType(); }
void SetStrokeStyle( PLOT_DASH_TYPE aStyle ) { m_stroke.SetType( aStyle ); }
COLOR4D GetStrokeColor() const { return m_stroke.GetColor(); }
void SetStrokeColor( const COLOR4D& aColor ) { m_stroke.SetColor( aColor ); }
void SwapData( SCH_ITEM* aItem ) override; void SwapData( SCH_ITEM* aItem ) override;
void ViewGetLayers( int aLayers[], int& aCount ) const override; void ViewGetLayers( int aLayers[], int& aCount ) const override;

View File

@ -47,4 +47,6 @@
//#define SEXPR_SCHEMATIC_FILE_VERSION 20200602 // Add support for exclude from board. //#define SEXPR_SCHEMATIC_FILE_VERSION 20200602 // Add support for exclude from board.
#define SEXPR_SCHEMATIC_FILE_VERSION 20200608 //#define SEXPR_SCHEMATIC_FILE_VERSION 20200608 // Add support for bus and junction properties.
#define SEXPR_SCHEMATIC_FILE_VERSION 20200618

View File

@ -460,6 +460,10 @@ public:
*/ */
virtual bool HasLineStroke() const { return false; } virtual bool HasLineStroke() const { return false; }
virtual STROKE_PARAMS GetStroke() const { wxCHECK( false, STROKE_PARAMS() ); }
virtual void SetStroke( const STROKE_PARAMS& aStroke ) { wxCHECK( false, /* void */ ); }
/** /**
* Plot the schematic item to \a aPlotter. * Plot the schematic item to \a aPlotter.
* *

View File

@ -121,8 +121,8 @@ public:
void SetLineWidth( const int aSize ); void SetLineWidth( const int aSize );
virtual bool HasLineStroke() const override { return true; } virtual bool HasLineStroke() const override { return true; }
STROKE_PARAMS GetStroke() const { return m_stroke; } virtual STROKE_PARAMS GetStroke() const override { return m_stroke; }
void SetStroke( const STROKE_PARAMS& aStroke ) { m_stroke = aStroke; } virtual void SetStroke( const STROKE_PARAMS& aStroke ) override { m_stroke = aStroke; }
/** /**
* Test if the #SCH_LINE object uses the default stroke settings. * Test if the #SCH_LINE object uses the default stroke settings.

View File

@ -1167,9 +1167,10 @@ void SCH_PAINTER::draw( LIB_BEZIER *aCurve, int aLayer )
// Draw the target (an open square) for a wire or label which has no connection or is // Draw the target (an open square) for a wire or label which has no connection or is
// being moved. // being moved.
void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, bool aDrawingShadows ) void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, int aWidth, bool aDrawingShadows )
{ {
wxPoint radius( Mils2iu( DANGLING_SYMBOL_SIZE ), Mils2iu( DANGLING_SYMBOL_SIZE ) ); wxPoint radius( aWidth + Mils2iu( DANGLING_SYMBOL_SIZE / 2 ),
aWidth + Mils2iu( DANGLING_SYMBOL_SIZE /2 ) );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
@ -1262,10 +1263,12 @@ void SCH_PAINTER::draw( SCH_LINE *aLine, int aLayer )
} }
if( aLine->IsStartDangling() ) if( aLine->IsStartDangling() )
drawDanglingSymbol( aLine->GetStartPoint(), drawingShadows ); drawDanglingSymbol( aLine->GetStartPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
if( aLine->IsEndDangling() ) if( aLine->IsEndDangling() )
drawDanglingSymbol( aLine->GetEndPoint(), drawingShadows ); drawDanglingSymbol( aLine->GetEndPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
} }
@ -1350,7 +1353,8 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer )
} }
if( aText->IsDangling() ) if( aText->IsDangling() )
drawDanglingSymbol( aText->GetTextPos(), drawingShadows ); drawDanglingSymbol( aText->GetTextPos(), Mils2iu( DANGLING_SYMBOL_SIZE / 2 ),
drawingShadows );
} }
@ -1703,34 +1707,41 @@ void SCH_PAINTER::draw( SCH_NO_CONNECT *aNC, int aLayer )
void SCH_PAINTER::draw( SCH_BUS_ENTRY_BASE *aEntry, int aLayer ) void SCH_PAINTER::draw( SCH_BUS_ENTRY_BASE *aEntry, int aLayer )
{ {
SCH_LINE line;
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS; bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
if( drawingShadows && !aEntry->IsSelected() ) line.SetLayer( aEntry->Type() == SCH_BUS_WIRE_ENTRY_T ? LAYER_WIRE : LAYER_BUS );
return;
COLOR4D color = getRenderColor( aEntry, LAYER_WIRE, drawingShadows ); if( aEntry->IsSelected() )
line.SetSelected();
if( aEntry->Type() == SCH_BUS_BUS_ENTRY_T ) line.SetStartPoint( aEntry->GetPosition() );
color = getRenderColor( aEntry, LAYER_BUS, drawingShadows ); line.SetEndPoint( aEntry->m_End() );
line.SetStroke( aEntry->GetStroke() );
if( aEntry->GetStrokeColor() == COLOR4D::UNSPECIFIED )
{
COLOR4D color = getRenderColor( aEntry, LAYER_WIRE, drawingShadows );
if( aEntry->Type() == SCH_BUS_BUS_ENTRY_T )
color = getRenderColor( aEntry, LAYER_BUS, drawingShadows );
line.SetLineColor( color );
}
draw( &line, aLayer );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getLineWidth( aEntry, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
VECTOR2D pos = aEntry->GetPosition(); m_gal->SetLineWidth( drawingShadows ? getShadowWidth() : 1.0 );
VECTOR2D endPos = aEntry->m_End();
m_gal->DrawLine( pos, endPos );
// Draw dangling symbols:
m_gal->SetLineWidth ( getLineWidth( aEntry, drawingShadows ) );
if( aEntry->IsDanglingStart() ) if( aEntry->IsDanglingStart() )
m_gal->DrawCircle( pos, TARGET_BUSENTRY_RADIUS ); m_gal->DrawCircle( aEntry->GetPosition(),
aEntry->GetPenWidth() + ( TARGET_BUSENTRY_RADIUS / 2 ) );
if( aEntry->IsDanglingEnd() ) if( aEntry->IsDanglingEnd() )
m_gal->DrawCircle( endPos, TARGET_BUSENTRY_RADIUS ); m_gal->DrawCircle( aEntry->m_End(),
aEntry->GetPenWidth() + ( TARGET_BUSENTRY_RADIUS / 2 ) );
} }

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019-2020 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -174,7 +174,7 @@ private:
void draw( SCH_BUS_ENTRY_BASE* aEntry, int aLayer ); void draw( SCH_BUS_ENTRY_BASE* aEntry, int aLayer );
void drawPinDanglingSymbol( const VECTOR2I& aPos, bool aDrawingShadows ); void drawPinDanglingSymbol( const VECTOR2I& aPos, bool aDrawingShadows );
void drawDanglingSymbol( const wxPoint& aPos, bool aDrawingShadows ); void drawDanglingSymbol( const wxPoint& aPos, int aWidth, bool aDrawingShadows );
int internalPinDecoSize( const LIB_PIN &aPin ); int internalPinDecoSize( const LIB_PIN &aPin );
int externalPinDecoSize( const LIB_PIN &aPin ); int externalPinDecoSize( const LIB_PIN &aPin );

View File

@ -2440,6 +2440,7 @@ SCH_BUS_WIRE_ENTRY* SCH_SEXPR_PARSER::parseBusEntry()
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bus entry." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a bus entry." ) );
T token; T token;
STROKE_PARAMS stroke;
std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry( new SCH_BUS_WIRE_ENTRY() ); std::unique_ptr<SCH_BUS_WIRE_ENTRY> busEntry( new SCH_BUS_WIRE_ENTRY() );
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
@ -2471,8 +2472,13 @@ SCH_BUS_WIRE_ENTRY* SCH_SEXPR_PARSER::parseBusEntry()
break; break;
} }
case T_stroke:
parseStroke( stroke );
busEntry->SetStroke( stroke );
break;
default: default:
Expecting( "at or size" ); Expecting( "at, size, or stroke" );
} }
} }

View File

@ -297,18 +297,18 @@ static const char* getTextTypeToken( KICAD_T aType )
* @param aStyle The stroke line style. * @param aStyle The stroke line style.
* @param aColor The stroke line color. * @param aColor The stroke line color.
*/ */
static void formatStroke( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aWidth, static void formatStroke( OUTPUTFORMATTER* aFormatter, int aNestLevel,
PLOT_DASH_TYPE aStyle, const COLOR4D& aColor ) const STROKE_PARAMS& aStroke )
{ {
wxASSERT( aFormatter != nullptr ); wxASSERT( aFormatter != nullptr );
aFormatter->Print( aNestLevel, "(stroke (width %s) (type %s) (color %d %d %d %s))", aFormatter->Print( aNestLevel, "(stroke (width %s) (type %s) (color %d %d %d %s))",
FormatInternalUnits( aWidth ).c_str(), FormatInternalUnits( aStroke.GetWidth() ).c_str(),
TO_UTF8( getLineStyleToken( aStyle ) ), TO_UTF8( getLineStyleToken( aStroke.GetType() ) ),
KiROUND( aColor.r * 255.0 ), KiROUND( aStroke.GetColor().r * 255.0 ),
KiROUND( aColor.g * 255.0 ), KiROUND( aStroke.GetColor().g * 255.0 ),
KiROUND( aColor.b * 255.0 ), KiROUND( aStroke.GetColor().b * 255.0 ),
Double2Str( aColor.a ).c_str() ); Double2Str( aStroke.GetColor().a ).c_str() );
} }
@ -1062,8 +1062,11 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel )
FormatInternalUnits( aSheet->GetSize().GetWidth() ).c_str(), FormatInternalUnits( aSheet->GetSize().GetWidth() ).c_str(),
FormatInternalUnits( aSheet->GetSize().GetHeight() ).c_str() ); FormatInternalUnits( aSheet->GetSize().GetHeight() ).c_str() );
formatStroke( m_out, aNestLevel + 1, aSheet->GetBorderWidth(), PLOT_DASH_TYPE::SOLID, STROKE_PARAMS stroke( aSheet->GetBorderWidth(), PLOT_DASH_TYPE::SOLID,
aSheet->GetBorderColor() ); aSheet->GetBorderColor() );
stroke.SetWidth( aSheet->GetBorderWidth() );
formatStroke( m_out, aNestLevel + 1, stroke );
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
@ -1133,11 +1136,15 @@ void SCH_SEXPR_PLUGIN::saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry, int aNestLev
} }
else else
{ {
m_out->Print( aNestLevel, "(bus_entry (at %s %s) (size %s %s))\n", m_out->Print( aNestLevel, "(bus_entry (at %s %s) (size %s %s) ",
FormatInternalUnits( aBusEntry->GetPosition().x ).c_str(), FormatInternalUnits( aBusEntry->GetPosition().x ).c_str(),
FormatInternalUnits( aBusEntry->GetPosition().y ).c_str(), FormatInternalUnits( aBusEntry->GetPosition().y ).c_str(),
FormatInternalUnits( aBusEntry->GetSize().GetWidth() ).c_str(), FormatInternalUnits( aBusEntry->GetSize().GetWidth() ).c_str(),
FormatInternalUnits( aBusEntry->GetSize().GetHeight() ).c_str() ); FormatInternalUnits( aBusEntry->GetSize().GetHeight() ).c_str() );
formatStroke( m_out, 0, aBusEntry->GetStroke() );
m_out->Print( 0, ")\n" );
} }
} }
@ -1163,8 +1170,7 @@ void SCH_SEXPR_PLUGIN::saveLine( SCH_LINE* aLine, int aNestLevel )
FormatInternalUnits( aLine->GetEndPoint().x ).c_str(), FormatInternalUnits( aLine->GetEndPoint().x ).c_str(),
FormatInternalUnits( aLine->GetEndPoint().y ).c_str() ); FormatInternalUnits( aLine->GetEndPoint().y ).c_str() );
formatStroke( m_out, aNestLevel + 1, aLine->GetLineSize(), aLine->GetLineStyle(), formatStroke( m_out, aNestLevel + 1, aLine->GetStroke() );
aLine->GetLineColor() );
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
m_out->Print( aNestLevel, ")\n" ); m_out->Print( aNestLevel, ")\n" );
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2019-2020 KiCad Developers, see CHANGELOG.TXT for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -24,6 +24,8 @@
#include <tools/ee_selection.h> #include <tools/ee_selection.h>
#include <sch_item.h>
EE_SELECTION::EE_SELECTION( SCH_SCREEN* aScreen ) : EE_SELECTION::EE_SELECTION( SCH_SCREEN* aScreen ) :
SELECTION() SELECTION()
@ -54,3 +56,17 @@ EDA_ITEM* EE_SELECTION::GetTopLeftItem( bool onlyModules ) const
return topLeftItem; return topLeftItem;
} }
bool EE_SELECTION::AllItemsHaveLineStroke() const
{
for( const EDA_ITEM* item : m_items )
{
const SCH_ITEM* schItem = dynamic_cast<const SCH_ITEM*>( item );
if( !schItem || !schItem->HasLineStroke() )
return false;
}
return true;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2019-2020 KiCad Developers, see CHANGELOG.TXT for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -45,6 +45,13 @@ public:
void SetScreen( SCH_SCREEN* aScreen ) { m_screen = aScreen; } void SetScreen( SCH_SCREEN* aScreen ) { m_screen = aScreen; }
SCH_SCREEN* GetScreen() { return m_screen; } SCH_SCREEN* GetScreen() { return m_screen; }
/**
* Checks if all items in the selection support line strokes
*
* @return True if all items support line strokes
*/
bool AllItemsHaveLineStroke() const;
}; };
#endif // EE_SELECTION_H #endif // EE_SELECTION_H

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2019 CERN * Copyright (C) 2019 CERN
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -193,12 +193,20 @@ bool SCH_EDIT_TOOL::Init()
if( aSel.GetSize() == 0 ) if( aSel.GetSize() == 0 )
return true; // Show worksheet properties return true; // Show worksheet properties
if( aSel.GetSize() != 1 SCH_ITEM* firstItem = dynamic_cast<SCH_ITEM*>( aSel.Front() );
&& !( aSel.GetSize() >= 1 && aSel.Front()->Type() == SCH_LINE_T
&& aSel.AreAllItemsIdentical() ) )
return false;
EDA_ITEM* firstItem = static_cast<EDA_ITEM*>( aSel.Front() ); wxCHECK( firstItem, false );
const EE_SELECTION* eeSelection = dynamic_cast<const EE_SELECTION*>( &aSel );
wxCHECK( eeSelection, false );
if( aSel.GetSize() != 1
&& !( aSel.GetSize() >= 1
&& ( firstItem->Type() == SCH_LINE_T
|| firstItem->Type() == SCH_BUS_WIRE_ENTRY_T )
&& eeSelection->AllItemsHaveLineStroke() ) )
return false;
switch( firstItem->Type() ) switch( firstItem->Type() )
{ {
@ -214,11 +222,12 @@ bool SCH_EDIT_TOOL::Init()
return aSel.GetSize() == 1; return aSel.GetSize() == 1;
case SCH_LINE_T: case SCH_LINE_T:
case SCH_BUS_WIRE_ENTRY_T:
for( EDA_ITEM* item : aSel.GetItems() ) for( EDA_ITEM* item : aSel.GetItems() )
{ {
SCH_LINE* line = dynamic_cast<SCH_LINE*>( item ); SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item );
if( !line ) if( !schItem || !schItem->HasLineStroke() )
return false; return false;
} }
@ -1263,7 +1272,8 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
switch( item->Type() ) switch( item->Type() )
{ {
case SCH_LINE_T: case SCH_LINE_T:
if( !selection.AreAllItemsIdentical() ) case SCH_BUS_WIRE_ENTRY_T:
if( !selection.AllItemsHaveLineStroke() )
return 0; return 0;
break; break;
@ -1386,20 +1396,21 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
break; break;
case SCH_LINE_T: case SCH_LINE_T:
case SCH_BUS_WIRE_ENTRY_T:
{ {
std::deque<SCH_LINE*> lines; std::deque<SCH_ITEM*> strokeItems;
for( auto selItem : selection.Items() ) for( auto selItem : selection.Items() )
{ {
SCH_LINE* line = dynamic_cast<SCH_LINE*>( selItem ); SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( selItem );
if( line ) if( schItem && schItem->HasLineStroke() )
lines.push_back( line ); strokeItems.push_back( schItem );
else else
return 0; return 0;
} }
DIALOG_EDIT_LINE_STYLE dlg( m_frame, lines ); DIALOG_EDIT_LINE_STYLE dlg( m_frame, strokeItems );
if( dlg.ShowModal() == wxID_OK ) if( dlg.ShowModal() == wxID_OK )
{ {