Пример #1
0
void PCB_BASE_FRAME::CursorGoto( const wxPoint& aPos, bool aWarp )
{
    // factored out of pcbnew/find.cpp

    PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen();

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    // There may be need to reframe the drawing.
    if( !m_canvas->IsPointOnDisplay( aPos ) )
    {
        screen->SetCrossHairPosition( aPos );
        RedrawScreen( aPos, aWarp );
    }
    else
    {
        // Put cursor on item position
        m_canvas->CrossHairOff( &dc );
        screen->SetCrossHairPosition( aPos );

        if( aWarp )
            m_canvas->MoveCursorToCrossHair();
    }
    m_canvas->CrossHairOn( &dc );
    m_canvas->CrossHairOn( &dc );
}
Пример #2
0
void WinEDA_GerberFrame::OnCloseWindow(wxCloseEvent & Event)
/***********************************************************/
{
PCB_SCREEN * screen;

	screen = ScreenPcb ;
	while( screen )
		{
		if(screen->IsModify()) break;
		screen = screen->Next();
		}

	if ( screen )
		{
		if( ! IsOK(this, _("Layer modified,  Continue ?")) )
			{
			Event.Veto();
			return;
			}
		}

	while( screen )	// suppression flag modify pour eviter d'autres message
		{
		screen->ClrModify();
		screen = screen->Next();
		}

	/* Reselection de l'ecran de base,
		pour les evenements de refresh générés par wxWindows */
	m_CurrentScreen = ActiveScreen = ScreenPcb;

	SaveSettings();
	Destroy();
}
Пример #3
0
void WinEDA_PcbFrame::RedrawActiveWindow(wxDC * DC, bool EraseBg)
/****************************************************************/
/* Trace le PCB, et les elements complementaires ( axes, grille .. )
 pour l'ecran actif et ses sous ecran
*/
{
PCB_SCREEN * Screen = GetScreen();

	if ( ! m_Pcb || ! Screen ) return;

	ActiveScreen = GetScreen();
	GRSetDrawMode(DC, GR_COPY);

	if ( EraseBg ) DrawPanel->EraseScreen(DC);

	DrawPanel->DrawBackGround(DC);

	Trace_Pcb(DC, GR_OR);
	TraceWorkSheet(DC, GetScreen());
	Affiche_Status_Box();

	/* Reaffichage des curseurs */
	for( Screen = GetScreen(); Screen != NULL; Screen = Screen->Next() )
	{
		if( m_CurrentScreen->ManageCurseur )
			m_CurrentScreen->ManageCurseur(DrawPanel, DC, FALSE);
		Screen->Trace_Curseur(DrawPanel, DC);
	}
}
VECTOR2I GRID_HELPER::GetGrid() const
{
    PCB_SCREEN* screen = m_frame->GetScreen();

    const wxRealPoint& size = screen->GetGridSize();

    return VECTOR2I( KiROUND( size.x ), KiROUND( size.y ) );
}
Пример #5
0
void WinEDA_PcbFrame::OnCloseWindow(wxCloseEvent & Event)
/********************************************************/
{
PCB_SCREEN * screen;

	DrawPanel->m_AbortRequest = TRUE;

	screen = ScreenPcb ;
	while( screen )
	{
		if(screen->IsModify()) break;
		screen = screen->Next();
	}

	if ( screen )
	{
	unsigned ii;
		wxMessageDialog dialog(this, _("Board modified, Save before exit ?"),
			_("Confirmation"), wxYES_NO | wxCANCEL | wxICON_EXCLAMATION | wxYES_DEFAULT);
		ii = dialog.ShowModal();
		switch ( ii )
		{
			case wxID_CANCEL:
			Event.Veto();
			return;

			case wxID_NO:
				break;

			case wxID_OK:
			case wxID_YES:
				SavePcbFile(GetScreen()->m_FileName);
				break;
		}
	}

	while( screen )	// suppression flag modify pour eviter d'autres message
	{
		screen->ClrModify();
		screen = screen->Next();
	}

	/* Reselection de l'ecran de base,
		pour les evenements de refresh générés par wxWindows */
	m_CurrentScreen = ActiveScreen = ScreenPcb;

	SaveSettings();
	Destroy();
}
Пример #6
0
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 );
}
Пример #7
0
/*
 * Update the status bar information.
 */
void PCB_BASE_FRAME::UpdateStatusBar()
{
    EDA_DRAW_FRAME::UpdateStatusBar();

    if( DisplayOpt.DisplayPolarCood )  // display polar coordinates
    {
        PCB_SCREEN* screen = GetScreen();

        if( !screen )
            return;

        wxString     Line;
        double       theta, ro;

        int dx = screen->GetCrossHairPosition().x - screen->m_O_Curseur.x;
        int dy = screen->GetCrossHairPosition().y - screen->m_O_Curseur.y;

        if( dx==0 && dy==0 )
            theta = 0.0;
        else
            theta = atan2( (double) -dy, (double) dx );

        theta = theta * 180.0 / M_PI;

        ro = sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
        wxString formatter;
        switch( g_UserUnit )
        {
        case INCHES:
            formatter = wxT( "Ro %.4f Th %.1f" );
            break;

        case MILLIMETRES:
            formatter = wxT( "Ro %.3f Th %.1f" );
            break;

        case UNSCALED_UNITS:
            formatter = wxT( "Ro %f Th %f" );
            break;
        }

        Line.Printf( formatter, To_User_Unit( g_UserUnit, ro, m_internalUnits ), theta );

        // overwrite the absolute cartesian coordinates
        SetStatusText( Line, 2 );
    }
}
Пример #8
0
void WinEDA_ModuleEditFrame::RedrawActiveWindow(wxDC * DC, bool EraseBg)
/**********************************************************************/

/* Trace le PCB, et les elements complementaires ( axes, grille .. )
 pour l'ecran actif et ses sous ecran
*/

{
MODULE * Module;
PCB_SCREEN * screen = GetScreen();

	if ( ! m_Pcb || ! screen ) return;

	ActiveScreen = screen;
	GRSetDrawMode(DC, GR_COPY);

	if ( EraseBg ) DrawPanel->EraseScreen(DC);

	DrawPanel->DrawBackGround(DC);
	TraceWorkSheet(DC, screen);

	Module = (MODULE*) m_Pcb->m_Modules;
	for ( ; Module != NULL; Module = (MODULE *) Module->Pnext )
		{
		Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR);
		}


	Affiche_Status_Box();

	if( screen->ManageCurseur )
		screen->ManageCurseur(DrawPanel, DC, FALSE);

	/* Reaffichage du curseur */
	screen->Trace_Curseur(DrawPanel, DC);

	screen->ClrRefreshReq();
}
Пример #9
0
void PCB_BASE_FRAME::CursorGoto( const wxPoint& aPos )
{
    // factored out of pcbnew/find.cpp

    PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen();

    wxClientDC dc( m_canvas );

    // There may be need to reframe the drawing.
    if( !m_canvas->IsPointOnDisplay( aPos ) )
    {
        screen->SetCrossHairPosition( aPos );
        RedrawScreen( aPos, true );
    }
    else
    {
        // Put cursor on item position
        m_canvas->CrossHairOff( &dc );
        screen->SetCrossHairPosition( aPos );
        m_canvas->MoveCursorToCrossHair();
        m_canvas->CrossHairOn( &dc );
    }
}
Пример #10
0
/*
 * Update the status bar information.
 */
void PCB_BASE_FRAME::UpdateStatusBar()
{
    EDA_DRAW_FRAME::UpdateStatusBar();

    PCB_SCREEN* screen = GetScreen();

    if( !screen )
        return;

    int dx;
    int dy;
    double dXpos;
    double dYpos;
    wxString line;
    wxString locformatter;

    if( DisplayOpt.DisplayPolarCood )  // display polar coordinates
    {
        double       theta, ro;

        dx = screen->GetCrossHairPosition().x - screen->m_O_Curseur.x;
        dy = screen->GetCrossHairPosition().y - screen->m_O_Curseur.y;

        if( dx==0 && dy==0 )
            theta = 0.0;
        else
            theta = atan2( (double) -dy, (double) dx );

        theta = theta * 180.0 / M_PI;

        ro = sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
        wxString formatter;
        switch( g_UserUnit )
        {
#if defined( USE_PCBNEW_NANOMETRE )
        case INCHES:
            formatter = wxT( "Ro %.6f Th %.1f" );
            break;

        case MILLIMETRES:
            formatter = wxT( "Ro %.6f Th %.1f" );
            break;
#else
        case INCHES:
            formatter = wxT( "Ro %.4f Th %.1f" );
            break;

        case MILLIMETRES:
            formatter = wxT( "Ro %.3f Th %.1f" );
            break;
#endif

        case UNSCALED_UNITS:
            formatter = wxT( "Ro %f Th %f" );
            break;
        }

        line.Printf( formatter, To_User_Unit( g_UserUnit, ro ), theta );

        SetStatusText( line, 3 );
    }

    // Display absolute coordinates:
    dXpos = To_User_Unit( g_UserUnit, screen->GetCrossHairPosition().x );
    dYpos = To_User_Unit( g_UserUnit, screen->GetCrossHairPosition().y );

    if ( g_UserUnit == MILLIMETRES )
    {
        dXpos = RoundTo0( dXpos, 1000.0 );
        dYpos = RoundTo0( dYpos, 1000.0 );
    }

    // The following sadly is an if Eeschema/if Pcbnew
    wxString absformatter;

    switch( g_UserUnit )
    {
#if defined( USE_PCBNEW_NANOMETRES )
    case INCHES:
        absformatter = wxT( "X %.6f  Y %.6f" );
        locformatter = wxT( "dx %.6f  dy %.6f  d %.6f" );
        break;

    case MILLIMETRES:
        absformatter = wxT( "X %.6f  Y %.6f" );
        locformatter = wxT( "dx %.6f  dy %.6f  d %.6f" );
        break;
#else
    case INCHES:
        absformatter = wxT( "X %.4f  Y %.4f" );
        locformatter = wxT( "dx %.4f  dy %.4f  d %.4f" );
        break;

    case MILLIMETRES:
        absformatter = wxT( "X %.3f  Y %.3f" );
        locformatter = wxT( "dx %.3f  dy %.3f  d %.3f" );
        break;
#endif

    case UNSCALED_UNITS:
        absformatter = wxT( "X %f  Y %f" );
        locformatter = wxT( "dx %f  dy %f  d %f" );
        break;
    }

    line.Printf( absformatter, dXpos, dYpos );
    SetStatusText( line, 2 );

    if( !DisplayOpt.DisplayPolarCood )  // display relative cartesian coordinates
    {
        // Display relative coordinates:
        dx = screen->GetCrossHairPosition().x - screen->m_O_Curseur.x;
        dy = screen->GetCrossHairPosition().y - screen->m_O_Curseur.y;
        dXpos = To_User_Unit( g_UserUnit, dx );
        dYpos = To_User_Unit( g_UserUnit, dy );

        if ( g_UserUnit == MILLIMETRES )
        {
            dXpos = RoundTo0( dXpos, 1000.0 );
            dYpos = RoundTo0( dYpos, 1000.0 );
        }

        // We already decided the formatter above
        line.Printf( locformatter, dXpos, dYpos, sqrt( dXpos * dXpos + dYpos * dYpos ) );
        SetStatusText( line, 3 );
    }
}
Пример #11
0
void EDGE_MODULE::Draw(WinEDA_DrawPanel * panel, wxDC * DC,
						const wxPoint & offset, int draw_mode)
/********************************************************************************/

/* Affichage d'un segment contour de module :
	Entree : ox, oy = offset de trace
	draw_mode = mode de trace ( GR_OR, GR_XOR, GR_AND)
		Les contours sont de differents type:
		- Segment
		- Cercles
		- Arcs
*/
{
int ux0, uy0, dx, dy,rayon, StAngle, EndAngle;
int color , type_trace;
int zoom;
int typeaff;
PCB_SCREEN * screen;
WinEDA_BasePcbFrame * frame;
MODULE * Module = NULL;

	if ( m_Parent && (m_Parent->m_StructType == TYPEMODULE) )
		Module = (MODULE*) m_Parent;

	GRSetDrawMode(DC, draw_mode);
	color = g_DesignSettings.m_LayerColor[m_Layer];

	if ( panel ) screen = (PCB_SCREEN *) panel->m_Parent->m_CurrentScreen;
	else screen = ActiveScreen;

	frame = screen->GetParentPcbFrame();

	zoom = screen->GetZoom();

	type_trace = m_Shape;
	ux0 = m_Start.x - offset.x; uy0 = m_Start.y - offset.y;
	dx = m_End.x - offset.x ;
	dy = m_End.y - offset.y ;

	typeaff = frame->m_DisplayModEdge;
	if( m_Layer <= CMP_N )
		typeaff = frame->m_DisplayPcbTrackFill;
	if( (m_Width /zoom) < L_MIN_DESSIN ) typeaff = FILAIRE;

	switch (type_trace )
	{
		case S_SEGMENT:
			if( typeaff == FILAIRE)
				GRLine(&panel->m_ClipBox, DC,  ux0, uy0, dx, dy, color);
			else Affiche_1_Segment(panel, DC, ux0,uy0,dx,dy,m_Width,
									typeaff,color);
			break ;

		case S_CIRCLE:
			rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) );
			if( typeaff == FILAIRE)
			{
				GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon, color) ;
			}
			else
			{
				if(typeaff == FILLED )
				{
					GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon, m_Width, color);
				}
				else
				{
					GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon + (m_Width/2), color) ;
					GRCircle(&panel->m_ClipBox, DC, ux0, uy0, rayon - (m_Width/2), color) ;
				}
			}
			break;

		case S_ARC:
			rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) );
			StAngle = (int)ArcTangente( dy-uy0, dx-ux0 );
			EndAngle = StAngle + m_Angle;
			if ( StAngle > EndAngle) EXCHG (StAngle, EndAngle);
			if( typeaff == FILAIRE)
			{
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon, color) ;
			}
			else if(typeaff == FILLED )
				{
					GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle, rayon,
								m_Width, color);
				}
			else
			{
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
						rayon + (m_Width/2), color) ;
				GRArc(&panel->m_ClipBox, DC, ux0, uy0, StAngle, EndAngle,
						rayon - (m_Width/2), color) ;
			}
			break;

		case S_POLYGON:
		{
			// We must compute true coordinates from m_PolyList
			// which are relative to module position, orientation 0
			int ii, * source, * ptr, * ptr_base;
			ptr = ptr_base = (int*) MyMalloc( 2 * m_PolyCount * sizeof(int) );
			source = m_PolyList;
			for (ii = 0; ii < m_PolyCount; ii++ )
			{
				int x, y;
				x = *source; source++; y = *source; source++;
				if ( Module )
				{
					RotatePoint (&x, &y, Module->m_Orient);
					x += Module->m_Pos.x;
					y += Module->m_Pos.y;
				}
				x +=  m_Start0.x - offset.x;
				y +=  m_Start0.y - offset.y;
				*ptr = x; ptr++; *ptr = y; ptr++;
			}
			GRPoly(&panel->m_ClipBox, DC, m_PolyCount, ptr_base,
				TRUE, color, color);
			free ( ptr_base);
			break;
		}
	}
}
Пример #12
0
void WinEDA_PcbFindFrame::FindItem(wxCommandEvent& event)
/********************************************************/
{
PCB_SCREEN * screen = m_Parent->GetScreen();
wxPoint locate_pos;
wxString msg;
bool succes = FALSE;
bool FindMarker = FALSE;
MODULE * Module;
int StartCount;
	
	switch ( event.GetId() )
	{
		case ID_FIND_ITEM:
			s_ItemCount = 0;
			break;
		
		case ID_FIND_MARKER: s_MarkerCount = 0;
		case ID_FIND_NEXT_MARKER:
			FindMarker = TRUE;
			break;
	}

	s_OldStringFound = m_NewText->GetValue();

	m_Parent->DrawPanel->GetViewStart(&screen->m_StartVisu.x, &screen->m_StartVisu.y);
	StartCount = 0;
	
	if( FindMarker )
	{
	MARQUEUR * Marker = (MARQUEUR *) m_Parent->m_Pcb->m_Drawings; 
		for( ; Marker != NULL; Marker = (MARQUEUR *)Marker->Pnext)
		{
			if( Marker->m_StructType != TYPEMARQUEUR ) continue;
			StartCount++;
			if ( StartCount > s_MarkerCount )
			{
				succes = TRUE;
				locate_pos = Marker->m_Pos;
				s_MarkerCount++;
				break;
			}
		}
	}
	
	else for ( Module = m_Parent->m_Pcb->m_Modules; Module != NULL; Module = (MODULE*)Module->Pnext)
	{
		if( WildCompareString( s_OldStringFound, Module->m_Reference->m_Text.GetData(), FALSE ) )
		{
			StartCount++;
			if ( StartCount > s_ItemCount )
			{
				succes = TRUE;
				locate_pos = Module->m_Pos;
				s_ItemCount++;
				break;
			}
		}
		if( WildCompareString( s_OldStringFound, Module->m_Value->m_Text.GetData(), FALSE ) )
		{
			StartCount++;
			if ( StartCount > s_ItemCount )
			{
				succes = TRUE;
				locate_pos = Module->m_Pos;
				s_ItemCount++;
				break;
			}
		}
	}
	
	if ( succes )
	{	/* Il y a peut-etre necessite de recadrer le dessin: */		
		if( ! m_Parent->DrawPanel->IsPointOnDisplay(locate_pos) )
		{
			screen->m_Curseur = locate_pos;
			m_Parent->Recadre_Trace(TRUE);
		}
		else
		{	// Positionnement du curseur sur l'item
			screen->Trace_Curseur(m_Parent->DrawPanel, m_DC);
			screen->m_Curseur = locate_pos;
			GRMouseWarp(m_Parent->DrawPanel, screen->m_Curseur );
			m_Parent->DrawPanel->MouseToCursorSchema();
			screen->Trace_Curseur(m_Parent->DrawPanel, m_DC);
		}

		if( FindMarker ) msg = _("Marker found");
		else msg.Printf( _("<%s> Found"), s_OldStringFound.GetData() );
		m_Parent->Affiche_Message(msg);
		EndModal(1);
	}

	else
	{
		m_Parent->Affiche_Message(wxEmptyString);
		if( FindMarker ) msg = _("Marker not found");
		else msg.Printf( _("<%s> Not Found"), s_OldStringFound.GetData());
		DisplayError(this,msg, 10);
	}
	EndModal(0);
}
Пример #13
0
/* Insert the new track created in the list of tracks.
 * amend the points of beginning and end of the track so that they are
 * connected
 * Center on pads even if they are off grid.
 */
static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
{
    if( g_FirstTrackSegment == NULL )
        return;

    int dx0, dy0, dx1, dy1;
    int marge, via_marge;
    EDA_DRAW_PANEL* panel = pcbframe->GetCanvas();
    PCB_SCREEN* screen = pcbframe->GetScreen();

    marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentTrackWidth() / 2 );
    via_marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentViaSize() / 2 );

    dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x;
    dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y;

    // Place on center of pad if off grid.
    dx0 = pt_cur_ch->m_PadStart->GetPosition().x - g_CurrentTrackSegment->GetStart().x;
    dy0 = pt_cur_ch->m_PadStart->GetPosition().y - g_CurrentTrackSegment->GetStart().y;

    // If aligned, change the origin point.
    if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) )
    {
        g_CurrentTrackSegment->SetEnd( pt_cur_ch->m_PadStart->GetPosition() );
    }
    else
    {
        TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone();

        newTrack->SetEnd( pt_cur_ch->m_PadStart->GetPosition() );
        newTrack->SetStart( g_CurrentTrackSegment->GetEnd() );

        g_CurrentTrackList.PushBack( newTrack );
    }

    g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment,
            ENDPOINT_START );

    if( g_FirstTrackSegment->start )
        g_FirstTrackSegment->SetState( BEGIN_ONPAD, true );

    g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment,
            ENDPOINT_END );

    if( g_CurrentTrackSegment->end )
        g_CurrentTrackSegment->SetState( END_ONPAD, true );

    // Out the new track on the matrix board
    for( TRACK* track = g_FirstTrackSegment; track; track = track->Next() )
    {
        TraceSegmentPcb( track, HOLE, marge, WRITE_CELL );
        TraceSegmentPcb( track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
    }

    // Insert new segments in  real board
    int    netcode    = g_FirstTrackSegment->GetNetCode();
    TRACK* firstTrack = g_FirstTrackSegment;
    int    newCount   = g_CurrentTrackList.GetCount();

    // Put entire new current segment list in BOARD
    TRACK* track;
    TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( pcbframe->GetBoard() );

    while( ( track = g_CurrentTrackList.PopFront() ) != NULL )
    {
        ITEM_PICKER picker( track, UR_NEW );
        s_ItemsListPicker.PushItem( picker );
        pcbframe->GetBoard()->m_Track.Insert( track, insertBeforeMe );
    }

    DrawTraces( panel, DC, firstTrack, newCount, GR_OR );

    pcbframe->TestNetConnection( DC, netcode );

    screen->SetModify();
}
Пример #14
0
void FOOTPRINT_WIZARD_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
{
    wxRealPoint     gridSize;
    wxPoint         oldpos;
    PCB_SCREEN*     screen  = GetScreen();
    wxPoint         pos     = aPosition;

    wxCommandEvent  cmd( wxEVT_COMMAND_MENU_SELECTED );

    cmd.SetEventObject( this );

    pos         = GetNearestGridPosition( pos );
    oldpos      = GetCrossHairPosition();
    gridSize    = screen->GetGridSize();

    switch( aHotKey )
    {
    case WXK_F1:
        cmd.SetId( ID_POPUP_ZOOM_IN );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case WXK_F2:
        cmd.SetId( ID_POPUP_ZOOM_OUT );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case WXK_F3:
        cmd.SetId( ID_ZOOM_REDRAW );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case WXK_F4:
        cmd.SetId( ID_POPUP_ZOOM_CENTER );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case WXK_HOME:
        cmd.SetId( ID_ZOOM_PAGE );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case ' ':
        screen->m_O_Curseur = GetCrossHairPosition();
        break;

    case WXK_NUMPAD8:       // cursor moved up
    case WXK_UP:
        pos.y -= KiROUND( gridSize.y );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD2:       // cursor moved down
    case WXK_DOWN:
        pos.y += KiROUND( gridSize.y );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD4:       // cursor moved left
    case WXK_LEFT:
        pos.x -= KiROUND( gridSize.x );
        m_canvas->MoveCursor( pos );
        break;

    case WXK_NUMPAD6:       // cursor moved right
    case WXK_RIGHT:
        pos.x += KiROUND( gridSize.x );
        m_canvas->MoveCursor( pos );
        break;
    }

    SetCrossHairPosition( pos );

    if( oldpos != GetCrossHairPosition() )
    {
        pos = GetCrossHairPosition();
        SetCrossHairPosition( oldpos );
        m_canvas->CrossHairOff( aDC );
        SetCrossHairPosition( pos );
        m_canvas->CrossHairOn( aDC );

        if( m_canvas->IsMouseCaptured() )
        {
            m_canvas->CallMouseCapture( aDC, aPosition, 0 );
        }
    }

    UpdateStatusBar();    // Display new cursor coordinates
}
Пример #15
0
/*
 * This is the real print function: print the active screen
 */
void BOARD_PRINTOUT_CONTROLER::DrawPage()
{
    int          tmpzoom;
    wxPoint      tmp_startvisu;
    wxPoint      old_org;
    wxPoint      DrawOffset;    // Offset de trace
    double       userscale;
    double       DrawZoom = 1;
    wxDC*        dc = GetDC();
    PCB_SCREEN*  screen = (PCB_SCREEN*) m_Parent->GetScreen();
    bool         printMirror = m_PrintParams.m_PrintMirror;

    wxBusyCursor dummy;

    // Save old draw scale and draw offset
    tmp_startvisu = screen->m_StartVisu;
    tmpzoom = screen->GetZoom();
    old_org = screen->m_DrawOrg;

    // Change draw scale and offset to draw the whole page
    screen->SetScalingFactor( DrawZoom );
    screen->m_DrawOrg.x   = screen->m_DrawOrg.y = 0;
    screen->m_StartVisu.x = screen->m_StartVisu.y = 0;

    PCB_BASE_FRAME* pcbframe = (PCB_BASE_FRAME*) m_Parent;

    wxSize  pageSizeIU = pcbframe->GetPageSizeIU();  // internal units
    EDA_RECT bbbox     = pcbframe->GetBoard()->ComputeBoundingBox();

    // In module editor, the module is located at 0,0 but for printing
    // it is moved to pageSizeIU.x/2, pageSizeIU.y/2.
    // So the equivalent board must be moved:
    if( m_Parent->IsType( MODULE_EDITOR_FRAME ) )
    {
        bbbox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) );
    }

    // Compute the PCB size in internal units
    userscale = m_PrintParams.m_PrintScale;

    if( userscale == 0 )                //  fit in page
    {
        // Margin = 0.4 inch
#if defined(KICAD_NANOMETRE)
        int extra_margin = int( 0.4 * 25400 );      // nanometers
#else
        int extra_margin = int( 0.4 * 1000 );       // deci-mils
#endif

        pageSizeIU.x = bbbox.GetWidth()  + extra_margin * 2;
        pageSizeIU.y = bbbox.GetHeight() + extra_margin * 2;

        userscale   = 0.99;
    }

    if( (m_PrintParams.m_PrintScale > 1.0)          //  scale > 1 -> Recadrage
       || (m_PrintParams.m_PrintScale == 0) )       //  fit in page
    {
        DrawOffset += bbbox.Centre();
    }

    if( m_PrintParams.m_PageSetupData )
    {
        wxSize pagesize;

        pagesize.x = int( pageSizeIU.x / userscale );
        pagesize.y = int( pageSizeIU.y / userscale );

        FitThisSizeToPageMargins( pagesize, *m_PrintParams.m_PageSetupData );
    }

    // Compute Accurate scale 1
    if( userscale == 1.0 )
    {
        // We want a 1:1 scale and margins for printing
        MapScreenSizeToPaper();
        int w, h;
        GetPPIPrinter( &w, &h );
        double accurate_Xscale = ( (double) ( DrawZoom * w ) ) / (double) PCB_INTERNAL_UNIT;
        double accurate_Yscale = ( (double) ( DrawZoom * h ) ) / (double) PCB_INTERNAL_UNIT;

        if( IsPreview() )  // Scale must take in account the DC size in Preview
        {
            // Get the size of the DC in pixels
            wxSize       PlotAreaSize;
            dc->GetSize( &PlotAreaSize.x, &PlotAreaSize.y );
            GetPageSizePixels( &w, &h );
            accurate_Xscale *= PlotAreaSize.x;
            accurate_Xscale /= (double) w;
            accurate_Yscale *= PlotAreaSize.y;
            accurate_Yscale /= (double) h;
        }
        accurate_Xscale *= m_PrintParams.m_XScaleAdjust;
        accurate_Yscale *= m_PrintParams.m_YScaleAdjust;
        // Fine scale adjust
        dc->SetUserScale( accurate_Xscale, accurate_Yscale );
    }

    // Get the final size of the DC in pixels
    wxSize       PlotAreaSizeInPixels;
    dc->GetSize( &PlotAreaSizeInPixels.x, &PlotAreaSizeInPixels.y );
    double scalex, scaley;
    dc->GetUserScale(&scalex, &scaley);
    wxSize PlotAreaSizeInUserUnits;
    PlotAreaSizeInUserUnits.x = (int) (PlotAreaSizeInPixels.x/scalex);
    PlotAreaSizeInUserUnits.y = (int) (PlotAreaSizeInPixels.y/scaley);

    /* In some cases the plot origin is the centre of the page
     *  when:
     *  - Asked
     *  - scale > 1
     *  - fit in page
     */
    if( m_PrintParams.m_ForceCentered
       || (m_PrintParams.m_PrintScale > 1.0)        //  scale > 1
       || (m_PrintParams.m_PrintScale == 0) )       //  fit in page
    {
        DrawOffset.x -= PlotAreaSizeInUserUnits.x / 2;
        DrawOffset.y -= PlotAreaSizeInUserUnits.y / 2;
    }

    screen->m_DrawOrg = DrawOffset;

    GRResetPenAndBrush( dc );

    if( m_PrintParams.m_Print_Black_and_White )
        GRForceBlackPen( true );

    EDA_DRAW_PANEL* panel = m_Parent->GetCanvas();
    EDA_RECT        tmp   = *panel->GetClipBox();

    // Set clip box to the max size
    #define MAX_VALUE (INT_MAX/2)   // MAX_VALUE is the max we can use in an integer
                                    // and that allows calculations without overflow
    panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );

    m_Parent->GetScreen()->m_IsPrinting = true;
    int bg_color = g_DrawBgColor;

    if( m_PrintParams.m_Print_Sheet_Ref )
        m_Parent->TraceWorkSheet( dc, screen, m_PrintParams.m_PenDefaultSize );

    if( printMirror )
    {
        // To plot mirror, we reverse the y axis, and modify the plot y origin
        dc->SetAxisOrientation( true, true );

        if( userscale < 1.0 )
            scaley /= userscale;

        /* Plot offset y is moved by the y plot area size in order to have
         * the old draw area in the new draw area, because the draw origin has not moved
         * (this is the upper left corner) but the Y axis is reversed, therefore the plotting area
         * is the y coordinate values from  - PlotAreaSize.y to 0 */
        int y_dc_offset = PlotAreaSizeInPixels.y;
        y_dc_offset = (int) ( ( double ) y_dc_offset * userscale );
        dc->SetDeviceOrigin( 0, y_dc_offset );
        int ysize = (int) ( PlotAreaSizeInPixels.y / scaley );
        DrawOffset.y += ysize;

        /* in order to keep the board position in the sheet
         * (when user scale <= 1) the y offset in moved by the distance between
         * the middle of the page and the middle of the board
         * This is equivalent to put the mirror axis to the board centre
         * for scales > 1, the DrawOffset was already computed to have the board centre
         * to the middle of the page.
         */
        wxPoint pcb_centre = bbbox.Centre();

        if( userscale <= 1.0 )
            DrawOffset.y += pcb_centre.y - (ysize / 2);

        dc->SetLogicalOrigin( screen->m_DrawOrg.x, screen->m_DrawOrg.y );
        panel->SetClipBox( EDA_RECT( wxPoint( -MAX_VALUE/2, -MAX_VALUE/2 ),
                                     panel->GetClipBox()->GetSize() ) );
    }

    g_DrawBgColor = WHITE;

    /* when printing in color mode, we use the graphic OR mode that gives the same look as the screen
     * But because the background is white when printing, we must use a trick:
     * In order to plot on a white background in OR mode we must:
     * 1 - Plot all items in black, this creates a local black backgroud
     * 2 - Plot in OR mode on black "local" background
     */
    if( !m_PrintParams.m_Print_Black_and_White )
    {   // Creates a "local" black background
        GRForceBlackPen( true );
        m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams );
        GRForceBlackPen( false );
    }

    m_Parent->PrintPage( dc, m_PrintParams.m_PrintMaskLayer, printMirror, &m_PrintParams );

    g_DrawBgColor = bg_color;
    m_Parent->GetScreen()->m_IsPrinting = false;
    panel->SetClipBox( tmp );

    GRForceBlackPen( false );

    screen->m_StartVisu = tmp_startvisu;
    screen->m_DrawOrg   = old_org;
    screen->SetZoom( tmpzoom );
}