bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery ) { if( GetBoard() == NULL ) return false; if( aQuery && GetScreen()->IsModify() ) { if( GetBoard()->m_Modules ) { if( !IsOK( this, _( "Current Footprint will be lost and this operation cannot be undone. Continue ?" ) ) ) return false; } } // Clear undo and redo lists GetScreen()->ClearUndoRedoList(); // Delete the current footprint GetBoard()->m_Modules.DeleteAll(); // init pointeurs et variables GetScreen()->GetFileName().Empty(); SetCurItem( NULL ); // preserve grid size accross call to InitDataPoints() // wxRealPoint gridsize = GetScreen()->GetGridSize(); GetScreen()->InitDataPoints( GetPageSizeIU() ); // GetScreen()->SetGrid( gridsize ); Zoom_Automatique( false ); return true; }
void FOOTPRINT_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMaskLayer, bool aPrintMirrorMode, void * aData) { const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0; int defaultPenSize = Millimeter2iu( 0.2 ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions(); DISPLAY_OPTIONS save_opt; PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE; if( printParameters ) defaultPenSize = printParameters->m_PenDefaultSize; save_opt = *displ_opts; displ_opts->m_ContrastModeDisplay = false; displ_opts->m_DisplayPadFill = true; displ_opts->m_DisplayViaFill = true; displ_opts->m_DisplayPadNum = false; bool nctmp = GetBoard()->IsElementVisible(NO_CONNECTS_VISIBLE); GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, false); displ_opts->m_DisplayPadIsol = false; displ_opts->m_DisplayModEdgeFill = FILLED; displ_opts->m_DisplayModTextFill = FILLED; displ_opts->m_DisplayPcbTrackFill = true; displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE; displ_opts->m_DisplayDrawItemsFill = FILLED; displ_opts->m_DisplayZonesMode = 0; displ_opts->m_DisplayNetNamesMode = 0; m_canvas->SetPrintMirrored( aPrintMirrorMode ); // Draw footprints, this is done at last in order to print the pad holes in // white after the tracks and zones int tmp = D_PAD::m_PadSketchModePenSize; D_PAD::m_PadSketchModePenSize = defaultPenSize; wxSize pageSizeIU = GetPageSizeIU() / 2; wxPoint offset( pageSizeIU.x, pageSizeIU.y ); for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) { module->Move( offset ); Print_Module( m_canvas, aDC, module, drawmode, aPrintMaskLayer, drillShapeOpt ); module->Move( -offset ); } D_PAD::m_PadSketchModePenSize = tmp; m_canvas->SetPrintMirrored( false ); *displ_opts = save_opt; GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, nctmp ); }
/** * Function Clear_Pcb * delete all and reinitialize the current board * @param aQuery = true to prompt user for confirmation, false to initialize silently */ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery ) { if( GetBoard() == NULL ) return false; if( aQuery ) { if( GetBoard()->m_Drawings || GetBoard()->m_Modules || GetBoard()->m_Track || GetBoard()->m_Zone ) { if( !IsOK( this, _( "Current Board will be lost and this operation cannot be undone. Continue ?" ) ) ) return false; } } // Clear undo and redo lists because we want a full deletion GetScreen()->ClearUndoRedoList(); /* Items visibility flags will be set becuse a new board will be created. * Grid and ratsnest can be left to their previous state */ bool showGrid = IsElementVisible( GRID_VISIBLE ); bool showRats = IsElementVisible( RATSNEST_VISIBLE ); // delete the old BOARD and create a new BOARD so that the default // layer names are put into the BOARD. SetBoard( new BOARD() ); SetElementVisibility( GRID_VISIBLE, showGrid ); SetElementVisibility( RATSNEST_VISIBLE, showRats ); SetCurItem( NULL ); // clear filename, to avoid overwriting an old file GetScreen()->GetFileName().Empty(); // preserve grid size accross call to InitDataPoints() // wxRealPoint gridsize = GetScreen()->GetGridSize(); GetScreen()->InitDataPoints( GetPageSizeIU() ); // GetScreen()->SetGrid( gridsize ); GetBoard()->ResetHighLight(); // Enable all layers (SetCopperLayerCount() will adjust the copper layers enabled) GetBoard()->SetEnabledLayers( ALL_LAYERS ); // Default copper layers count set to 2: double layer board GetBoard()->SetCopperLayerCount( 2 ); // Update display: GetBoard()->SetVisibleLayers( ALL_LAYERS ); ReFillLayerWidget(); Zoom_Automatique( false ); return true; }
EDA_RECT PCB_BASE_FRAME::GetBoardBoundingBox( bool aBoardEdgesOnly ) const { wxASSERT( m_Pcb ); EDA_RECT area = m_Pcb->ComputeBoundingBox( aBoardEdgesOnly ); if( area.GetWidth() == 0 && area.GetHeight() == 0 ) { wxSize pageSize = GetPageSizeIU(); if( m_showBorderAndTitleBlock ) { area.SetOrigin( 0, 0 ); area.SetEnd( pageSize.x, pageSize.y ); } else { area.SetOrigin( -pageSize.x / 2, -pageSize.y / 2 ); area.SetEnd( pageSize.x / 2, pageSize.y / 2 ); } } return area; }
bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // This is for python: if( aFileSet.size() != 1 ) { UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ ); DisplayError( this, msg ); return false; } wxString fullFileName( aFileSet[0] ); // We insist on caller sending us an absolute path, if it does not, we say it's a bug. wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) ); std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName ); if( !lockFile ) { wxString msg = wxString::Format( _( "PCB file \"%s\" is already open." ), fullFileName ); DisplayError( this, msg ); return false; } if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) { if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ), [&]()->bool { return SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); } ) ) { return false; } } // Release the lock file, until the new file is actually loaded ReleaseFile(); wxFileName pro = fullFileName; pro.SetExt( ProjectFileExtension ); bool is_new = !wxFileName::IsFileReadable( fullFileName ); // If its a non-existent schematic and caller thinks it exists if( is_new && !( aCtl & KICTL_CREATE ) ) { // notify user that fullFileName does not exist, ask if user wants to create it. wxString ask = wxString::Format( _( "PCB \"%s\" does not exist. Do you wish to create it?" ), fullFileName ); if( !IsOK( this, ask ) ) return false; } Clear_Pcb( false ); // pass false since we prompted above for a modified board IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP; if( !converted ) { // PROJECT::SetProjectFullName() is an impactful function. It should only be // called under carefully considered circumstances. // The calling code should know not to ask me here to change projects unless // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); // load project settings before BOARD LoadProjectSettings(); } if( is_new ) { OnModify(); } else { BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); // This will rename the file if there is an autosave and the user want to recover CheckForAutoSaveFile( fullFileName ); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; #if USE_INSTRUMENTATION // measure the time to load a BOARD. unsigned startTime = GetRunningMicroSecs(); #endif loadedBoard = pi->Load( fullFileName, NULL, &props ); #if USE_INSTRUMENTATION unsigned stopTime = GetRunningMicroSecs(); printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); #endif } catch( const IO_ERROR& ioe ) { if( ioe.Problem() != wxT( "CANCEL" ) ) { wxString msg = wxString::Format( _( "Error loading board file:\n%s" ), fullFileName ); DisplayErrorMessage( this, msg, ioe.What() ); } return false; } // 6.0 TODO: some settings didn't make it into the board file in 5.1 so as not to // change the file format. For 5.1 we must copy them across from the config-initialized // board. BOARD_DESIGN_SETTINGS& bds = loadedBoard->m_designSettings; BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings(); bds.m_RequireCourtyards = configBds.m_RequireCourtyards; bds.m_ProhibitOverlappingCourtyards = configBds.m_ProhibitOverlappingCourtyards; bds.m_HoleToHoleMin = configBds.m_HoleToHoleMin; bds.m_LineThickness[LAYER_CLASS_OTHERS] = configBds.m_LineThickness[LAYER_CLASS_OTHERS]; bds.m_TextSize[LAYER_CLASS_OTHERS] = configBds.m_TextSize[LAYER_CLASS_OTHERS]; bds.m_TextThickness[LAYER_CLASS_OTHERS] = configBds.m_TextThickness[LAYER_CLASS_OTHERS]; std::copy( configBds.m_TextItalic, configBds.m_TextItalic + 4, bds.m_TextItalic ); std::copy( configBds.m_TextUpright, configBds.m_TextUpright + 4, bds.m_TextUpright ); bds.m_DiffPairDimensionsList = configBds.m_DiffPairDimensionsList; bds.m_CopperEdgeClearance = configBds.m_CopperEdgeClearance; SetBoard( loadedBoard ); // we should not ask PLUGINs to do these items: loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); // If this is a legacy board then we set the copper edge clearance to 1/2 the edge-cut // line width (which was a legacy kludge for implementing edge clearances). if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) ) bds.SetCopperEdgeClearance( inferLegacyEdgeClearance( loadedBoard ) ); if( loadedBoard->IsModified() ) OnModify(); else GetScreen()->ClrModify(); if( pluginType == IO_MGR::LEGACY && loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) { DisplayInfoMessage( this, _( "This file was created by an older version of Pcbnew.\n" "It will be stored in the new file format when you save this file again." ) ); } } { wxFileName fn = fullFileName; if( converted ) fn.SetExt( PcbFileExtension ); wxString fname = fn.GetFullPath(); fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); GetBoard()->SetFileName( fname ); } // Lock the file newly opened: m_file_checker.reset( lockFile.release() ); if( !converted ) UpdateFileHistory( GetBoard()->GetFileName() ); // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; // Select netclass Default as current netclass (it always exists) SetCurrentNetClass( NETCLASS::Default ); // Rebuild list of nets (full ratsnest rebuild) Compile_Ratsnest( NULL, true ); GetBoard()->BuildConnectivity(); onBoardLoaded(); // Refresh the 3D view, if any EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->NewDisplay(); #if 0 && defined(DEBUG) // Output the board object tree to stdout, but please run from command prompt: GetBoard()->Show( 0, std::cout ); #endif // from EDA_APPL which was first loaded BOARD only: { /* For an obscure reason the focus is lost after loading a board file * when starting up the process. * (seems due to the recreation of the layer manager after loading the file) * Give focus to main window and Drawpanel * must be done for these 2 windows (for an obscure reason ...) * Linux specific * This is more a workaround than a fix. */ SetFocus(); GetCanvas()->SetFocus(); } return true; }
bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // This is for python: if( aFileSet.size() != 1 ) { UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ ); DisplayError( this, msg ); return false; } wxString fullFileName( aFileSet[0] ); // We insist on caller sending us an absolute path, if it does not, we say it's a bug. wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "bug in single_top.cpp or project manager." ) ); if( !LockFile( fullFileName ) ) { wxString msg = wxString::Format( _( "PCB file '%s' is already open." ), GetChars( fullFileName ) ); DisplayError( this, msg ); return false; } if( GetScreen()->IsModify() ) { int response = YesNoCancelDialog( this, _( "The current board has been modified. Do you wish to save the changes?" ), wxEmptyString, _( "Save and Load" ), _( "Load Without Saving" ) ); if( response == wxID_CANCEL ) return false; else if( response == wxID_YES ) SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); else { // response == wxID_NO, fall thru } } wxFileName pro = fullFileName; pro.SetExt( ProjectFileExtension ); bool is_new = !wxFileName::IsFileReadable( fullFileName ); // If its a non-existent schematic and caller thinks it exists if( is_new && !( aCtl & KICTL_CREATE ) ) { // notify user that fullFileName does not exist, ask if user wants to create it. wxString ask = wxString::Format( _( "Board '%s' does not exist. Do you wish to create it?" ), GetChars( fullFileName ) ); if( !IsOK( this, ask ) ) return false; } Clear_Pcb( false ); // pass false since we prompted above for a modified board IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD; if( !converted ) { // PROJECT::SetProjectFullName() is an impactful function. It should only be // called under carefully considered circumstances. // The calling code should know not to ask me here to change projects unless // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); // load project settings before BOARD LoadProjectSettings(); } if( is_new ) { OnModify(); } else { BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; #if USE_INSTRUMENTATION // measure the time to load a BOARD. unsigned startTime = GetRunningMicroSecs(); #endif loadedBoard = pi->Load( fullFileName, NULL, &props ); #if USE_INSTRUMENTATION unsigned stopTime = GetRunningMicroSecs(); printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); #endif } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error loading board.\n%s" ), GetChars( ioe.errorText ) ); DisplayError( this, msg ); return false; } SetBoard( loadedBoard ); // we should not ask PLUGINs to do these items: loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); SetStatusText( wxEmptyString ); BestZoom(); // update the layer names in the listbox ReCreateLayerBox( false ); GetScreen()->ClrModify(); { wxFileName fn = fullFileName; CheckForAutoSaveFile( fullFileName, fn.GetExt() ); } if( pluginType == IO_MGR::LEGACY && loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) { DisplayInfoMessage( this, _( "This file was created by an older version of Pcbnew.\n" "It will be stored in the new file format when you save this file again." ) ); } } { wxFileName fn = fullFileName; if( converted ) fn.SetExt( PcbFileExtension ); wxString fname = fn.GetFullPath(); fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); GetBoard()->SetFileName( fname ); } UpdateTitle(); if( !converted ) UpdateFileHistory( GetBoard()->GetFileName() ); // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; // Update info shown by the horizontal toolbars SetCurrentNetClass( NETCLASS::Default ); ReFillLayerWidget(); ReCreateLayerBox(); // upate the layer widget to match board visibility states, both layers and render columns. syncLayerVisibilities(); syncLayerWidgetLayer(); syncRenderStates(); // Update the tracks / vias available sizes list: ReCreateAuxiliaryToolbar(); // Update the RATSNEST items, which were not loaded at the time // BOARD::SetVisibleElements() was called from within any PLUGIN. // See case RATSNEST_VISIBLE: in BOARD::SetElementVisibility() GetBoard()->SetVisibleElements( GetBoard()->GetVisibleElements() ); // Display the loaded board: Zoom_Automatique( false ); // Compile ratsnest and displays net info { wxBusyCursor dummy; // Displays an Hourglass while building connectivity Compile_Ratsnest( NULL, true ); GetBoard()->GetRatsnest()->ProcessBoard(); } SetMsgPanel( GetBoard() ); // Refresh the 3D view, if any if( m_Draw3DFrame ) m_Draw3DFrame->NewDisplay(); #if 0 && defined(DEBUG) // Output the board object tree to stdout, but please run from command prompt: GetBoard()->Show( 0, std::cout ); #endif // from EDA_APPL which was first loaded BOARD only: { /* For an obscure reason the focus is lost after loading a board file * when starting up the process. * (seems due to the recreation of the layer manager after loading the file) * Give focus to main window and Drawpanel * must be done for these 2 windows (for an obscure reason ...) * Linux specific * This is more a workaround than a fix. */ SetFocus(); GetCanvas()->SetFocus(); } return true; }
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) : PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Library Browser" ), wxDefaultPosition, wxDefaultSize, aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ? KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT : KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintViewerFrameName() ) { wxASSERT( aFrameType==FRAME_PCB_MODULE_VIEWER || aFrameType==FRAME_PCB_MODULE_VIEWER_MODAL ); if( aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ) SetModal( true ); wxAcceleratorTable table( DIM( accels ), accels ); m_FrameName = GetFootprintViewerFrameName(); m_configPath = wxT( "FootprintViewer" ); m_showAxis = true; // true to draw axis. // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( modview_icon_xpm ) ); SetIcon( icon ); m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr; m_libList = new wxListBox( this, ID_MODVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); SetBoard( new BOARD() ); // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); GetScreen()->m_Center = true; // Center coordinate origins on screen. LoadSettings( config() ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); ReCreateHToolbar(); ReCreateVToolbar(); ReCreateLibraryList(); UpdateTitle(); // If a footprint was previously loaded, reload it if( getCurNickname().size() && getCurFootprintName().size() ) { FPID id; id.SetLibNickname( getCurNickname() ); id.SetFootprintName( getCurFootprintName() ); GetBoard()->Add( loadFootprint( id ) ); } if( m_canvas ) m_canvas->SetAcceleratorTable( table ); m_auimgr.SetManagedWindow( this ); wxSize minsize(100,-1); // Min size of list boxes // Main toolbar is initially docked at the top of the main window and dockable on any side. // The close button is disable because the footprint viewer has no main menu to re-enable it. // The tool bar will only be dockable on the top or bottom of the main frame window. This is // most likely due to the fact that the other windows are not dockable and are preventing the // tool bar from docking on the right and left. wxAuiPaneInfo toolbarPaneInfo; toolbarPaneInfo.Name( wxT( "m_mainToolBar" ) ).ToolbarPane().Top().CloseButton( false ); EDA_PANEINFO info; info.InfoToolbarPane(); EDA_PANEINFO mesg; mesg.MessageToolbarPane(); // Manage main toolbar, top pane m_auimgr.AddPane( m_mainToolBar, toolbarPaneInfo ); // Manage the list of libraries, left pane. m_auimgr.AddPane( m_libList, wxAuiPaneInfo( info ).Name( wxT( "m_libList" ) ) .Left().Row( 1 ).MinSize( minsize ) ); // Manage the list of footprints, center pane. m_auimgr.AddPane( m_footprintList, wxAuiPaneInfo( info ).Name( wxT( "m_footprintList" ) ) .Left().Row( 2 ).MinSize( minsize ) ); // Manage the draw panel, right pane. m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); // Manage the message panel, bottom pane. m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() ); if( !m_perspective.IsEmpty() ) { // Restore last saved sizes, pos and other params // However m_mainToolBar size cannot be set to its last saved size // because the actual size change depending on the way modview was called: // the tool to export the current footprint exist or not. // and the saved size is not always OK // the trick is to get the default toolbar size, and set the size after // calling LoadPerspective wxSize tbsize = m_mainToolBar->GetSize(); m_auimgr.LoadPerspective( m_perspective, false ); m_auimgr.GetPane( m_mainToolBar ).BestSize( tbsize ); } #if 0 // no. // Set min size (overwrite params read in LoadPerspective(), if any) m_auimgr.GetPane( m_libList ).MinSize( minsize ); m_auimgr.GetPane( m_footprintList ).MinSize( minsize ); #endif // after changing something to the aui manager, // call Update()() to reflect the changes m_auimgr.Update(); // Now Drawpanel is sized, we can use BestZoom to show the component (if any) #ifdef USE_WX_GRAPHICS_CONTEXT GetScreen()->SetZoom( BestZoom() ); #else Zoom_Automatique( false ); #endif Show( true ); }
void EDA_DRAW_FRAME::AdjustScrollBars( const wxPoint& aCenterPositionIU ) { BASE_SCREEN* screen = GetScreen(); if( !screen || !m_canvas ) return; double scale = screen->GetScalingFactor(); wxLogTrace( traceScrollSettings, wxT( "Center Position = ( %d, %d ), scale = %.10g" ), aCenterPositionIU.x, aCenterPositionIU.y, scale ); // Calculate the portion of the drawing that can be displayed in the // client area at the current zoom level. // visible viewport in device units ~ pixels wxSize clientSizeDU = m_canvas->GetClientSize(); // Size of the client window in IU DSIZE clientSizeIU( clientSizeDU.x / scale, clientSizeDU.y / scale ); // Full drawing or "page" rectangle in internal units DBOX pageRectIU( wxPoint( 0, 0 ), wxSize( GetPageSizeIU().x, GetPageSizeIU().y ) ); // The upper left corner of the client rectangle in internal units. double xIU = aCenterPositionIU.x - clientSizeIU.x / 2.0; double yIU = aCenterPositionIU.y - clientSizeIU.y / 2.0; // If drawn around the center, adjust the client rectangle accordingly. if( screen->m_Center ) { // half page offset. xIU += pageRectIU.GetWidth() / 2.0; yIU += pageRectIU.GetHeight() / 2.0; } DBOX clientRectIU( wxPoint( xIU, yIU ), wxSize( clientSizeIU.x, clientSizeIU.y ) ); wxPoint centerPositionIU; // put "int" limits on the clientRect if( clientRectIU.GetLeft() < VIRT_MIN ) clientRectIU.MoveLeftTo( VIRT_MIN ); if( clientRectIU.GetTop() < VIRT_MIN ) clientRectIU.MoveTopTo( VIRT_MIN ); if( clientRectIU.GetRight() > VIRT_MAX ) clientRectIU.MoveRightTo( VIRT_MAX ); if( clientRectIU.GetBottom() > VIRT_MAX ) clientRectIU.MoveBottomTo( VIRT_MAX ); centerPositionIU.x = KiROUND( clientRectIU.GetX() + clientRectIU.GetWidth() / 2 ); centerPositionIU.y = KiROUND( clientRectIU.GetY() + clientRectIU.GetHeight() / 2 ); if( screen->m_Center ) { centerPositionIU.x -= KiROUND( pageRectIU.GetWidth() / 2.0 ); centerPositionIU.y -= KiROUND( pageRectIU.GetHeight() / 2.0 ); } DSIZE virtualSizeIU; if( pageRectIU.GetLeft() < clientRectIU.GetLeft() && pageRectIU.GetRight() > clientRectIU.GetRight() ) { virtualSizeIU.x = pageRectIU.GetSize().x; } else { double pageCenterX = pageRectIU.GetX() + ( pageRectIU.GetWidth() / 2 ); double clientCenterX = clientRectIU.GetX() + ( clientRectIU.GetWidth() / 2 ); if( clientRectIU.GetWidth() > pageRectIU.GetWidth() ) { if( pageCenterX > clientCenterX ) virtualSizeIU.x = ( pageCenterX - clientRectIU.GetLeft() ) * 2; else if( pageCenterX < clientCenterX ) virtualSizeIU.x = ( clientRectIU.GetRight() - pageCenterX ) * 2; else virtualSizeIU.x = clientRectIU.GetWidth(); } else { if( pageCenterX > clientCenterX ) virtualSizeIU.x = pageRectIU.GetWidth() + ( (pageRectIU.GetLeft() - clientRectIU.GetLeft() ) * 2 ); else if( pageCenterX < clientCenterX ) virtualSizeIU.x = pageRectIU.GetWidth() + ( (clientRectIU.GetRight() - pageRectIU.GetRight() ) * 2 ); else virtualSizeIU.x = pageRectIU.GetWidth(); } } if( pageRectIU.GetTop() < clientRectIU.GetTop() && pageRectIU.GetBottom() > clientRectIU.GetBottom() ) { virtualSizeIU.y = pageRectIU.GetSize().y; } else { double pageCenterY = pageRectIU.GetY() + ( pageRectIU.GetHeight() / 2 ); double clientCenterY = clientRectIU.GetY() + ( clientRectIU.GetHeight() / 2 ); if( clientRectIU.GetHeight() > pageRectIU.GetHeight() ) { if( pageCenterY > clientCenterY ) virtualSizeIU.y = ( pageCenterY - clientRectIU.GetTop() ) * 2; else if( pageCenterY < clientCenterY ) virtualSizeIU.y = ( clientRectIU.GetBottom() - pageCenterY ) * 2; else virtualSizeIU.y = clientRectIU.GetHeight(); } else { if( pageCenterY > clientCenterY ) virtualSizeIU.y = pageRectIU.GetHeight() + ( ( pageRectIU.GetTop() - clientRectIU.GetTop() ) * 2 ); else if( pageCenterY < clientCenterY ) virtualSizeIU.y = pageRectIU.GetHeight() + ( ( clientRectIU.GetBottom() - pageRectIU.GetBottom() ) * 2 ); else virtualSizeIU.y = pageRectIU.GetHeight(); } } // put "int" limits on the virtualSizeIU virtualSizeIU.x = std::min( virtualSizeIU.x, MAX_AXIS ); virtualSizeIU.y = std::min( virtualSizeIU.y, MAX_AXIS ); if( screen->m_Center ) { screen->m_DrawOrg.x = -KiROUND( virtualSizeIU.x / 2.0 ); screen->m_DrawOrg.y = -KiROUND( virtualSizeIU.y / 2.0 ); } else { screen->m_DrawOrg.x = -KiROUND( ( virtualSizeIU.x - pageRectIU.GetWidth() ) / 2.0 ); screen->m_DrawOrg.y = -KiROUND( ( virtualSizeIU.y - pageRectIU.GetHeight() ) / 2.0 ); } /* Always set scrollbar pixels per unit to 1 unless you want the zoom * around cursor to jump around. This reported problem occurs when the * zoom point is not on a pixel per unit increment. If you set the * pixels per unit to 10, you have potential for the zoom point to * jump around +/-5 pixels from the nearest grid point. */ screen->m_ScrollPixelsPerUnitX = screen->m_ScrollPixelsPerUnitY = 1; // Number of scroll bar units for the given zoom level in device units. double unitsX = virtualSizeIU.x * scale; double unitsY = virtualSizeIU.y * scale; // Calculate the scroll bar position in internal units to place the // center position at the center of client rectangle. SetScrollCenterPosition( centerPositionIU ); double posX = centerPositionIU.x - clientRectIU.GetWidth() / 2.0 - screen->m_DrawOrg.x; double posY = centerPositionIU.y - clientRectIU.GetHeight() / 2.0 - screen->m_DrawOrg.y; // Convert scroll bar position to device units. posX = KiROUND( posX * scale ); posY = KiROUND( posY * scale ); if( posX < 0 ) { wxLogTrace( traceScrollSettings, wxT( "Required scroll bar X position %.10g" ), posX ); posX = 0; } if( posX > unitsX ) { wxLogTrace( traceScrollSettings, wxT( "Required scroll bar X position %.10g" ), posX ); posX = unitsX; } if( posY < 0 ) { wxLogTrace( traceScrollSettings, wxT( "Required scroll bar Y position %.10g" ), posY ); posY = 0; } if( posY > unitsY ) { wxLogTrace( traceScrollSettings, wxT( "Required scroll bar Y position %.10g" ), posY ); posY = unitsY; } screen->m_ScrollbarPos = wxPoint( KiROUND( posX ), KiROUND( posY ) ); screen->m_ScrollbarNumber = wxSize( KiROUND( unitsX ), KiROUND( unitsY ) ); wxLogTrace( traceScrollSettings, wxT( "Drawing = (%.10g, %.10g), Client = (%.10g, %.10g), Offset = (%d, %d), SetScrollbars(%d, %d, %d, %d, %d, %d)" ), virtualSizeIU.x, virtualSizeIU.y, clientSizeIU.x, clientSizeIU.y, screen->m_DrawOrg.x, screen->m_DrawOrg.y, screen->m_ScrollPixelsPerUnitX, screen->m_ScrollPixelsPerUnitY, screen->m_ScrollbarNumber.x, screen->m_ScrollbarNumber.y, screen->m_ScrollbarPos.x, screen->m_ScrollbarPos.y ); bool noRefresh = true; m_canvas->SetScrollbars( screen->m_ScrollPixelsPerUnitX, screen->m_ScrollPixelsPerUnitY, screen->m_ScrollbarNumber.x, screen->m_ScrollbarNumber.y, screen->m_ScrollbarPos.x, screen->m_ScrollbarPos.y, noRefresh ); }
FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) : PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Wizard" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT, FOOTPRINT_WIZARD_FRAME_NAME ) { wxASSERT( aFrameType==FRAME_PCB_FOOTPRINT_WIZARD_MODAL ); if( aFrameType == FRAME_PCB_FOOTPRINT_WIZARD_MODAL ) SetModal( true ); wxAcceleratorTable table( ACCEL_TABLE_CNT, accels ); m_FrameName = FOOTPRINT_WIZARD_FRAME_NAME; m_configPath = wxT( "FootprintWizard" ); m_showAxis = true; // true to draw axis. // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( module_wizard_xpm) ); SetIcon( icon ); m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr; m_wizardName.Empty(); SetBoard( new BOARD() ); // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); GetScreen()->m_Center = true; // Center coordinate origins on screen. LoadSettings( config() ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); ReCreateHToolbar(); ReCreateVToolbar(); // Creates the parameter pages list m_pageList = new wxListBox( this, ID_FOOTPRINT_WIZARD_PAGE_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); // Creates the The list of parameters for the current parameter page m_parameterGrid = new wxGrid( this, ID_FOOTPRINT_WIZARD_PARAMETER_LIST ); m_parameterGrid->CreateGrid( 1, 3 ); // Columns m_parameterGrid->SetColLabelValue( 0, _( "Parameter" ) ); m_parameterGrid->SetColLabelValue( 1, _( "Value" ) ); m_parameterGrid->SetColLabelValue( 2, _( "Units" ) ); m_parameterGrid->SetColLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTRE ); m_parameterGrid->AutoSizeColumns(); ReCreatePageList(); DisplayWizardInfos(); if( m_canvas ) m_canvas->SetAcceleratorTable( table ); m_auimgr.SetManagedWindow( this ); EDA_PANEINFO horiztb; horiztb.HorizontalToolbarPane(); EDA_PANEINFO info; info.InfoToolbarPane(); EDA_PANEINFO mesg; mesg.MessageToolbarPane(); // Manage main toolbal m_auimgr.AddPane( m_mainToolBar, wxAuiPaneInfo( horiztb ). Name( wxT ("m_mainToolBar" ) ).Top().Row( 0 ) ); // Manage the left window (list of parameter pages) EDA_PANEINFO paneList; paneList.InfoToolbarPane().Name( wxT( "m_pageList" ) ).Left().Row( 0 ); m_auimgr.AddPane( m_pageList, wxAuiPaneInfo( paneList ) ); // Manage the parameters grid editor for the current parameter page EDA_PANEINFO panePrms; panePrms.InfoToolbarPane().Name( wxT( "m_parameterGrid" ) ).Left().Row( 1 ); m_auimgr.AddPane( m_parameterGrid, wxAuiPaneInfo( panePrms ) ); // Manage the draw panel m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); // Manage the message panel m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(1) ); // Gives a min size and the last saved size to left windows m_auimgr.GetPane( m_pageList ).MinSize( wxSize(60, -1 ) ); m_auimgr.GetPane( m_pageList ).BestSize( wxSize(m_pageListWidth, -1) ); m_auimgr.GetPane( m_parameterGrid ).MinSize( wxSize( 120, -1 ) ); m_auimgr.GetPane( m_parameterGrid ).BestSize( wxSize(m_parameterGridWidth, -1) ); m_auimgr.Update(); // Now Drawpanel is sized, we can use BestZoom to show the component (if any) #ifdef USE_WX_GRAPHICS_CONTEXT GetScreen()->SetZoom( BestZoom() ); #else Zoom_Automatique( false ); #endif Show( true ); this->SelectFootprintWizard(); }
bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl ) { IO_MGR::PCB_FILE_T pluginType = plugin_type( aFullFileName, aCtl ); PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); // keep trace of existing items, in order to know what are the new items // (for undo command for instance) // Tracks are inserted, not append, so mark existing tracks to know what are // the new tracks for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() ) track->SetFlags( FLAG0 ); // Other items are append to the item list, so keep trace to the // last existing item is enough MODULE* module = GetBoard()->m_Modules.GetLast(); BOARD_ITEM* drawing = GetBoard()->m_Drawings.GetLast(); int zonescount = GetBoard()->GetAreaCount(); // Keep also the count of copper layers, because we can happen boards // with different copper layers counts, // and the enabled layers int initialCopperLayerCount = GetBoard()->GetCopperLayerCount(); LSET initialEnabledLayers = GetBoard()->GetEnabledLayers(); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; GetDesignSettings().m_NetClasses.Clear(); pi->Load( aFullFileName, GetBoard(), &props ); } catch( const IO_ERROR& ioe ) { for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() ) track->ClearFlags( FLAG0 ); wxString msg = wxString::Format( _( "Error loading board.\n%s" ), GetChars( ioe.What() ) ); DisplayError( this, msg ); return false; } // Now prepare a block move command to place the new items, and // prepare the undo command. BLOCK_SELECTOR& blockmove = GetScreen()->m_BlockLocate; HandleBlockBegin( NULL, BLOCK_PRESELECT_MOVE, wxPoint( 0, 0) ); PICKED_ITEMS_LIST& blockitemsList = blockmove.GetItems(); PICKED_ITEMS_LIST undoListPicker; ITEM_PICKER picker( NULL, UR_NEW ); EDA_RECT bbox; // the new items bounding box, for block move bool bboxInit = true; // true until the bounding box is initialized for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() ) { if( track->GetFlags() & FLAG0 ) { track->ClearFlags( FLAG0 ); continue; } track->SetFlags( IS_MOVED ); picker.SetItem( track ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); if( bboxInit ) bbox = track->GetBoundingBox(); else bbox.Merge( track->GetBoundingBox() ); bboxInit = false; } if( module ) module = module->Next(); else module = GetBoard()->m_Modules; for( ; module; module = module->Next() ) { module->SetFlags( IS_MOVED ); picker.SetItem( module ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); if( bboxInit ) bbox = module->GetBoundingBox(); else bbox.Merge( module->GetBoundingBox() ); bboxInit = false; } if( drawing ) drawing = drawing->Next(); else drawing = GetBoard()->m_Drawings; for( ; drawing; drawing = drawing->Next() ) { drawing->SetFlags( IS_MOVED ); picker.SetItem( drawing ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); if( bboxInit ) bbox = drawing->GetBoundingBox(); else bbox.Merge( drawing->GetBoundingBox() ); bboxInit = false; } for( ZONE_CONTAINER* zone = GetBoard()->GetArea( zonescount ); zone; zone = GetBoard()->GetArea( zonescount ) ) { zone->SetFlags( IS_MOVED ); picker.SetItem( zone ); undoListPicker.PushItem( picker ); blockitemsList.PushItem( picker ); zonescount++; if( bboxInit ) bbox = zone->GetBoundingBox(); else bbox.Merge( zone->GetBoundingBox() ); bboxInit = false; } SaveCopyInUndoList( undoListPicker, UR_NEW ); // we should not ask PLUGINs to do these items: int copperLayerCount = GetBoard()->GetCopperLayerCount(); if( copperLayerCount > initialCopperLayerCount ) GetBoard()->SetCopperLayerCount( copperLayerCount ); // Enable all used layers, and make them visible: LSET enabledLayers = GetBoard()->GetEnabledLayers(); enabledLayers |= initialEnabledLayers; GetBoard()->SetEnabledLayers( enabledLayers ); GetBoard()->SetVisibleLayers( enabledLayers ); ReCreateLayerBox(); ReFillLayerWidget(); if( IsGalCanvasActive() ) static_cast<PCB_DRAW_PANEL_GAL*>( GetGalCanvas() )->SyncLayersVisibility( GetBoard() ); GetBoard()->BuildListOfNets(); GetBoard()->SynchronizeNetsAndNetClasses(); SetStatusText( wxEmptyString ); BestZoom(); // Finish block move command: wxPoint cpos = GetNearestGridPosition( bbox.Centre() ); blockmove.SetOrigin( bbox.GetOrigin() ); blockmove.SetSize( bbox.GetSize() ); blockmove.SetLastCursorPosition( cpos ); HandleBlockEnd( NULL ); return true; }
DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent ) : PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME ) { m_showAxis = true; // true to draw axis. // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) ); SetIcon( icon ); SetBoard( new BOARD() ); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); LoadSettings( config() ); // Initialize grid id to a default value if not found in config or incorrect: if( !( GetScreen()->GridExists( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 ) ) ) m_LastGridSizeId = ID_POPUP_GRID_LEVEL_500 - ID_POPUP_GRID_LEVEL_1000; GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 ); // Initialize some display options DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions(); displ_opts->m_DisplayPadIsol = false; // Pad clearance has no meaning here // Track and via clearance has no meaning here. displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE; SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); ReCreateHToolbar(); ReCreateVToolbar(); ReCreateOptToolbar(); m_auimgr.SetManagedWindow( this ); EDA_PANEINFO horiz; horiz.HorizontalToolbarPane(); EDA_PANEINFO vert; vert.VerticalToolbarPane(); EDA_PANEINFO mesg; mesg.MessageToolbarPane(); m_auimgr.AddPane( m_mainToolBar, wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) ); if( m_drawToolBar ) // Currently, no vertical right toolbar. m_auimgr.AddPane( m_drawToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_drawToolBar" ) ).Right() ); m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DisplayFrame" ) ).CentrePane() ); m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) ); m_auimgr.AddPane( m_optionsToolBar, wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() ); m_auimgr.Update(); Show( true ); }
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) : PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Library Browser" ), wxDefaultPosition, wxDefaultSize, aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ? #ifdef __WINDOWS__ KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP : #else KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT : #endif KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINT_VIEWER_FRAME_NAME ) { wxASSERT( aFrameType==FRAME_PCB_MODULE_VIEWER || aFrameType==FRAME_PCB_MODULE_VIEWER_MODAL ); if( aFrameType == FRAME_PCB_MODULE_VIEWER_MODAL ) SetModal( true ); m_configFrameName = FOOTPRINT_VIEWER_FRAME_NAME; m_showAxis = true; // true to draw axis. // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( modview_icon_xpm ) ); SetIcon( icon ); m_hotkeysDescrList = g_Module_Viewer_Hokeys_Descr; m_libList = new wxListBox( this, ID_MODVIEW_LIB_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); m_footprintList = new wxListBox( this, ID_MODVIEW_FOOTPRINT_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); SetBoard( new BOARD() ); // In viewer, the default net clearance is not known (it depends on the actual board). // So we do not show the default clearance, by setting it to 0 // The footprint or pad specific clearance will be shown GetBoard()->GetDesignSettings().GetDefault()->SetClearance(0); // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); GetScreen()->m_Center = true; // Center coordinate origins on screen. LoadSettings( config() ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); // Menu bar is not mandatory: uncomment/comment the next line // to add/remove the menubar ReCreateMenuBar(); ReCreateHToolbar(); ReCreateVToolbar(); ReCreateLibraryList(); UpdateTitle(); PCB_BASE_FRAME* parentFrame = static_cast<PCB_BASE_FRAME*>( Kiway().Player( FRAME_PCB, true ) ); // Create GAL canvas PCB_DRAW_PANEL_GAL* drawPanel = new PCB_DRAW_PANEL_GAL( this, -1, wxPoint( 0, 0 ), m_FrameSize, parentFrame->GetGalCanvas()->GetBackend() ); SetGalCanvas( drawPanel ); // Create the manager and dispatcher & route draw panel events to the dispatcher m_toolManager = new TOOL_MANAGER; m_toolManager->SetEnvironment( GetBoard(), drawPanel->GetView(), drawPanel->GetViewControls(), this ); m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager ); drawPanel->SetEventDispatcher( m_toolDispatcher ); m_toolManager->RegisterTool( new PCBNEW_CONTROL ); m_toolManager->ResetTools( TOOL_BASE::RUN ); // If a footprint was previously loaded, reload it if( getCurNickname().size() && getCurFootprintName().size() ) { FPID id; id.SetLibNickname( getCurNickname() ); id.SetFootprintName( getCurFootprintName() ); GetBoard()->Add( loadFootprint( id ) ); } drawPanel->DisplayBoard( m_Pcb ); updateView(); m_auimgr.SetManagedWindow( this ); wxSize minsize(100,-1); // Min size of list boxes // Main toolbar is initially docked at the top of the main window and dockable on any side. // The close button is disable because the footprint viewer has no main menu to re-enable it. // The tool bar will only be dockable on the top or bottom of the main frame window. This is // most likely due to the fact that the other windows are not dockable and are preventing the // tool bar from docking on the right and left. wxAuiPaneInfo toolbarPaneInfo; toolbarPaneInfo.Name( wxT( "m_mainToolBar" ) ).ToolbarPane().Top().CloseButton( false ); EDA_PANEINFO info; info.InfoToolbarPane(); EDA_PANEINFO mesg; mesg.MessageToolbarPane(); // Manage main toolbar, top pane m_auimgr.AddPane( m_mainToolBar, toolbarPaneInfo ); // Manage the list of libraries, left pane. m_auimgr.AddPane( m_libList, wxAuiPaneInfo( info ).Name( wxT( "m_libList" ) ) .Left().Row( 1 ).MinSize( minsize ) ); // Manage the list of footprints, center pane. m_auimgr.AddPane( m_footprintList, wxAuiPaneInfo( info ).Name( wxT( "m_footprintList" ) ) .Left().Row( 2 ).MinSize( minsize ) ); // Manage the draw panel, right pane. m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); m_auimgr.AddPane( (wxWindow*) GetGalCanvas(), wxAuiPaneInfo().Name( wxT( "DrawFrameGal" ) ).CentrePane().Hide() ); // Manage the message panel, bottom pane. m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom() ); if( !m_perspective.IsEmpty() ) { // Restore last saved sizes, pos and other params // However m_mainToolBar size cannot be set to its last saved size // because the actual size change depending on the way modview was called: // the tool to export the current footprint exist or not. // and the saved size is not always OK // the trick is to get the default toolbar size, and set the size after // calling LoadPerspective wxSize tbsize = m_mainToolBar->GetSize(); m_auimgr.LoadPerspective( m_perspective, false ); m_auimgr.GetPane( m_mainToolBar ).BestSize( tbsize ); } // after changing something to the aui manager, // call Update()() to reflect the changes m_auimgr.Update(); // Now Drawpanel is sized, we can use BestZoom to show the component (if any) #ifdef USE_WX_GRAPHICS_CONTEXT GetScreen()->SetZoom( BestZoom() ); #else Zoom_Automatique( false ); #endif UseGalCanvas( parentFrame->IsGalCanvasActive() ); if( !IsModal() ) // For modal mode, calling ShowModal() will show this frame { Raise(); // On some window managers, this is needed Show( true ); } } FOOTPRINT_VIEWER_FRAME::~FOOTPRINT_VIEWER_FRAME() { if( m_Draw3DFrame ) m_Draw3DFrame->Destroy(); } void FOOTPRINT_VIEWER_FRAME::OnCloseWindow( wxCloseEvent& Event ) { DBG(printf( "%s:\n", __func__ );) if( IsGalCanvasActive() )
bool PCB_BASE_FRAME::ExportToHpglFile( const wxString& aFullFileName, int aLayer, EDA_DRAW_MODE_T aTraceMode ) { wxSize boardSize; wxPoint boardCenter; bool center = false; double scale; wxPoint offset; LOCALE_IO toggle; FILE* output_file = wxFopen( aFullFileName, wxT( "wt" ) ); if( output_file == NULL ) { return false; } // Compute pen_dim (from g_m_HPGLPenDiam in mils) in pcb units, // with plot scale (if Scale is 2, pen diameter is always g_m_HPGLPenDiam // so apparent pen diam is real pen diam / Scale int pen_diam = wxRound( (g_PcbPlotOptions.m_HPGLPenDiam * U_PCB) / g_PcbPlotOptions.m_PlotScale ); // compute pen_overlay (from g_m_HPGLPenOvr in mils) with plot scale if( g_PcbPlotOptions.m_HPGLPenOvr < 0 ) g_PcbPlotOptions.m_HPGLPenOvr = 0; if( g_PcbPlotOptions.m_HPGLPenOvr >= g_PcbPlotOptions.m_HPGLPenDiam ) g_PcbPlotOptions.m_HPGLPenOvr = g_PcbPlotOptions.m_HPGLPenDiam - 1; int pen_overlay = wxRound( g_PcbPlotOptions.m_HPGLPenOvr * 10.0 / g_PcbPlotOptions.m_PlotScale ); if( g_PcbPlotOptions.m_PlotScale != 1.0 || g_PcbPlotOptions.m_AutoScale ) { // when scale != 1.0 we must calculate the position in page // because actual position has no meaning center = true; } wxSize pageSizeIU = GetPageSizeIU(); // Calculate the center of the PCB EDA_RECT bbbox = GetBoardBoundingBox(); boardSize = bbbox.GetSize(); boardCenter = bbbox.Centre(); if( g_PcbPlotOptions.m_AutoScale ) // Optimum scale { // Fit to 80% of the page double Xscale = ( ( pageSizeIU.x * 0.8 ) / boardSize.x ); double Yscale = ( ( pageSizeIU.y * 0.8 ) / boardSize.y ); scale = MIN( Xscale, Yscale ); } else { scale = g_PcbPlotOptions.m_PlotScale; } // Calculate the page size offset. if( center ) { offset.x = wxRound( (double) boardCenter.x - ( (double) pageSizeIU.x / 2.0 ) / scale ); offset.y = wxRound( (double) boardCenter.y - ( (double) pageSizeIU.y / 2.0 ) / scale ); } else { offset.x = 0; offset.y = 0; } HPGL_PLOTTER* plotter = new HPGL_PLOTTER(); plotter->SetPageSettings( GetPageSettings() ); plotter->set_viewport( offset, scale, g_PcbPlotOptions.m_PlotMirror ); plotter->set_default_line_width( g_PcbPlotOptions.m_PlotLineWidth ); plotter->set_creator( wxT( "PCBNEW-HPGL" ) ); plotter->set_filename( aFullFileName ); plotter->set_pen_speed( g_PcbPlotOptions.m_HPGLPenSpeed ); plotter->set_pen_number( g_PcbPlotOptions.m_HPGLPenNum ); plotter->set_pen_overlap( pen_overlay ); plotter->set_pen_diameter( pen_diam ); plotter->start_plot( output_file ); // The worksheet is not significant with scale!=1... It is with paperscale!=1, anyway if( g_PcbPlotOptions.m_PlotFrameRef && !center ) PlotWorkSheet( plotter, GetScreen() ); Plot_Layer( plotter, aLayer, aTraceMode ); plotter->end_plot(); delete plotter; return true; }
FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType ) : PCB_BASE_FRAME( aKiway, aParent, aFrameType, _( "Footprint Wizard" ), wxDefaultPosition, wxDefaultSize, aParent ? KICAD_DEFAULT_DRAWFRAME_STYLE | MODAL_MODE_EXTRASTYLE : KICAD_DEFAULT_DRAWFRAME_STYLE | wxSTAY_ON_TOP, FOOTPRINT_WIZARD_FRAME_NAME ) { wxASSERT( aFrameType == FRAME_PCB_FOOTPRINT_WIZARD_MODAL ); // This frame is always show modal: SetModal( true ); m_messagesFrame = NULL; // This windows will be created the first time a wizard is loaded m_showAxis = true; // true to draw axis. // Give an icon wxIcon icon; icon.CopyFromBitmap( KiBitmap( module_wizard_xpm) ); SetIcon( icon ); m_hotkeysDescrList = g_Module_Viewer_Hokeys_Descr; m_wizardName.Empty(); SetBoard( new BOARD() ); // Ensure all layers and items are visible: GetBoard()->SetVisibleAlls(); SetScreen( new PCB_SCREEN( GetPageSizeIU() ) ); GetScreen()->m_Center = true; // Center coordinate origins on screen. LoadSettings( config() ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); // Set some display options here, because the FOOTPRINT_WIZARD_FRAME // does not have a config menu to do that: DISPLAY_OPTIONS* disp_opts = (DISPLAY_OPTIONS*) GetDisplayOptions(); disp_opts->m_DisplayPadIsol = false; disp_opts->m_DisplayPadNum = true; GetBoard()->SetElementVisibility( PCB_VISIBLE(NO_CONNECTS_VISIBLE), false ); GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); ReCreateHToolbar(); ReCreateVToolbar(); // Creates the parameter pages list m_pageList = new wxListBox( this, ID_FOOTPRINT_WIZARD_PAGE_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_HSCROLL ); // Creates the The list of parameters for the current parameter page initParameterGrid(); ReCreatePageList(); DisplayWizardInfos(); m_auimgr.SetManagedWindow( this ); EDA_PANEINFO horiztb; horiztb.HorizontalToolbarPane(); EDA_PANEINFO info; info.InfoToolbarPane(); EDA_PANEINFO mesg; mesg.MessageToolbarPane(); // Manage main toolbal m_auimgr.AddPane( m_mainToolBar, wxAuiPaneInfo( horiztb ). Name( wxT ("m_mainToolBar" ) ).Top().Row( 0 ) ); // Manage the left window (list of parameter pages) EDA_PANEINFO paneList; paneList.InfoToolbarPane().Name( wxT( "m_pageList" ) ).Left().Row( 0 ); m_auimgr.AddPane( m_pageList, wxAuiPaneInfo( paneList ) ); // Manage the parameters grid editor for the current parameter page EDA_PANEINFO panePrms; panePrms.InfoToolbarPane().Name( wxT( "m_parameterGrid" ) ).Left().Row( 1 ); m_auimgr.AddPane( m_parameterGrid, wxAuiPaneInfo( panePrms ) ); // Manage the draw panel m_auimgr.AddPane( m_canvas, wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() ); // Manage the message panel m_auimgr.AddPane( m_messagePanel, wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(1) ); // Gives a min size and the last saved size to left windows m_auimgr.GetPane( m_pageList ).MinSize( wxSize(60, -1 ) ); m_auimgr.GetPane( m_pageList ).BestSize( wxSize(m_pageListWidth, -1) ); m_auimgr.GetPane( m_parameterGrid ).MinSize( wxSize( 120, -1 ) ); m_auimgr.GetPane( m_parameterGrid ).BestSize( wxSize(m_parameterGridWidth, -1) ); m_auimgr.Update(); // Now Drawpanel is sized, we can use BestZoom to show the component (if any) #ifdef USE_WX_GRAPHICS_CONTEXT GetScreen()->SetZoom( BestZoom() ); #else Zoom_Automatique( false ); #endif // Do not Run a dialog here: on some Window Managers, it creates issues. // Reason: the FOOTPRINT_WIZARD_FRAME is run as modal; // It means the call to FOOTPRINT_WIZARD_FRAME::ShowModal will change the // Event Loop Manager, and stop the one created by the dialog. // It does not happen on all W.M., perhaps due to the way the order events are called // SelectFootprintWizard(); }
void FOOTPRINT_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMaskLayer, bool aPrintMirrorMode, void * aData) { GR_DRAWMODE drawmode = GR_COPY; int defaultPenSize = Millimeter2iu( 0.2 ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions(); DISPLAY_OPTIONS save_opt; PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE; if( printParameters ) defaultPenSize = printParameters->m_PenDefaultSize; save_opt = *displ_opts; displ_opts->m_ContrastModeDisplay = false; displ_opts->m_DisplayPadFill = true; displ_opts->m_DisplayViaFill = true; displ_opts->m_DisplayPadNum = false; bool nctmp = GetBoard()->IsElementVisible(NO_CONNECTS_VISIBLE); GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, false); displ_opts->m_DisplayPadIsol = false; displ_opts->m_DisplayModEdgeFill = FILLED; displ_opts->m_DisplayModTextFill = FILLED; displ_opts->m_DisplayPcbTrackFill = true; displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE; displ_opts->m_DisplayDrawItemsFill = FILLED; displ_opts->m_DisplayZonesMode = 0; displ_opts->m_DisplayNetNamesMode = 0; m_canvas->SetPrintMirrored( aPrintMirrorMode ); // The OR mode is used in color mode, but be aware the background *must be // BLACK. In the print page dialog, we first print in BLACK, and after // reprint in color, on the black "local" background, in OR mode the black // print is not made before, only a white page is printed if( GetGRForceBlackPenState() == false ) drawmode = GR_OR; // Draw footprints, this is done at last in order to print the pad holes in // white after the tracks and zones int tmp = D_PAD::m_PadSketchModePenSize; D_PAD::m_PadSketchModePenSize = defaultPenSize; wxSize pageSizeIU = GetPageSizeIU() / 2; wxPoint offset( pageSizeIU.x, pageSizeIU.y ); for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) { module->Move( offset ); Print_Module( m_canvas, aDC, module, drawmode, aPrintMaskLayer, drillShapeOpt ); module->Move( -offset ); } D_PAD::m_PadSketchModePenSize = tmp; m_canvas->SetPrintMirrored( false ); *displ_opts = save_opt; GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, nctmp ); }