Implement hypertext links for intersheet references.

This commit is contained in:
Jeff Young 2020-10-02 21:18:07 +01:00
parent 5ef1dc17ad
commit cc617b715f
21 changed files with 433 additions and 187 deletions

View File

@ -189,6 +189,7 @@ int EDA_TEXT::LenSize( const wxString& aLine, int aThickness ) const
{
basic_gal.SetFontItalic( IsItalic() );
basic_gal.SetFontBold( IsBold() );
basic_gal.SetFontUnderlined( false );
basic_gal.SetLineWidth( (float) aThickness );
basic_gal.SetGlyphSize( VECTOR2D( GetTextSize() ) );
@ -282,7 +283,7 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
{ // A overbar adds an extra size to the text
// Height from the base line text of chars like [ or {
double curr_height = GetTextHeight() * 1.15;
double overbarPosition = font.ComputeOverbarVerticalPosition( fontSize.y, penWidth );
double overbarPosition = font.ComputeOverbarVerticalPosition( fontSize.y );
int extra_height = KiROUND( overbarPosition - curr_height );
extra_height += thickness / 2;

View File

@ -150,6 +150,7 @@ void GAL::SetTextAttributes( const EDA_TEXT* aText )
SetVerticalJustify( aText->GetVertJustify() );
SetFontBold( aText->IsBold() );
SetFontItalic( aText->IsItalic() );
SetFontUnderlined( false );
SetTextMirrored( aText->IsMirrored() );
}
@ -165,6 +166,7 @@ void GAL::ResetTextAttributes()
SetFontBold( false );
SetFontItalic( false );
SetFontUnderlined( false );
SetTextMirrored( false );
}

View File

@ -37,6 +37,7 @@ using namespace KIGFX;
const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.61;
const double STROKE_FONT::OVERBAR_POSITION_FACTOR = 1.33;
const double STROKE_FONT::UNDERLINE_POSITION_FACTOR = 0.41;
const double STROKE_FONT::BOLD_FACTOR = 1.3;
const double STROKE_FONT::STROKE_FONT_SCALE = 1.0 / 21.0;
const double STROKE_FONT::ITALIC_TILT = 1.0 / 8;
@ -444,6 +445,15 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
last_had_overbar = false;
}
if( m_gal->IsFontUnderlined() )
{
double vOffset = computeUnderlineVerticalPosition();
VECTOR2D startUnderline( xOffset, - vOffset );
VECTOR2D endUnderline( xOffset + glyphSize.x * bbox.GetEnd().x, - vOffset );
m_gal->DrawLine( startUnderline, endUnderline );
}
for( const std::vector<VECTOR2D>* ptList : *glyph )
{
std::deque<VECTOR2D> ptListScaled;
@ -475,13 +485,9 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
}
double STROKE_FONT::ComputeOverbarVerticalPosition( double aGlyphHeight, double aGlyphThickness ) const
double STROKE_FONT::ComputeOverbarVerticalPosition( double aGlyphHeight ) const
{
// Static method.
// Compute the Y position of the overbar. This is the distance between the text base line
// and the overbar axis.
// Don't use the glyph thickness anymore. We don't know how much of it is "real" and how
// much it has been plumped for drop shadows, etc.
return aGlyphHeight * OVERBAR_POSITION_FACTOR;
}
@ -490,7 +496,15 @@ double STROKE_FONT::computeOverbarVerticalPosition() const
{
// Compute the Y position of the overbar. This is the distance between
// the text base line and the overbar axis.
return ComputeOverbarVerticalPosition( m_gal->GetGlyphSize().y, m_gal->GetLineWidth() );
return ComputeOverbarVerticalPosition( m_gal->GetGlyphSize().y );
}
double STROKE_FONT::computeUnderlineVerticalPosition() const
{
// Compute the Y position of the underline. This is the distance between
// the text base line and the underline axis.
return - m_gal->GetGlyphSize().y * UNDERLINE_POSITION_FACTOR;
}

View File

@ -266,6 +266,7 @@ set( EESCHEMA_SRCS
tools/sch_editor_control.cpp
tools/sch_line_wire_bus_tool.cpp
tools/sch_move_tool.cpp
tools/sch_navigate_tool.cpp
)

View File

@ -59,18 +59,6 @@ const KICAD_T EE_COLLECTOR::EditableItems[] = {
};
const KICAD_T EE_COLLECTOR::AnchorableItems[] = {
SCH_PIN_T,
SCH_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIER_LABEL_T,
SCH_SHEET_PIN_T,
SCH_JUNCTION_T,
SCH_LINE_T,
EOT
};
const KICAD_T EE_COLLECTOR::ComponentsOnly[] = {
SCH_COMPONENT_T,
EOT

View File

@ -46,7 +46,6 @@ public:
static const KICAD_T EditableItems[];
static const KICAD_T ComponentsOnly[];
static const KICAD_T SheetsOnly[];
static const KICAD_T AnchorableItems[];
EE_COLLECTOR( const KICAD_T* aScanTypes = EE_COLLECTOR::AllItems ) :
m_Unit( 0 ),

View File

@ -72,6 +72,7 @@
#include <tools/sch_editor_control.h>
#include <tools/sch_line_wire_bus_tool.h>
#include <tools/sch_move_tool.h>
#include <tools/sch_navigate_tool.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <widgets/infobar.h>
@ -343,6 +344,7 @@ void SCH_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new EE_INSPECTION_TOOL );
m_toolManager->RegisterTool( new SCH_EDITOR_CONTROL );
m_toolManager->RegisterTool( new EE_POINT_EDITOR );
m_toolManager->RegisterTool( new SCH_NAVIGATE_TOOL );
m_toolManager->InitTools();
// Run the selection tool, it is supposed to be always active

View File

@ -26,19 +26,20 @@
#include <sch_iref.h>
#include <sch_sheet.h>
#include <schematic.h>
#include <tools/sch_editor_control.h>
#include <tool/tool_manager.h>
#include <tools/sch_editor_control.h>
#include <tools/sch_navigate_tool.h>
SCH_IREF::SCH_IREF( const wxPoint& pos, const wxString& text, SCH_GLOBALLABEL* aParent,
KICAD_T aType ) :
SCH_TEXT( pos, text, SCH_IREF_T )
{
m_Layer = LAYER_GLOBLABEL;
m_parent = aParent;
SetMultilineAllowed( false );
}
void SCH_IREF::PlaceAtDefaultPosition()
{
wxPoint offset;
@ -62,11 +63,13 @@ wxPoint SCH_IREF::GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const
return m_parent->GetSchematicTextOffset( aSettings );
}
EDA_ITEM* SCH_IREF::Clone() const
{
return new SCH_IREF( *this );
}
void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle )
{
wxPoint pt = GetTextPos() - GetParent()->GetPosition();
@ -107,6 +110,7 @@ void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle )
SetPosition( GetParent()->GetPosition() + pt );
}
void SCH_IREF::CopyParentStyle()
{
SetTextSize( m_parent->GetTextSize() );
@ -115,3 +119,22 @@ void SCH_IREF::CopyParentStyle()
SetTextThickness( m_parent->GetTextThickness() );
SetIrefOrientation( m_parent->GetLabelSpinStyle() );
}
void SCH_IREF::BuildHypertextMenu( wxMenu* aMenu )
{
std::map<int, wxString> sheetNames;
for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() )
sheetNames[ sheet.GetPageNumber() ] = sheet.Last()->GetName();
for( int i : m_refTable )
{
aMenu->Append( i, wxString::Format( _( "Go to Page %d (%s)" ),
i,
i == 1 ? _( "Root" ) : sheetNames[ i ] ) );
}
aMenu->AppendSeparator();
aMenu->Append( ID_HYPERTEXT_BACK, _( "Back" ) );
}

View File

@ -72,6 +72,8 @@ public:
void SetScreen( SCH_SCREEN* screen ) { m_screen = screen; }
void BuildHypertextMenu( wxMenu* aMenu );
private:
void SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle );

View File

@ -706,6 +706,7 @@ void SCH_PAINTER::draw( LIB_TEXT *aText, int aLayer )
m_gal->SetGlyphSize( VECTOR2D( aText->GetTextSize() ) );
m_gal->SetFontBold( aText->IsBold() );
m_gal->SetFontItalic( aText->IsItalic() );
m_gal->SetFontUnderlined( false );
strokeText( aText->GetText(), pos, orient );
}
@ -806,6 +807,7 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
m_gal->SetLineWidth( getLineWidth( aPin, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetFontBold( false );
m_gal->SetFontUnderlined( false );
m_gal->SetFontItalic( false );
const int radius = externalPinDecoSize( *aPin );
@ -1295,6 +1297,13 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer )
}
COLOR4D color = getRenderColor( aText, aLayer, drawingShadows );
m_gal->SetFontUnderlined( false );
if( aText->Type() == SCH_IREF_T && ( aText->GetFlags() & IS_ROLLOVER ) > 0 )
{
color = BLUE;
m_gal->SetFontUnderlined( true );
}
if( m_schematic )
{
@ -1536,6 +1545,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer )
m_gal->SetGlyphSize( VECTOR2D( aField->GetTextSize() ) );
m_gal->SetFontBold( aField->IsBold() );
m_gal->SetFontItalic( aField->IsItalic() );
m_gal->SetFontUnderlined( false );
m_gal->SetTextMirrored( aField->IsMirrored() );
m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) );

View File

@ -603,22 +603,6 @@ TOOL_ACTION EE_ACTIONS::generateBOM( "eeschema.EditorControl.generateBOM",
_( "Generate BOM..." ), _( "Generate a bill of materials for the current schematic" ),
bom_xpm );
TOOL_ACTION EE_ACTIONS::enterSheet( "eeschema.EditorControl.enterSheet",
AS_GLOBAL, 0, "",
_( "Enter Sheet" ), _( "Display the selected sheet's contents in the Eeschema window" ),
enter_sheet_xpm );
TOOL_ACTION EE_ACTIONS::leaveSheet( "eeschema.EditorControl.leaveSheet",
AS_GLOBAL,
MD_ALT + WXK_BACK, LEGACY_HK_NAME( "Leave Sheet" ),
_( "Leave Sheet" ), _( "Display the parent sheet in the Eeschema window" ),
leave_sheet_xpm );
TOOL_ACTION EE_ACTIONS::navigateHierarchy( "eeschema.EditorControl.navigateHierarchy",
AS_GLOBAL, 0, "",
_( "Show Hierarchy Navigator" ), "",
hierarchy_nav_xpm );
TOOL_ACTION EE_ACTIONS::explicitCrossProbe( "eeschema.EditorControl.explicitCrossProbe",
AS_GLOBAL, 0, "",
_( "Highlight on PCB" ), _( "Highlight corresponding items in PCBNew" ),
@ -640,6 +624,30 @@ TOOL_ACTION EE_ACTIONS::toggleForceHV( "eeschema.EditorControl.forceHVLines",
lines90_xpm );
// SCH_NAVIGATE_TOOL
//
TOOL_ACTION EE_ACTIONS::enterSheet( "eeschema.NavigateTool.enterSheet",
AS_GLOBAL, 0, "",
_( "Enter Sheet" ), _( "Display the selected sheet's contents in the Eeschema window" ),
enter_sheet_xpm );
TOOL_ACTION EE_ACTIONS::leaveSheet( "eeschema.NavigateTool.leaveSheet",
AS_GLOBAL,
MD_ALT + WXK_BACK, LEGACY_HK_NAME( "Leave Sheet" ),
_( "Leave Sheet" ), _( "Display the parent sheet in the Eeschema window" ),
leave_sheet_xpm );
TOOL_ACTION EE_ACTIONS::navigateHierarchy( "eeschema.NavigateTool.navigateHierarchy",
AS_GLOBAL, 0, "",
_( "Show Hierarchy Navigator" ), "",
hierarchy_nav_xpm );
TOOL_ACTION EE_ACTIONS::hypertextCommand( "eeschema.NavigateTool.hypertextCommand",
AS_GLOBAL, 0, "",
_( "Navigate to page" ), "",
nullptr );
// SCH_LINE_WIRE_BUS_TOOL
//
TOOL_ACTION EE_ACTIONS::addNeededJunctions(

View File

@ -183,6 +183,7 @@ public:
static TOOL_ACTION enterSheet;
static TOOL_ACTION leaveSheet;
static TOOL_ACTION navigateHierarchy;
static TOOL_ACTION hypertextCommand;
// Global edit tools
static TOOL_ACTION cleanupSheetPins;

View File

@ -43,6 +43,7 @@
#include <sch_item.h>
#include <sch_line.h>
#include <sch_sheet.h>
#include <sch_iref.h>
#include <schematic.h>
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
@ -298,10 +299,13 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
KIID lastRolloverItem = niluuid;
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
bool displayPencil = false;
KIID rolloverItem = niluuid;
m_additive = m_subtractive = m_exclusive_or = false;
if( evt->Modifier( MD_SHIFT ) && evt->Modifier( MD_CTRL ) )
@ -315,51 +319,61 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
// items without removing less likely selection candidates
m_skip_heuristics = !!evt->Modifier( MD_ALT );
EE_GRID_HELPER grid( m_toolMgr );
VECTOR2I rawPos = evt->IsPrime() ? evt->Position() : getViewControls()->GetMousePosition();
VECTOR2I cursorPos = grid.BestSnapAnchor( rawPos, nullptr );
// Single click? Select single object
if( evt->IsClick( BUT_LEFT ) )
{
if( auto schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
if( SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
schframe->FocusOnItem( nullptr );
EE_COLLECTOR collector;
bool continueSelect = true;
// Collect items at the clicked location (doesn't select them yet)
if( !CollectHits( evt->Position(), collector, EE_COLLECTOR::AllItems, false ) )
if( collectHits( collector, evt->Position() ) )
{
return false;
}
narrowSelection( collector, evt->Position(), false );
// Check if we want to auto start wires if we clicked on anchors of items
bool continueSelect = true;
if( collector.GetCount() == 1 && m_frame->eeconfig()->m_Drawing.auto_start_wires )
{
EE_GRID_HELPER grid( m_toolMgr );
wxPoint cursorPos = wxPoint( grid.BestSnapAnchor(
evt->IsPrime() ? evt->Position() : getViewControls()->GetMousePosition(),
nullptr ) );
if( collector[0]->IsPointClickableAnchor( cursorPos ) )
if( collector.GetCount() == 1 )
{
OPT_TOOL_EVENT newEvt = EE_ACTIONS::drawWire.MakeEvent();
// Check if we want to auto start wires
if( m_frame->eeconfig()->m_Drawing.auto_start_wires
&& collector[0]->IsPointClickableAnchor( (wxPoint) cursorPos ) )
{
OPT_TOOL_EVENT newEvt = EE_ACTIONS::drawWire.MakeEvent();
auto* params = newEvt->Parameter<DRAW_SEGMENT_EVENT_PARAMS*>();
auto* newParams = new DRAW_SEGMENT_EVENT_PARAMS();
DRAW_SEGMENT_EVENT_PARAMS* params =
newEvt->Parameter<DRAW_SEGMENT_EVENT_PARAMS*>();
DRAW_SEGMENT_EVENT_PARAMS* newParams = new DRAW_SEGMENT_EVENT_PARAMS();
*newParams = *params;
newParams->quitOnDraw = true;
newEvt->SetParameter( newParams );
*newParams= *params;
newParams->quitOnDraw = true;
newEvt->SetParameter( newParams );
newEvt->SetMousePosition( newEvt->Position() );
m_toolMgr->ProcessEvent( *newEvt );
continueSelect = false;
newEvt->SetMousePosition( newEvt->Position() );
m_toolMgr->ProcessEvent( *newEvt );
continueSelect = false;
}
else if( collector[0]->Type() == SCH_IREF_T )
{
wxMenu menu;
static_cast<SCH_IREF*>( collector[0] )->BuildHypertextMenu( &menu );
intptr_t sel = m_frame->GetPopupMenuSelectionFromUser( menu );
m_toolMgr->RunAction( EE_ACTIONS::hypertextCommand, true, (void*) sel );
}
}
}
if( continueSelect )
{
// If we didn't click on an anchor, we perform a normal select, pass in the items we previously collected
SelectPoint(
collector, nullptr, nullptr, m_additive, m_subtractive, m_exclusive_or );
// If we didn't click on an anchor, we perform a normal select, pass in the
// items we previously collected
SelectPoint( collector, nullptr, nullptr, m_additive, m_subtractive,
m_exclusive_or );
}
}
@ -369,7 +383,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
bool selectionCancelled = false;
if( m_selection.Empty() ||
!m_selection.GetBoundingBox().Contains( wxPoint( evt->Position() ) ) )
!m_selection.GetBoundingBox().Contains( (wxPoint) evt->Position() ) )
{
ClearSelection();
SelectPoint( evt->Position(), EE_COLLECTOR::AllItems, nullptr,
@ -483,24 +497,24 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
else if( evt->IsMotion() )
{
if( m_frame->eeconfig()->m_Drawing.auto_start_wires )
EE_COLLECTOR collector;
// We are checking if we should display a pencil when hovering over anchors
// for "auto starting" wires when clicked
if( collectHits( collector, evt->Position() ) )
{
EE_COLLECTOR collector;
narrowSelection( collector, evt->Position(), false );
// We are checking if we should display a pencil when hovering over anchors for "auto starting" wires when clicked
if( CollectHits(
evt->Position(), collector, EE_COLLECTOR::AnchorableItems, false ) )
if( collector.GetCount() == 1 )
{
if( collector.GetCount() == 1 )
if( m_frame->eeconfig()->m_Drawing.auto_start_wires
&& collector[0]->IsPointClickableAnchor( (wxPoint) cursorPos ) )
{
SCH_ITEM* item = collector[0];
if( item
&& item->IsPointClickableAnchor( static_cast<wxPoint>(
getViewControls()->GetCursorPosition( true ) ) ) )
{
displayPencil = true;
}
displayPencil = true;
}
else if( collector[0]->Type() == SCH_IREF_T )
{
rolloverItem = collector[0]->m_Uuid;
}
}
}
@ -509,16 +523,35 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
else
evt->SetPassEvent();
if( rolloverItem != lastRolloverItem )
{
EDA_ITEM* item = m_frame->GetItem( lastRolloverItem );
if( item )
{
item->ClearFlags( IS_ROLLOVER );
lastRolloverItem = niluuid;
m_frame->GetCanvas()->GetView()->Update( item );
}
item = m_frame->GetItem( rolloverItem );
if( item && m_frame->ToolStackIsEmpty() )
{
item->SetFlags( IS_ROLLOVER );
lastRolloverItem = rolloverItem;
m_frame->GetCanvas()->GetView()->Update( item );
}
}
if( m_frame->ToolStackIsEmpty() )
{
if( displayPencil )
{
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_PENCIL );
}
else if( rolloverItem != niluuid )
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_HAND );
else
{
m_frame->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
}
}
}
@ -532,8 +565,8 @@ EE_SELECTION& EE_SELECTION_TOOL::GetSelection()
}
bool EE_SELECTION_TOOL::CollectHits( const VECTOR2I& aWhere, EE_COLLECTOR& aCollector,
const KICAD_T* aFilterList, bool aCheckLocked )
bool EE_SELECTION_TOOL::collectHits( EE_COLLECTOR& aCollector, const VECTOR2I& aWhere,
const KICAD_T* aFilterList )
{
aCollector.m_Threshold = KiROUND( getView()->ToWorld( HITTEST_THRESHOLD_PIXELS ) );
@ -544,39 +577,45 @@ bool EE_SELECTION_TOOL::CollectHits( const VECTOR2I& aWhere, EE_COLLECTOR& aColl
if( !part )
return false;
aCollector.Collect(
part->GetDrawItems(), aFilterList, (wxPoint) aWhere, m_unit, m_convert );
aCollector.Collect( part->GetDrawItems(), aFilterList, (wxPoint) aWhere, m_unit,
m_convert );
}
else
{
aCollector.Collect(
m_frame->GetScreen(), aFilterList, (wxPoint) aWhere, m_unit, m_convert );
aCollector.Collect( m_frame->GetScreen(), aFilterList, (wxPoint) aWhere, m_unit,
m_convert );
}
// Post-process collected items
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
return aCollector.GetCount() > 0;
}
void EE_SELECTION_TOOL::narrowSelection( EE_COLLECTOR& collector, const VECTOR2I& aWhere,
bool aCheckLocked )
{
for( int i = collector.GetCount() - 1; i >= 0; --i )
{
if( !Selectable( aCollector[i] ) )
if( !Selectable( collector[i] ) )
{
aCollector.Remove( i );
collector.Remove( i );
continue;
}
if( aCheckLocked && aCollector[i]->IsLocked() )
if( aCheckLocked && collector[i]->IsLocked() )
{
aCollector.Remove( i );
collector.Remove( i );
continue;
}
// SelectPoint, unlike other selection routines, can select line ends
if( aCollector[i]->Type() == SCH_LINE_T )
if( collector[i]->Type() == SCH_LINE_T )
{
SCH_LINE* line = (SCH_LINE*) aCollector[i];
SCH_LINE* line = (SCH_LINE*) collector[i];
line->ClearFlags( STARTPOINT | ENDPOINT );
if( HitTestPoints( line->GetStartPoint(), (wxPoint) aWhere, aCollector.m_Threshold ) )
if( HitTestPoints( line->GetStartPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
line->SetFlags( STARTPOINT );
else if( HitTestPoints( line->GetEndPoint(), (wxPoint) aWhere, aCollector.m_Threshold ) )
else if( HitTestPoints( line->GetEndPoint(), (wxPoint) aWhere, collector.m_Threshold ) )
line->SetFlags( ENDPOINT );
else
line->SetFlags( STARTPOINT | ENDPOINT );
@ -584,20 +623,27 @@ bool EE_SELECTION_TOOL::CollectHits( const VECTOR2I& aWhere, EE_COLLECTOR& aColl
}
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
if( aCollector.GetCount() > 1 && !m_skip_heuristics )
if( collector.GetCount() > 1 && !m_skip_heuristics )
{
GuessSelectionCandidates( aCollector, aWhere );
GuessSelectionCandidates( collector, aWhere );
}
return true;
}
bool EE_SELECTION_TOOL::SelectPoint( EE_COLLECTOR& aCollector, EDA_ITEM** aItem,
bool* aSelectionCancelledFlag, bool aAdd, bool aSubtract, bool aExclusiveOr )
bool* aSelectionCancelledFlag, bool aAdd, bool aSubtract,
bool aExclusiveOr )
{
m_selection.ClearReferencePoint();
// We have to allow SCH_IREFs in Selectable() for hypertext rollovers and linking to work,
// but at the end of the day we don't actually want them to be selectable.
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
{
if( aCollector[i]->Type() == SCH_IREF_T )
aCollector.Remove( i );
}
// If still more than one item we're going to have to ask the user.
if( aCollector.GetCount() > 1 )
{
@ -662,10 +708,10 @@ bool EE_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFil
{
EE_COLLECTOR collector;
if( !CollectHits( aWhere, collector, aFilterList, aCheckLocked ) )
{
if( !collectHits( collector, aWhere, aFilterList ) )
return false;
}
narrowSelection( collector, aWhere, aCheckLocked );
return SelectPoint( collector, aItem, aSelectionCancelledFlag, aAdd, aSubtract, aExclusiveOr );
}
@ -985,7 +1031,8 @@ bool EE_SELECTION_TOOL::selectMultiple()
{
EDA_ITEM* item = dynamic_cast<EDA_ITEM*>( pair.first );
if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
if( item && Selectable( item ) && item->Type() != SCH_IREF_T
&& item->HitTest( selectionRect, windowSelection ) )
{
if( m_subtractive || ( m_exclusive_or && item->IsSelected() ) )
{
@ -1462,9 +1509,6 @@ bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityO
case SCH_MARKER_T: // Always selectable
return true;
case SCH_IREF_T: // Never selectable
return false;
default: // Suppress warnings
break;
}

View File

@ -122,21 +122,6 @@ public:
bool* aSelectionCancelledFlag = nullptr, bool aAdd = false,
bool aSubtract = false, bool aExclusiveOr = false );
/**
* Function CollectHits()
* Selects one or more items at the location given by parameter aWhere.
*
* This method does not attempt to disambiguate multiple items and is simply "collecting"
*
* @param aWhere is the place where the item should be selected.
* @param aCollector is the collector object that will store found item(s)
* @param aFilterList is a list of items that are acceptable for collection
* @param aCheckLocked indicates if locked items should be excluded.
*/
bool CollectHits( const VECTOR2I& aWhere, EE_COLLECTOR& aCollector,
const KICAD_T* aFilterList = EE_COLLECTOR::AllItems,
bool aCheckLocked = false );
int AddItemToSel( const TOOL_EVENT& aEvent );
void AddItemToSel( EDA_ITEM* aItem, bool aQuietMode = false );
int AddItemsToSel( const TOOL_EVENT& aEvent );
@ -198,6 +183,29 @@ public:
void RebuildSelection();
private:
/**
* Function CollectHits()
* Selects one or more items at the location given by parameter aWhere.
*
* This method does not attempt to disambiguate multiple items and is simply "collecting"
*
* @param aCollector is the collector object that will store found item(s)
* @param aWhere is the place where the item should be selected.
* @param aFilterList is a list of items that are acceptable for collection
* @param aCheckLocked indicates if locked items should be excluded.
*/
bool collectHits( EE_COLLECTOR& aCollector, const VECTOR2I& aWhere,
const KICAD_T* aFilterList = EE_COLLECTOR::AllItems );
/**
* Applies rules to narrow the collection down to selectable objects, and then heuristics
* to try and narrow it to a single object.
* @param collector
* @param aWhere
* @param aCheckLocked
*/
void narrowSelection( EE_COLLECTOR& collector, const VECTOR2I& aWhere, bool aCheckLocked );
/**
* Function selectMultiple()
* Handles drawing a selection box that allows one to select many items at

View File

@ -0,0 +1,120 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 1992-2020 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 <schematic.h>
#include <tools/ee_actions.h>
#include <tools/sch_navigate_tool.h>
int SCH_NAVIGATE_TOOL::NavigateHierarchy( const TOOL_EVENT& aEvent )
{
m_frame->UpdateHierarchyNavigator( true );
return 0;
}
int SCH_NAVIGATE_TOOL::HypertextCommand( const TOOL_EVENT& aEvent )
{
intptr_t target = aEvent.Parameter<intptr_t>();
auto goToPage =
[&]( intptr_t aPage )
{
for( const SCH_SHEET_PATH& sheet : m_frame->Schematic().GetSheets() )
{
if( sheet.GetPageNumber() == aPage )
{
m_frame->GetToolManager()->RunAction( ACTIONS::cancelInteractive, true );
m_frame->GetToolManager()->RunAction( EE_ACTIONS::clearSelection, true );
m_frame->SetCurrentSheet( sheet );
m_frame->DisplayCurrentSheet();
return;
}
}
};
if( target == ID_HYPERTEXT_BACK )
{
if( m_hypertextStack.size() > 0 )
{
goToPage( m_hypertextStack.top() );
m_hypertextStack.pop();
}
}
else
{
m_hypertextStack.push( m_frame->GetCurrentSheet().GetPageNumber() );
goToPage( target );
}
return 0;
}
int SCH_NAVIGATE_TOOL::EnterSheet( const TOOL_EVENT& aEvent )
{
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
const EE_SELECTION& selection = selTool->RequestSelection( EE_COLLECTOR::SheetsOnly );
if( selection.GetSize() == 1 )
{
SCH_SHEET* sheet = (SCH_SHEET*) selection.Front();
m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_frame->GetCurrentSheet().push_back( sheet );
m_frame->DisplayCurrentSheet();
m_frame->UpdateHierarchyNavigator();
}
return 0;
}
int SCH_NAVIGATE_TOOL::LeaveSheet( const TOOL_EVENT& aEvent )
{
if( m_frame->GetCurrentSheet().Last() != &m_frame->Schematic().Root() )
{
m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
m_frame->GetCurrentSheet().pop_back();
m_frame->DisplayCurrentSheet();
m_frame->UpdateHierarchyNavigator();
}
return 0;
}
void SCH_NAVIGATE_TOOL::setTransitions()
{
Go( &SCH_NAVIGATE_TOOL::EnterSheet, EE_ACTIONS::enterSheet.MakeEvent() );
Go( &SCH_NAVIGATE_TOOL::LeaveSheet, EE_ACTIONS::leaveSheet.MakeEvent() );
Go( &SCH_NAVIGATE_TOOL::NavigateHierarchy, EE_ACTIONS::navigateHierarchy.MakeEvent() );
Go( &SCH_NAVIGATE_TOOL::HypertextCommand, EE_ACTIONS::hypertextCommand.MakeEvent() );
}

View File

@ -0,0 +1,65 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019 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 SCH_NAVIGATE_TOOL_H
#define SCH_NAVIGATE_TOOL_H
#include <sch_base_frame.h>
#include <tools/ee_tool_base.h>
#include <status_popup.h>
class SCH_EDIT_FRAME;
#define ID_HYPERTEXT_BACK 999
/**
* SCH_NAVIGATE_TOOL
*
* Handles actions specific to the schematic editor in eeschema.
*/
class SCH_NAVIGATE_TOOL : public wxEvtHandler, public EE_TOOL_BASE<SCH_EDIT_FRAME>
{
public:
SCH_NAVIGATE_TOOL() :
EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.NavigateTool" )
{ }
~SCH_NAVIGATE_TOOL() { }
int EnterSheet( const TOOL_EVENT& aEvent );
int LeaveSheet( const TOOL_EVENT& aEvent );
int NavigateHierarchy( const TOOL_EVENT& aEvent );
int HypertextCommand( const TOOL_EVENT& aEvent );
private:
///> Sets up handlers for various events.
void setTransitions() override;
private:
std::stack<int> m_hypertextStack;
};
#endif // SCH_NAVIGATE_TOOL_H

View File

@ -227,6 +227,7 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
m_gal->SetLineWidth( textSize/10 );
m_gal->SetFontBold( false );
m_gal->SetFontItalic( false );
m_gal->SetFontUnderlined( false );
m_gal->SetTextMirrored( false );
m_gal->SetGlyphSize( VECTOR2D( textSize, textSize) );
m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );

View File

@ -135,7 +135,7 @@ typedef const INSPECTOR_FUNC& INSPECTOR; /// std::function passed to nested u
#define BEGIN_ONPAD (1 << 22) ///< Pcbnew: flag set for track segment starting on a pad
#define END_ONPAD (1 << 23) ///< Pcbnew: flag set for track segment ending on a pad
#define OBSOLETE_3 (1 << 24) ///< Not presently used
#define OBSOLETE_4 (1 << 25) ///< Not presently used
#define IS_ROLLOVER (1 << 25) ///< Rollover active. Used for hyperlink highlighting.
#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

View File

@ -378,16 +378,6 @@ public:
*/
VECTOR2D GetTextLineSize( const UTF8& aText ) const;
/**
* Compute the vertical position of an overbar, sometimes used in texts.
* This is the distance between the text base line and the overbar.
* @return the relative position of the overbar axis.
*/
double GetOverbarVerticalPosition() const
{
return strokeFont.computeOverbarVerticalPosition();
}
/**
* @brief Loads attributes of the given text (bold/italic/underline/mirrored and so on).
*
@ -408,72 +398,35 @@ public:
*
* @param aGlyphSize is the new font glyph size.
*/
inline void SetGlyphSize( const VECTOR2D aGlyphSize )
{
textProperties.m_glyphSize = aGlyphSize;
}
/**
* @return the current font glyph size.
*/
const VECTOR2D& GetGlyphSize() const
{
return textProperties.m_glyphSize;
}
inline void SetGlyphSize( const VECTOR2D aSize ) { textProperties.m_glyphSize = aSize; }
const VECTOR2D& GetGlyphSize() const { return textProperties.m_glyphSize; }
/**
* @brief Set bold property of current font.
*
* @param aBold tells if the font should be bold or not.
*/
inline void SetFontBold( const bool aBold )
{
textProperties.m_bold = aBold;
}
/**
* @brief Returns true if current font has 'bold' attribute enabled.
*/
inline bool IsFontBold() const
{
return textProperties.m_bold;
}
inline void SetFontBold( const bool aBold ) { textProperties.m_bold = aBold; }
inline bool IsFontBold() const { return textProperties.m_bold; }
/**
* @brief Set italic property of current font.
*
* @param aItalic tells if the font should be italic or not.
*/
inline void SetFontItalic( const bool aItalic )
{
textProperties.m_italic = aItalic;
}
inline void SetFontItalic( bool aItalic ) { textProperties.m_italic = aItalic; }
inline bool IsFontItalic() const { return textProperties.m_italic; }
/**
* @brief Returns true if current font has 'italic' attribute enabled.
*/
inline bool IsFontItalic() const
{
return textProperties.m_italic;
}
inline void SetFontUnderlined( bool aUnderlined ) { textProperties.m_underlined = aUnderlined; }
inline bool IsFontUnderlined() const { return textProperties.m_underlined; }
/**
* @brief Set a mirrored property of text.
*
* @param aMirrored tells if the text should be mirrored or not.
*/
inline void SetTextMirrored( const bool aMirrored )
{
textProperties.m_mirrored = aMirrored;
}
/**
* @brief Returns true if text should displayed mirrored.
*/
inline bool IsTextMirrored() const
{
return textProperties.m_mirrored;
}
inline void SetTextMirrored( const bool aMirrored ) { textProperties.m_mirrored = aMirrored; }
inline bool IsTextMirrored() const { return textProperties.m_mirrored; }
/**
* @brief Set the horizontal justify for text drawing.
@ -1189,6 +1142,7 @@ private:
EDA_TEXT_VJUSTIFY_T m_verticalJustify; ///< Vertical justification
bool m_bold;
bool m_italic;
bool m_underlined;
bool m_mirrored;
} textProperties;
};

View File

@ -98,10 +98,9 @@ public:
* Compute the vertical position of an overbar, sometimes used in texts.
* This is the distance between the text base line and the overbar.
* @param aGlyphHeight is the height (vertical size) of the text.
* @param aGlyphThickness is the thickness of the lines used to draw the text.
* @return the relative position of the overbar axis.
*/
double ComputeOverbarVerticalPosition( double aGlyphHeight, double aGlyphThickness ) const;
double ComputeOverbarVerticalPosition( double aGlyphHeight ) const;
/**
* @brief Compute the distance (interline) between 2 lines of text (for multiline texts).
@ -133,6 +132,7 @@ private:
* @return the relative position of the overbar axis.
*/
double computeOverbarVerticalPosition() const;
double computeUnderlineVerticalPosition() const;
/**
* @brief Compute the bounding box of a given glyph.
@ -168,6 +168,7 @@ private:
///> Factor that determines relative vertical position of the overbar.
static const double OVERBAR_POSITION_FACTOR;
static const double UNDERLINE_POSITION_FACTOR;
///> Factor that determines relative line width for bold text.
static const double BOLD_FACTOR;

View File

@ -504,6 +504,7 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
m_gal->SetLineWidth( width / 10.0 );
m_gal->SetFontBold( false );
m_gal->SetFontItalic( false );
m_gal->SetFontUnderlined( false );
m_gal->SetTextMirrored( false );
m_gal->SetGlyphSize( VECTOR2D( textSize * 0.7, textSize * 0.7 ) );
m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
@ -773,6 +774,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
m_gal->SetFontBold( false );
m_gal->SetFontItalic( false );
m_gal->SetFontUnderlined( false );
m_gal->SetTextMirrored( false );
m_gal->SetStrokeColor( m_pcbSettings.GetColor( NULL, aLayer ) );
m_gal->SetIsStroke( true );