static void BuildDimension( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) { PCB_SCREEN* screen = (PCB_SCREEN*) aPanel->GetScreen(); DIMENSION* Dimension = (DIMENSION*) screen->GetCurItem(); wxPoint pos = aPanel->GetParent()->GetCrossHairPosition(); if( Dimension == NULL ) return; // Erase previous dimension. if( aErase ) { Dimension->Draw( aPanel, aDC, GR_XOR ); } Dimension->SetLayer( screen->m_Active_Layer ); if( status_dimension == 1 ) { Dimension->m_featureLineDO = pos; Dimension->m_crossBarF = Dimension->m_featureLineDO; Dimension->AdjustDimensionDetails( ); } else { wxPoint delta; int dx, dy; double angle, depl; delta = Dimension->m_featureLineDO - Dimension->m_featureLineGO; /* Calculating the direction of travel perpendicular to the selected axis. */ angle = atan2( delta.y, delta.x ) + (M_PI / 2); delta = pos - Dimension->m_featureLineDO; depl = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) ); dx = KiROUND( depl * cos( angle ) ); dy = KiROUND( depl * sin( angle ) ); Dimension->m_crossBarO.x = Dimension->m_featureLineGO.x + dx; Dimension->m_crossBarO.y = Dimension->m_featureLineGO.y + dy; Dimension->m_crossBarF.x = Dimension->m_featureLineDO.x + dx; Dimension->m_crossBarF.y = Dimension->m_featureLineDO.y + dy; Dimension->AdjustDimensionDetails( ); } Dimension->Draw( aPanel, aDC, GR_XOR ); }
int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent ) { DIMENSION* dimension = NULL; int width, maxThickness; // if one day it is possible to draw dimensions in the footprint editor, // then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet assert( !m_editModules ); // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); Activate(); m_frame->SetToolID( ID_PCB_DIMENSION_BUTT, wxCURSOR_PENCIL, _( "Add dimension" ) ); enum DIMENSION_STEPS { SET_ORIGIN = 0, SET_END, SET_HEIGHT, FINISHED }; int step = SET_ORIGIN; // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( evt->IsCancel() || evt->IsActivate() ) { if( step != SET_ORIGIN ) // start from the beginning { preview.Clear(); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); delete dimension; step = SET_ORIGIN; } else break; if( evt->IsActivate() ) // now finish unconditionally break; } else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) && step != SET_ORIGIN ) { dimension->SetWidth( dimension->GetWidth() + WIDTH_STEP ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) && step != SET_ORIGIN ) { int width = dimension->GetWidth(); if( width > WIDTH_STEP ) { dimension->SetWidth( width - WIDTH_STEP ); preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } else if( evt->IsClick( BUT_LEFT ) ) { switch( step ) { case SET_ORIGIN: { LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; if( IsCopperLayer( layer ) || layer == Edge_Cuts ) { DisplayInfoMessage( NULL, _( "Dimension not allowed on Copper or Edge Cut layers" ) ); --step; } else { // Init the new item attributes dimension = new DIMENSION( m_board ); dimension->SetLayer( layer ); dimension->SetOrigin( wxPoint( cursorPos.x, cursorPos.y ) ); dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); dimension->Text().SetSize( m_board->GetDesignSettings().m_PcbTextSize ); width = m_board->GetDesignSettings().m_PcbTextWidth; maxThickness = Clamp_Text_PenSize( width, dimension->Text().GetSize() ); if( width > maxThickness ) width = maxThickness; dimension->Text().SetThickness( width ); dimension->SetWidth( width ); dimension->AdjustDimensionDetails(); preview.Add( dimension ); m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); } } break; case SET_END: dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); // Dimensions that have origin and end in the same spot are not valid if( dimension->GetOrigin() == dimension->GetEnd() ) --step; break; case SET_HEIGHT: { if( wxPoint( cursorPos.x, cursorPos.y ) != dimension->GetPosition() ) { assert( dimension->GetOrigin() != dimension->GetEnd() ); assert( dimension->GetWidth() > 0 ); m_view->Add( dimension ); m_board->Add( dimension ); dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); m_frame->OnModify(); m_frame->SaveCopyInUndoList( dimension, UR_NEW ); preview.Remove( dimension ); } } break; } if( ++step == FINISHED ) { step = SET_ORIGIN; m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); } } else if( evt->IsMotion() ) { switch( step ) { case SET_END: dimension->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); break; case SET_HEIGHT: { // Calculating the direction of travel perpendicular to the selected axis double angle = dimension->GetAngle() + ( M_PI / 2 ); wxPoint pos( cursorPos.x, cursorPos.y ); wxPoint delta( pos - dimension->m_featureLineDO ); double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) ); dimension->SetHeight( height ); } break; } // Show a preview of the item preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } if( step != SET_ORIGIN ) delete dimension; m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); m_view->Remove( &preview ); m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; }