Allow click-selection and greedy-drag selection of visible pin text.
Stingy drag still works only on the pin itself. Fixes https://gitlab.com/kicad/code/kicad/issues/11723
This commit is contained in:
parent
404015b0a5
commit
3def3d659e
|
@ -378,7 +378,7 @@ void DIALOG_PIN_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
|
|||
SYMBOL_EDIT_FRAME* symbolEditor = (SYMBOL_EDIT_FRAME*) GetParent();
|
||||
|
||||
// Calculate a suitable scale to fit the available draw area
|
||||
EDA_RECT bBox = m_dummyPin->GetBoundingBox( true );
|
||||
EDA_RECT bBox = m_dummyPin->GetBoundingBox( true, true, false );
|
||||
double xscale = (double) dc_size.x / bBox.GetWidth();
|
||||
double yscale = (double) dc_size.y / bBox.GetHeight();
|
||||
double scale = std::min( xscale, yscale );
|
||||
|
|
|
@ -117,26 +117,31 @@ const KICAD_T EE_COLLECTOR::FieldOwners[] = {
|
|||
|
||||
SEARCH_RESULT EE_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
|
||||
{
|
||||
if( aItem->Type() == LIB_PIN_T )
|
||||
{
|
||||
// Special selection rules apply to pins of different units when edited in
|
||||
// synchronized pins mode. Leave it to EE_SELECTION_TOOL::Selectable() to
|
||||
// decide what to do with them.
|
||||
}
|
||||
else if( m_Unit || m_Convert )
|
||||
if( m_Unit || m_Convert )
|
||||
{
|
||||
LIB_ITEM* lib_item = dynamic_cast<LIB_ITEM*>( aItem );
|
||||
|
||||
if( m_Unit && lib_item && lib_item->GetUnit() && lib_item->GetUnit() != m_Unit )
|
||||
return SEARCH_RESULT::CONTINUE;
|
||||
// Special selection rules apply to pins of different units when edited in synchronized
|
||||
// pins mode. Leave it to EE_SELECTION_TOOL::Selectable() to decide what to do with them.
|
||||
|
||||
if( m_Convert && lib_item && lib_item->GetConvert() && lib_item->GetConvert() != m_Convert )
|
||||
return SEARCH_RESULT::CONTINUE;
|
||||
if( lib_item && lib_item->Type() != LIB_PIN_T )
|
||||
{
|
||||
if( m_Unit && lib_item->GetUnit() && lib_item->GetUnit() != m_Unit )
|
||||
return SEARCH_RESULT::CONTINUE;
|
||||
|
||||
if( m_Convert && lib_item->GetConvert() && lib_item->GetConvert() != m_Convert )
|
||||
return SEARCH_RESULT::CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_ShowPinElectricalTypes )
|
||||
aItem->SetFlags( SHOW_ELEC_TYPE );
|
||||
|
||||
if( aItem->HitTest( m_refPos, m_Threshold ) )
|
||||
Append( aItem );
|
||||
|
||||
aItem->ClearFlags( SHOW_ELEC_TYPE );
|
||||
|
||||
return SEARCH_RESULT::CONTINUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,8 @@ public:
|
|||
public:
|
||||
int m_Unit; // Fixed symbol unit filter (for symbol editor)
|
||||
int m_Convert; // Fixed DeMorgan filter (for symbol editor)
|
||||
|
||||
bool m_ShowPinElectricalTypes;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ LIB_PIN::LIB_PIN( LIB_SYMBOL* aParent, const wxString& aName, const wxString& aN
|
|||
|
||||
bool LIB_PIN::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
{
|
||||
EDA_RECT rect = GetBoundingBox();
|
||||
EDA_RECT rect = GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
|
||||
|
||||
return rect.Inflate( aAccuracy ).Contains( aPosition );
|
||||
}
|
||||
|
@ -157,9 +157,9 @@ bool LIB_PIN::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) c
|
|||
sel.Inflate( aAccuracy );
|
||||
|
||||
if( aContained )
|
||||
return sel.Contains( GetBoundingBox( false, true ) );
|
||||
return sel.Contains( GetBoundingBox( false, false, false ) );
|
||||
|
||||
return sel.Intersects( GetBoundingBox( false, true ) );
|
||||
return sel.Intersects( GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1104,6 +1104,14 @@ void LIB_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
|
|||
}
|
||||
|
||||
|
||||
const BOX2I LIB_PIN::ViewBBox() const
|
||||
{
|
||||
EDA_RECT bbox = GetBoundingBox( false, true, true );
|
||||
|
||||
return BOX2I( bbox.GetOrigin(), bbox.GetSize() );
|
||||
}
|
||||
|
||||
|
||||
void LIB_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
aCount = 3;
|
||||
|
@ -1115,7 +1123,8 @@ void LIB_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
|
|||
}
|
||||
|
||||
|
||||
const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly ) const
|
||||
const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
|
||||
bool aIncludeElectricalType ) const
|
||||
{
|
||||
KIFONT::FONT* font = KIFONT::FONT::GetFont( Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>()->m_Appearance.default_font );
|
||||
|
||||
|
@ -1127,35 +1136,33 @@ const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly )
|
|||
int nameTextHeight = 0;
|
||||
int numberTextLength = 0;
|
||||
int numberTextHeight = 0;
|
||||
int typeTextLength = 0;
|
||||
wxString name = GetShownName();
|
||||
wxString number = GetShownNumber();
|
||||
bool showName = !name.IsEmpty();
|
||||
bool showNum = !number.IsEmpty();
|
||||
bool includeName = aIncludeNameAndNumber && !name.IsEmpty();
|
||||
bool includeNumber = aIncludeNameAndNumber && !number.IsEmpty();
|
||||
bool includeType = aIncludeElectricalType;
|
||||
int minsizeV = TARGET_PIN_RADIUS;
|
||||
int penWidth = GetPenWidth();
|
||||
|
||||
if( !aIncludeInvisibles && !IsVisible() )
|
||||
showName = false;
|
||||
if( !aIncludeInvisiblePins && !IsVisible() )
|
||||
{
|
||||
includeName = false;
|
||||
includeType = false;
|
||||
}
|
||||
|
||||
if( GetParent() )
|
||||
{
|
||||
if( GetParent()->ShowPinNames() )
|
||||
nameTextOffset = GetParent()->GetPinNameOffset();
|
||||
else
|
||||
showName = false;
|
||||
includeName = false;
|
||||
|
||||
if( !GetParent()->ShowPinNumbers() )
|
||||
showNum = false;
|
||||
includeNumber = false;
|
||||
}
|
||||
|
||||
if( aPinOnly )
|
||||
{
|
||||
showName = false;
|
||||
showNum = false;
|
||||
}
|
||||
|
||||
// First, calculate boundary box corners position
|
||||
if( showNum )
|
||||
if( includeNumber )
|
||||
{
|
||||
VECTOR2D fontSize( m_numTextSize, m_numTextSize );
|
||||
VECTOR2I numSize = font->StringBoundaryLimits( number, fontSize, penWidth, false, false );
|
||||
|
@ -1164,16 +1171,7 @@ const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly )
|
|||
numberTextHeight = numSize.y;
|
||||
}
|
||||
|
||||
if( m_shape == GRAPHIC_PINSHAPE::INVERTED || m_shape == GRAPHIC_PINSHAPE::INVERTED_CLOCK )
|
||||
minsizeV = std::max( TARGET_PIN_RADIUS, externalPinDecoSize( nullptr, *this ) );
|
||||
|
||||
// calculate top left corner position
|
||||
// for the default pin orientation (PIN_RIGHT)
|
||||
begin.y = std::max( minsizeV, numberTextHeight + Mils2iu( PIN_TEXT_MARGIN ) );
|
||||
begin.x = std::min( 0, m_length - ( numberTextLength / 2) );
|
||||
|
||||
// calculate bottom right corner position and adjust top left corner position
|
||||
if( showName )
|
||||
if( includeName )
|
||||
{
|
||||
VECTOR2D fontSize( m_nameTextSize, m_nameTextSize );
|
||||
VECTOR2I nameSize = font->StringBoundaryLimits( name, fontSize, penWidth, false, false );
|
||||
|
@ -1182,6 +1180,27 @@ const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly )
|
|||
nameTextHeight = nameSize.y + Mils2iu( PIN_TEXT_MARGIN );
|
||||
}
|
||||
|
||||
if( includeType )
|
||||
{
|
||||
double fontSize = std::max( m_nameTextSize * 3 / 4, Millimeter2iu( 0.7 ) );
|
||||
VECTOR2I typeTextSize = font->StringBoundaryLimits( GetElectricalTypeName(),
|
||||
VECTOR2D( fontSize, fontSize ),
|
||||
fontSize / 8.0, false, false );
|
||||
|
||||
typeTextLength = typeTextSize.x + Mils2iu( PIN_TEXT_MARGIN ) + TARGET_PIN_RADIUS;
|
||||
minsizeV = std::max( minsizeV, typeTextSize.y / 2 );
|
||||
}
|
||||
|
||||
// First, calculate boundary box corners position
|
||||
if( m_shape == GRAPHIC_PINSHAPE::INVERTED || m_shape == GRAPHIC_PINSHAPE::INVERTED_CLOCK )
|
||||
minsizeV = std::max( TARGET_PIN_RADIUS, externalPinDecoSize( nullptr, *this ) );
|
||||
|
||||
// calculate top left corner position
|
||||
// for the default pin orientation (PIN_RIGHT)
|
||||
begin.y = std::max( minsizeV, numberTextHeight + Mils2iu( PIN_TEXT_MARGIN ) );
|
||||
begin.x = std::min( -typeTextLength, m_length - ( numberTextLength / 2) );
|
||||
|
||||
// calculate bottom right corner position and adjust top left corner position
|
||||
if( nameTextOffset ) // for values > 0, pin name is inside the body
|
||||
{
|
||||
end.x = m_length + nameTextLength;
|
||||
|
|
|
@ -177,16 +177,19 @@ public:
|
|||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
||||
/* Cannot use a default parameter here as it will not be compatible with the virtual. */
|
||||
const EDA_RECT GetBoundingBox() const override { return GetBoundingBox( false ); }
|
||||
const EDA_RECT GetBoundingBox() const override { return GetBoundingBox( false, true, false ); }
|
||||
|
||||
/**
|
||||
* @param aIncludeInvisibles - if false, do not include labels for invisible pins
|
||||
* in the calculation.
|
||||
*/
|
||||
const EDA_RECT GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly = false ) const;
|
||||
const EDA_RECT GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
|
||||
bool aIncludeElectricalType ) const;
|
||||
|
||||
/**
|
||||
* Return whether this pin forms an implicit power connection: i.e., is hidden
|
||||
|
|
|
@ -938,7 +938,7 @@ const EDA_RECT LIB_SYMBOL::GetBodyBoundingBox( int aUnit, int aConvert, bool aIn
|
|||
// a well-defined body.
|
||||
|
||||
if( aIncludePins )
|
||||
bbox.Merge( pin.GetBoundingBox( false, true ) );
|
||||
bbox.Merge( pin.GetBoundingBox( false, false, false ) );
|
||||
else
|
||||
bbox.Merge( pin.GetPinRoot() );
|
||||
}
|
||||
|
|
|
@ -143,6 +143,14 @@ int SCH_PIN::GetLength() const
|
|||
}
|
||||
|
||||
|
||||
const BOX2I SCH_PIN::ViewBBox() const
|
||||
{
|
||||
EDA_RECT bbox = GetBoundingBox( false, true, true );
|
||||
|
||||
return BOX2I( bbox.GetOrigin(), bbox.GetSize() );
|
||||
}
|
||||
|
||||
|
||||
void SCH_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
|
||||
{
|
||||
aCount = 3;
|
||||
|
@ -305,10 +313,12 @@ VECTOR2I SCH_PIN::GetTransformedPosition() const
|
|||
}
|
||||
|
||||
|
||||
const EDA_RECT SCH_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly ) const
|
||||
const EDA_RECT SCH_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
|
||||
bool aIncludeElectricalType ) const
|
||||
{
|
||||
TRANSFORM t = GetParentSymbol()->GetTransform();
|
||||
EDA_RECT r = m_libPin->GetBoundingBox( aIncludeInvisibles, aPinOnly );
|
||||
EDA_RECT r = m_libPin->GetBoundingBox( aIncludeInvisiblePins, aIncludeNameAndNumber,
|
||||
aIncludeElectricalType );
|
||||
|
||||
r.RevertYAxis();
|
||||
|
||||
|
@ -326,7 +336,7 @@ bool SCH_PIN::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
|||
if( Schematic() )
|
||||
aAccuracy = std::max( aAccuracy, Schematic()->Settings().m_PinSymbolSize / 4 );
|
||||
|
||||
EDA_RECT rect = GetBoundingBox();
|
||||
EDA_RECT rect = GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
|
||||
return rect.Inflate( aAccuracy ).Contains( aPosition );
|
||||
}
|
||||
|
||||
|
@ -339,9 +349,9 @@ bool SCH_PIN::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) c
|
|||
sel.Inflate( aAccuracy );
|
||||
|
||||
if( aContained )
|
||||
return sel.Contains( GetBoundingBox( false, true ) );
|
||||
return sel.Contains( GetBoundingBox( false, false, false ) );
|
||||
|
||||
return sel.Intersects( GetBoundingBox( false, true ) );
|
||||
return sel.Intersects( GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
wxString GetAlt() const { return m_alt; }
|
||||
void SetAlt( const wxString& aAlt ) { m_alt = aAlt; }
|
||||
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
void ViewGetLayers( int aLayers[], int& aCount ) const override;
|
||||
|
||||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
|
||||
|
@ -82,13 +84,14 @@ public:
|
|||
void SetPosition( const VECTOR2I& aPosition ) override { m_position = aPosition; }
|
||||
|
||||
/* Cannot use a default parameter here as it will not be compatible with the virtual. */
|
||||
const EDA_RECT GetBoundingBox() const override { return GetBoundingBox( false ); }
|
||||
const EDA_RECT GetBoundingBox() const override { return GetBoundingBox( false, true, false ); }
|
||||
|
||||
/**
|
||||
* @param aIncludeInvisibles - if false, do not include labels for invisible pins
|
||||
* in the calculation.
|
||||
*/
|
||||
const EDA_RECT GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly = false ) const;
|
||||
const EDA_RECT GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
|
||||
bool aIncludeElectricalType ) const;
|
||||
|
||||
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
|
||||
bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <math/util.h>
|
||||
#include <geometry/shape_rect.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <painter.h>
|
||||
#include <sch_painter.h>
|
||||
#include <preview_items/selection_area.h>
|
||||
#include <sch_base_frame.h>
|
||||
#include <sch_symbol.h>
|
||||
|
@ -788,6 +788,7 @@ bool EE_SELECTION_TOOL::CollectHits( EE_COLLECTOR& aCollector, const VECTOR2I& a
|
|||
int pixelThreshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
|
||||
int gridThreshold = KiROUND( getView()->GetGAL()->GetGridSize().EuclideanNorm() / 2 );
|
||||
aCollector.m_Threshold = std::max( pixelThreshold, gridThreshold );
|
||||
aCollector.m_ShowPinElectricalTypes = m_frame->GetRenderSettings()->m_ShowPinsElectricalType;
|
||||
|
||||
if( m_isSymbolEditor )
|
||||
{
|
||||
|
@ -1349,22 +1350,32 @@ bool EE_SELECTION_TOOL::selectMultiple()
|
|||
|
||||
for( EDA_ITEM* item : nearbyItems )
|
||||
{
|
||||
if( m_frame->GetRenderSettings()->m_ShowPinsElectricalType )
|
||||
item->SetFlags( SHOW_ELEC_TYPE );
|
||||
|
||||
if( Selectable( item ) && item->HitTest( selectionRect, isWindowSelection ) )
|
||||
{
|
||||
item->SetFlags( CANDIDATE );
|
||||
flaggedItems.push_back( item );
|
||||
selectItem( item );
|
||||
}
|
||||
|
||||
item->ClearFlags( SHOW_ELEC_TYPE );
|
||||
}
|
||||
|
||||
for( EDA_ITEM* item : nearbyChildren )
|
||||
{
|
||||
if( m_frame->GetRenderSettings()->m_ShowPinsElectricalType )
|
||||
item->SetFlags( SHOW_ELEC_TYPE );
|
||||
|
||||
if( Selectable( item )
|
||||
&& !item->GetParent()->HasFlag( CANDIDATE )
|
||||
&& item->HitTest( selectionRect, isWindowSelection ) )
|
||||
{
|
||||
selectItem( item );
|
||||
}
|
||||
|
||||
item->ClearFlags( SHOW_ELEC_TYPE );
|
||||
}
|
||||
|
||||
for( EDA_ITEM* item : flaggedItems )
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#define END_ONPAD (1 << 23) ///< Pcbnew: flag set for track segment ending on a pad
|
||||
#define HOLE_PROXY (1 << 24) ///< Indicates the BOARD_ITEM is a proxy for its hole
|
||||
#define IS_ROLLOVER (1 << 25) ///< Rollover active. Used for hyperlink highlighting.
|
||||
#define SHOW_ELEC_TYPE (1 << 25) ///< Show pin electrical type. Shared with IS_ROLLOVER.
|
||||
#define BRIGHTENED (1 << 26) ///< item is drawn with a bright contour
|
||||
|
||||
#define DP_COUPLED (1 << 27) ///< item is coupled with another item making a differential pair
|
||||
|
|
Loading…
Reference in New Issue