*) Switch kicad.exe to using KIFACE modules for all major top level windows.

Eeschema, Pcbnew, and Cvpcb all run under the same process now,
    FOR THE VERY FIRST TIME!

*)  Added KIWAY::PlayerCreate(), PlayerClose(), and PlayersClose().

*)  Factored FRAME_T into <frame_type.h> from ID_DRAWFRAME_TYPE.

*)  Found that the following command line is helpful for collecting all the *.kiface
    files into the <build>/kicad/ directory so that kicad can find them.

      $ cp `find . -name '*.kiface'` kicad/

    Maybe somebody will want to rework how the CMake files are organized so all
    the binaries can go into the same place.  See python-a-mingw-us.

*)  This might fix the problem on the Mac where child process windows were not
    coming to the front.  See ->Raise() in kicad/mainframe.cpp.

*)  You can set USE_KIFACE to 0 in kicad/mainframe.cpp to chain load child exes
    instead of using the KIFACE modules directly, i.e. revert.
This commit is contained in:
Dick Hollenbeck 2014-04-19 13:47:20 -05:00
parent ee3e97e6ca
commit 0d6560a218
44 changed files with 357 additions and 140 deletions

View File

@ -81,7 +81,7 @@ END_EVENT_TABLE()
EDA_3D_FRAME::EDA_3D_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent,
const wxString& aTitle, long style ) :
KIWAY_PLAYER( aKiway, aParent, DISPLAY3D_FRAME_TYPE, aTitle,
KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle,
wxDefaultPosition, wxDefaultSize, style, wxT( "Frame3D" ) )
{
m_canvas = NULL;

View File

@ -62,7 +62,7 @@ static const wxChar entryPerspective[] = wxT( "Perspective" );
EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aFrameName ) :
wxFrame( aParent, wxID_ANY, aTitle, aPos, aSize, aStyle, aFrameName )

View File

@ -90,7 +90,7 @@ END_EVENT_TABLE()
EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent,
ID_DRAWFRAME_TYPE aFrameType,
FRAME_T aFrameType,
const wxString& aTitle,
const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString & aFrameName ) :

View File

@ -24,21 +24,29 @@
#include <string.h>
#include <macros.h>
#include <kiway.h>
#include <kiway_player.h>
#include <config.h>
#include <wx/debug.h>
#include <wx/stdpaths.h>
KIWAY::KIWAY()
KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT];
int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
KIWAY::KIWAY( PGM_BASE* aProgram, wxFrame* aTop ):
m_program( aProgram ),
m_top( aTop )
{
memset( &m_kiface, 0, sizeof( m_kiface ) );
memset( m_player, 0, sizeof( m_player ) );
}
const wxString KIWAY::dso_full_path( FACE_T aFaceId )
{
const wxChar* name = wxT("");
const wxChar* name;
switch( aFaceId )
{
@ -68,22 +76,24 @@ PROJECT& KIWAY::Prj() const
}
KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad )
KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
{
switch( aFaceId )
// Since this will be called from python, cannot assume that code will
// not pass a bad aFaceId.
if( unsigned( aFaceId ) >= DIM( m_kiface ) )
{
// case FACE_SCH:
case FACE_PCB:
if( m_kiface[aFaceId] )
return m_kiface[aFaceId];
break;
// @todo : throw an exception here for python's benefit, at least that
// way it gets some explanatory text.
default:
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
return NULL;
}
// DSO with KIFACE has not been loaded yet, does user want to load it?
// return the previously loaded KIFACE, if it was.
if( m_kiface[aFaceId] )
return m_kiface[aFaceId];
// DSO with KIFACE has not been loaded yet, does caller want to load it?
if( doLoad )
{
wxString dname = dso_full_path( aFaceId );
@ -108,7 +118,7 @@ KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad )
{
KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr;
KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, aProgram );
KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, m_program );
// KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
wxASSERT_MSG( kiface,
@ -116,7 +126,7 @@ KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad )
// Give the DSO a single chance to do its "process level" initialization.
// "Process level" specifically means stay away from any projects in there.
if( kiface->OnKifaceStart( aProgram, KFCTL_PROJECT_SUITE ) )
if( kiface->OnKifaceStart( m_program, KFCTL_PROJECT_SUITE ) )
{
// Tell dso's wxDynamicLibrary destructor not to Unload() the program image.
(void) dso.Detach();
@ -131,3 +141,105 @@ KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad )
return NULL;
}
KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType )
{
switch( aFrameType )
{
case FRAME_SCH:
case FRAME_SCH_LIB_EDITOR:
case FRAME_SCH_VIEWER:
return FACE_SCH;
case FRAME_PCB:
case FRAME_PCB_MODULE_EDITOR:
case FRAME_PCB_MODULE_VIEWER:
case FRAME_PCB_FOOTPRINT_WIZARD:
case FRAME_PCB_DISPLAY3D:
return FACE_PCB;
case FRAME_CVPCB:
case FRAME_CVPCB_DISPLAY:
return FACE_CVPCB;
case FRAME_GERBER:
return FACE_GERBVIEW;
case FRAME_PL_EDITOR:
return FACE_PL_EDITOR;
default:
return FACE_T( -1 );
}
}
KIWAY_PLAYER* KIWAY::PlayerCreate( FRAME_T aFrameType )
{
// Since this will be called from python, cannot assume that code will
// not pass a bad aFrameType.
if( unsigned( aFrameType ) >= DIM( m_player ) )
{
// @todo : throw an exception here for python's benefit, at least that
// way it gets some explanatory text.
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
return NULL;
}
// return the previously opened window
if( m_player[aFrameType] )
return m_player[aFrameType];
FACE_T face_type = KifaceType( aFrameType );
wxASSERT( face_type != FACE_T(-1) );
KIFACE* kiface = KiFACE( face_type );
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( m_top, aFrameType, this, KFCTL_PROJECT_SUITE );
return m_player[aFrameType] = frame;
}
bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
{
// Since this will be called from python, cannot assume that code will
// not pass a bad aFrameType.
if( unsigned( aFrameType ) >= DIM( m_player ) )
{
// @todo : throw an exception here for python's benefit, at least that
// way it gets some explanatory text.
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFrameType" ) );
return false;
}
if( m_player[aFrameType] )
{
if( m_player[aFrameType]->Close( doForce ) )
{
m_player[aFrameType] = 0;
return true;
}
return false;
}
return true; // window is closed already.
}
bool KIWAY::PlayersClose( bool doForce )
{
bool ret = true;
for( unsigned i=0; i < DIM( m_player ); ++i )
{
ret = ret && PlayerClose( FRAME_T( i ), doForce );
}
return ret;
}

View File

@ -121,7 +121,7 @@ static const wxString dso_full_path( const wxString& aAbsoluteArgv0 )
// Only a single KIWAY is supported in this single_top top level component,
// which is dedicated to loading only a single DSO.
static KIWAY kiway;
KIWAY Kiway( &Pgm() );
// implement a PGM_BASE and a wxApp side by side:
@ -304,17 +304,17 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp )
// Use KIFACE to create a top window that the KIFACE knows about.
// TOP_FRAME is passed on compiler command line from CMake, and is one of
// the types in ID_DRAWFRAME_TYPE.
// the types in FRAME_T.
// KIFACE::CreateWindow() is a virtual so we don't need to link to it.
// Remember its in the *.kiface DSO.
#if 0
// this pulls in EDA_DRAW_FRAME type info, which we don't want in
// the single_top link image.
KIWAY_PLAYER* frame = dynamic_cast<KIWAY_PLAYER*>( kiface->CreateWindow(
NULL, TOP_FRAME, &kiway, KFCTL_STANDALONE ) );
NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE ) );
#else
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow(
NULL, TOP_FRAME, &kiway, KFCTL_STANDALONE );
NULL, TOP_FRAME, &Kiway, KFCTL_STANDALONE );
#endif
App().SetTopWindow( frame ); // wxApp gets a face.

View File

@ -81,7 +81,7 @@ if( USE_KIWAY_DLLS )
${CVPCB_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=CVPCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL"
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL"
)
target_link_libraries( cvpcb
#singletop # replaces common, giving us restrictive control and link warnings.

View File

@ -72,7 +72,7 @@ END_EVENT_TABLE()
DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent ) :
PCB_BASE_FRAME( aKiway, aParent, CVPCB_DISPLAY_FRAME_TYPE, _( "Footprint Viewer" ),
PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ),
wxDefaultPosition, wxDefaultSize,
KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME )
{

View File

@ -107,7 +107,7 @@ END_EVENT_TABLE()
CVPCB_MAINFRAME::CVPCB_MAINFRAME( KIWAY* aKiway, wxWindow* aParent ) :
KIWAY_PLAYER( aKiway, aParent, CVPCB_FRAME_TYPE, wxT( "CvPCB" ), wxDefaultPosition,
KIWAY_PLAYER( aKiway, aParent, FRAME_CVPCB, wxT( "CvPCB" ), wxDefaultPosition,
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, CVPCB_MAINFRAME_NAME )
{
m_FrameName = CVPCB_MAINFRAME_NAME;

View File

@ -108,7 +108,7 @@ static struct IFACE : public KIFACE_I
{
switch( aClassId )
{
case CVPCB_FRAME_TYPE:
case FRAME_CVPCB:
{
CVPCB_MAINFRAME* frame = new CVPCB_MAINFRAME( aKiway, aParent );
return frame;

View File

@ -251,7 +251,7 @@ if( USE_KIWAY_DLLS )
${EESCHEMA_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=SCHEMATIC_FRAME_TYPE;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL"
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL"
)
target_link_libraries( eeschema
#singletop # replaces common, giving us restrictive control and link warnings.
@ -345,7 +345,7 @@ else()
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=SCHEMATIC_FRAME_TYPE;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL"
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL"
)
if( APPLE )

View File

@ -79,7 +79,7 @@ static struct IFACE : public KIFACE_I
{
switch( aClassId )
{
case SCHEMATIC_FRAME_TYPE:
case FRAME_SCH:
{
SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent );
@ -97,7 +97,7 @@ static struct IFACE : public KIFACE_I
}
break;
case LIBEDITOR_FRAME_TYPE:
case FRAME_SCH_LIB_EDITOR:
{
LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway,
dynamic_cast<SCH_EDIT_FRAME*>( aParent ) );

View File

@ -810,7 +810,7 @@ void LIB_PIN::drawGraphic( EDA_DRAW_PANEL* aPanel,
if( aPanel && aPanel->GetParent() )
frame = (EDA_DRAW_FRAME*)aPanel->GetParent();
if( frame && frame->IsType( SCHEMATIC_FRAME_TYPE ) &&
if( frame && frame->IsType( FRAME_SCH ) &&
! ((SCH_EDIT_FRAME*)frame)->GetShowAllPins() )
return;

View File

@ -190,7 +190,7 @@ END_EVENT_TABLE()
#define LIB_EDIT_FRAME_NAME wxT( "LibeditFrame" )
LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, SCH_EDIT_FRAME* aParent ) :
SCH_BASE_FRAME( aKiway, aParent, LIBEDITOR_FRAME_TYPE, _( "Library Editor" ),
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetLibEditFrameName() )
{
wxASSERT( aParent ); // LIB_EDIT_FRAME needs a parent, since it peeks up there.

View File

@ -29,7 +29,7 @@
SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent,
ID_DRAWFRAME_TYPE aWindowType, const wxString& aTitle,
FRAME_T aWindowType, const wxString& aTitle,
const wxPoint& aPosition, const wxSize& aSize, long aStyle,
const wxString& aFrameName ) :
EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition,

View File

@ -176,7 +176,7 @@ END_EVENT_TABLE()
#define SCH_EDIT_FRAME_NAME wxT( "SchematicFrame" )
SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
SCH_BASE_FRAME( aKiway, aParent, SCHEMATIC_FRAME_TYPE, wxT( "Eeschema" ),
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
m_item_to_repeat( 0 )
{
@ -821,7 +821,7 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
{
KIFACE_I& kf = Kiface();
wxWindow* w = kf.CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
wxWindow* w = kf.CreateWindow( this, FRAME_SCH_LIB_EDITOR, &Kiway(), kf.StartFlags() );
libeditFrame = dynamic_cast<LIB_EDIT_FRAME*>( w );
}

View File

@ -97,7 +97,7 @@ static wxAcceleratorEntry accels[] =
LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, SCH_BASE_FRAME* aParent,
CMP_LIBRARY* aLibrary, wxSemaphore* aSemaphore, long aStyle ) :
SCH_BASE_FRAME( aKiway, aParent, VIEWER_FRAME_TYPE, _( "Library Browser" ),
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Library Browser" ),
wxDefaultPosition, wxDefaultSize, aStyle, GetLibViewerFrameName() )
{
wxAcceleratorTable table( ACCEL_TABLE_CNT, accels );

View File

@ -100,7 +100,7 @@ if( USE_KIWAY_DLLS )
${GERBVIEW_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=GERBER_FRAME_TYPE;BUILD_KIWAY_DLL"
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_GERBER;BUILD_KIWAY_DLL"
)
target_link_libraries( gerbview
#singletop # replaces common, giving us restrictive control and link warnings.

View File

@ -81,7 +81,7 @@ static struct IFACE : public KIFACE_I
{
switch( aClassId )
{
case GERBER_FRAME_TYPE:
case FRAME_GERBER:
{
GERBVIEW_FRAME* frame = new GERBVIEW_FRAME( aKiway, aParent );

View File

@ -65,7 +65,7 @@ static const wxString cfgShowBorderAndTitleBlock( wxT( "ShowBorderAndTitleBloc
#define GERBVIEW_FRAME_NAME wxT( "GerberFrame" )
GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ):
EDA_DRAW_FRAME( aKiway, aParent, GERBER_FRAME_TYPE, wxT( "GerbView" ),
EDA_DRAW_FRAME( aKiway, aParent, FRAME_GERBER, wxT( "GerbView" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GERBVIEW_FRAME_NAME )
{
m_colorsSettings = &g_ColorsSettings;

View File

@ -118,7 +118,7 @@ protected:
public:
EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent,
ID_DRAWFRAME_TYPE aFrameType,
FRAME_T aFrameType,
const wxString& aTitle,
const wxPoint& aPos, const wxSize& aSize,
long aStyle,

32
include/frame_type.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef FRAME_T_H_
#define FRAME_T_H_
/**
* Enum FRAME_T
* is the set of EDA_BASE_FRAME derivatives, typically stored in
* EDA_BASE_FRAME::m_Ident.
*/
enum FRAME_T
{
FRAME_SCH,
FRAME_SCH_LIB_EDITOR,
FRAME_SCH_VIEWER,
FRAME_PCB,
FRAME_PCB_MODULE_EDITOR,
FRAME_PCB_MODULE_VIEWER,
FRAME_PCB_FOOTPRINT_WIZARD,
FRAME_PCB_DISPLAY3D,
FRAME_CVPCB,
FRAME_CVPCB_DISPLAY,
FRAME_GERBER,
KIWAY_PLAYER_COUNT, // counts subset of FRAME_T's tracked in class KIWAY
KICAD_MAIN_FRAME_T = KIWAY_PLAYER_COUNT,
FRAME_PL_EDITOR,
//TEXT_EDITOR_FRAME_T,
FRAME_T_COUNT
};
#endif // FRAME_T_H_

View File

@ -101,6 +101,7 @@ as such! As such, it is OK to use UTF8 characters:
#include <import_export.h>
#include <search_stack.h>
#include <project.h>
#include <frame_type.h>
#define VTBL_ENTRY virtual
@ -126,6 +127,7 @@ class wxWindow;
class wxConfigBase;
class PGM_BASE;
class KIWAY;
class KIWAY_PLAYER;
/**
@ -248,50 +250,109 @@ class KIWAY : public wxEvtHandler
{
public:
/// Possible KIFACEs on *this* KIWAY
/// Known KIFACE implementations
enum FACE_T
{
FACE_SCH, ///< eeschema DSO
// FACE_LIB,
FACE_PCB, ///< pcbnew DSO
// FACE_MOD,
FACE_CVPCB,
FACE_BMP2CMP,
/// count of those above here, which is the subset managed in a KIWAY.
KIWAY_FACE_COUNT,
FACE_BMP2CMP = KIWAY_FACE_COUNT,
FACE_GERBVIEW,
FACE_PL_EDITOR,
FACE_PCB_CALCULATOR,
FACE_COUNT, ///< how many KIWAY player types
FACE_COUNT
};
// If you change the vtable, recompile all of KiCad.
/**
* Function KifaceType
* is a simple mapping function which returns the FACE_T which is known to
* implement @a aFrameType.
*
* @return KIWAY::FACE_T - a valid value or FACE_T(-1) if given a bad aFrameType.
*/
static FACE_T KifaceType( FRAME_T aFrameType );
// If you change the vtable, recompile all of KiCad.
/**
* Function KiFACE
* returns the KIFACE* given a FACE_T. If it is not already loaded, the
* KIFACE is loaded and initialized with a call to KIFACE::OnKifaceStart()
*/
VTBL_ENTRY KIFACE* KiFACE( PGM_BASE* aProgram,
FACE_T aFaceId, bool doLoad = true );
VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad = true );
/**
* Function PlayerCreate
* returns the KIWAY_PLAYER* given a FRAME_T. If it is not already created,
* the required KIFACE is found and loaded and initialized if necessary, then
* the KIWAY_PLAYER window is created but not shown. Caller must Show() it.
* If it is already created, then the existing KIWAY_PLAYER* pointer is returned.
*
* @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there
* is something wrong.
*/
VTBL_ENTRY KIWAY_PLAYER* PlayerCreate( FRAME_T aFrameType );
/**
* Function PlayerClose
* calls the KIWAY_PLAYER::Close( bool force ) function on the window and
* if not vetoed, returns true, else false. If window actually closes, then
* this KIWAY marks it as not opened internally.
*
* @return bool - true the window is closed and not vetoed, else false.
*/
VTBL_ENTRY bool PlayerClose( FRAME_T aFrameType, bool doForce );
/**
* Function PlayersClose
* calls the KIWAY_PLAYER::Close( bool force ) function on all the windows and
* if none are vetoed, returns true, else false. If window actually closes, then
* this KIWAY marks it as not opened internally.
*
* @return bool - true the window is closed and not vetoed, else false.
*/
VTBL_ENTRY bool PlayersClose( bool doForce );
/**
* Function Prj
* returns the PROJECT associated with this KIWAY. This is here as an
* accessor, so that there is freedom to put the actual PROJECT storage
* in a place decided by the implementation, and not known to the caller.
*/
VTBL_ENTRY PROJECT& Prj() const;
KIWAY();
KIWAY( PGM_BASE* aProgram, wxFrame* aTop = NULL );
/// In case aTop may not be known at time of KIWAY construction:
void SetTop( wxFrame* aTop ) { m_top = aTop; }
private:
/// Get the full path & name of the DSO holding the requested FACE_T.
static const wxString dso_full_path( FACE_T aFaceId );
KIFACE* m_kiface[FACE_COUNT];
int m_kiface_version[FACE_COUNT];
static KIFACE* m_kiface[KIWAY_FACE_COUNT];
static int m_kiface_version[KIWAY_FACE_COUNT];
KIWAY_PLAYER* m_player[KIWAY_PLAYER_COUNT]; // from frame_type.h
PROJECT m_project; // do not assume this is here, use Prj().
PGM_BASE* m_program;
wxFrame* m_top;
};
extern KIWAY Kiway; // provided by single_top.cpp and kicad.cpp
/**
* Function Pointer KIFACE_GETTER_FUNC
* points to the one and only KIFACE export. The export's address
@ -310,4 +371,5 @@ typedef KIFACE* KIFACE_GETTER_FUNC( int* aKIFACEversion, int aKIWAYversion,
/// No name mangling. Each KIFACE (DSO/DLL) will implement this once.
extern "C" KIFACE* KIFACE_GETTER( int* aKIFACEversion, int aKIWAYversion, PGM_BASE* aProgram );
#endif // KIWAY_H_

View File

@ -98,7 +98,7 @@ private:
class KIWAY_PLAYER : public EDA_BASE_FRAME, public KIWAY_HOLDER
{
public:
KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aWdoName = wxFrameNameStr ) :
EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ),
@ -110,7 +110,7 @@ public:
KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle,
const wxPoint& aPos, const wxSize& aSize, long aStyle,
const wxString& aWdoName = wxFrameNameStr ) :
EDA_BASE_FRAME( aParent, (ID_DRAWFRAME_TYPE) aId, aTitle, aPos, aSize, aStyle, aWdoName ),
EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ),
KIWAY_HOLDER( 0 )
{}

View File

@ -47,7 +47,7 @@ class SCH_BASE_FRAME : public EDA_DRAW_FRAME
{
public:
SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent,
ID_DRAWFRAME_TYPE aWindowType,
FRAME_T aWindowType,
const wxString& aTitle,
const wxPoint& aPosition, const wxSize& aSize,
long aStyle, const wxString & aFrameName );

View File

@ -115,7 +115,7 @@ protected:
static const LAYER_NUM GAL_LAYER_ORDER[];
public:
PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aFrameName );

View File

@ -46,6 +46,7 @@
#include <fctsys.h>
#include <common.h>
#include <layers_id_colors_and_visibility.h>
#include <frame_type.h>
#ifdef USE_WX_OVERLAY
#include <wx/overlay.h>
@ -81,26 +82,6 @@ enum id_librarytype {
};
enum ID_DRAWFRAME_TYPE
{
NOT_INIT_FRAME_TYPE = 0,
SCHEMATIC_FRAME_TYPE,
LIBEDITOR_FRAME_TYPE,
VIEWER_FRAME_TYPE,
PCB_FRAME_TYPE,
MODULE_EDITOR_FRAME_TYPE,
MODULE_VIEWER_FRAME_TYPE,
FOOTPRINT_WIZARD_FRAME_TYPE,
CVPCB_FRAME_TYPE,
CVPCB_DISPLAY_FRAME_TYPE,
GERBER_FRAME_TYPE,
TEXT_EDITOR_FRAME_TYPE,
DISPLAY3D_FRAME_TYPE,
KICAD_MAIN_FRAME_TYPE,
PL_EDITOR_FRAME_TYPE
};
/// Custom trace mask to enable and disable auto save tracing.
extern const wxChar traceAutoSave[];
@ -132,7 +113,7 @@ class EDA_BASE_FRAME : public wxFrame
void windowClosing( wxCloseEvent& event );
protected:
ID_DRAWFRAME_TYPE m_Ident; ///< Id Type (pcb, schematic, library..)
FRAME_T m_Ident; ///< Id Type (pcb, schematic, library..)
wxPoint m_FramePos;
wxSize m_FrameSize;
@ -196,7 +177,7 @@ protected:
virtual wxString help_name();
public:
EDA_BASE_FRAME( wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString& aFrameName );
@ -219,7 +200,7 @@ public:
bool IsActive() const { return m_FrameIsActive; }
bool IsType( ID_DRAWFRAME_TYPE aType ) const { return m_Ident == aType; }
bool IsType( FRAME_T aType ) const { return m_Ident == aType; }
void GetKicadHelp( wxCommandEvent& event );

View File

@ -32,7 +32,7 @@
#include <fctsys.h>
#include <wx/stdpaths.h>
#include <kicad.h>
#include <kiway_mgr.h>
#include <kiway.h>
#include <pgm_kicad.h>
#include <tree_project_frame.h>
#include <online_help.h>
@ -149,6 +149,8 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp )
wxDefaultPosition, wxDefaultSize );
App().SetTopWindow( frame );
Kiway.SetTop( frame );
bool prjloaded = false; // true when the project is loaded
if( App().argc > 1 )
@ -251,7 +253,7 @@ void PGM_KICAD::destroy()
}
KIWAY_MGR Kiways;
KIWAY Kiway( &Pgm() );
/**
@ -262,7 +264,7 @@ struct APP_KICAD : public wxApp
{
bool OnInit() // overload wxApp virtual
{
if( Kiways.OnStart( this ) )
// if( Kiways.OnStart( this ) )
{
return Pgm().OnPgmInit( this );
}
@ -271,7 +273,7 @@ struct APP_KICAD : public wxApp
int OnExit() // overload wxApp virtual
{
Kiways.OnEnd();
// Kiways.OnEnd();
Pgm().OnPgmExit();
@ -297,10 +299,12 @@ IMPLEMENT_APP( APP_KICAD );
// this link image need this function.
PROJECT& Prj()
{
return Kiways[0].Prj();
return Kiway.Prj();
}
#if 0 // there can be only one in C++ project manager.
bool KIWAY_MGR::OnStart( wxApp* aProcess )
{
// The C++ project manager supports only one open PROJECT
@ -314,3 +318,5 @@ bool KIWAY_MGR::OnStart( wxApp* aProcess )
void KIWAY_MGR::OnEnd()
{
}
#endif

View File

@ -30,7 +30,7 @@
#include <fctsys.h>
#include <pgm_kicad.h>
#include <kiway_mgr.h>
#include <kiway.h>
#include <kiway_player.h>
#include <confirm.h>
#include <gestfich.h>
@ -41,13 +41,14 @@
#include <wildcards_and_files_ext.h>
#include <menus_helpers.h>
#define USE_KIFACE 1
#define TreeFrameWidthEntry wxT( "LeftWinWidth" )
KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent,
const wxString& title, const wxPoint& pos, const wxSize& size ) :
EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_TYPE, title, pos, size,
EDA_BASE_FRAME( parent, KICAD_MAIN_FRAME_T, title, pos, size,
KICAD_DEFAULT_DRAWFRAME_STYLE, wxT( "KicadFrame" ) )
{
m_leftWinWidth = 60;
@ -154,6 +155,8 @@ void KICAD_MANAGER_FRAME::OnSize( wxSizeEvent& event )
void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
if( Kiway.PlayersClose( false ) )
{
int px, py;
UpdateFileHistory( m_ProjectFileName.GetFullPath(), &Pgm().GetFileHistory() );
@ -174,6 +177,7 @@ void KICAD_MANAGER_FRAME::OnCloseWindow( wxCloseEvent& Event )
m_LeftWin->Show( false );
Destroy();
}
}
@ -243,17 +247,12 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event )
wxFileName& board = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ?
kicad_board : legacy_board;
#if 0 // it works!
KIFACE* kiface = Kiways[0].KiFACE( &Pgm(), KIWAY::FACE_PCB );
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( this, PCB_FRAME_TYPE, &Kiways[0], KFCTL_PROJECT_SUITE );
#if USE_KIFACE
KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_PCB );
frame->OpenProjectFiles( std::vector<wxString>( 1, board.GetFullPath() ) );
frame->Show( true );
frame->Raise();
#else
Execute( this, PCBNEW_EXE, QuoteFullPath( board ) );
#endif
@ -265,25 +264,49 @@ void KICAD_MANAGER_FRAME::OnRunCvpcb( wxCommandEvent& event )
wxFileName fn( m_ProjectFileName );
fn.SetExt( NetlistFileExtension );
#if USE_KIFACE
KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_CVPCB );
frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
frame->Show( true );
frame->Raise();
#else
Execute( this, CVPCB_EXE, QuoteFullPath( fn ) );
#endif
}
void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event )
{
wxFileName fn( m_ProjectFileName );
fn.SetExt( SchematicFileExtension );
Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) );
#if USE_KIFACE
KIWAY_PLAYER* frame = Kiway.PlayerCreate( FRAME_SCH );
frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
frame->Show( true );
frame->Raise();
#else
Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) );
#endif
}
void KICAD_MANAGER_FRAME::OnRunGerbview( wxCommandEvent& event )
{
wxFileName fn( m_ProjectFileName );
wxString path = wxT( "\"" );
path += fn.GetPath( wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME ) + wxT( "\"" );
#if USE_KIFACE && 0
#else
Execute( this, GERBVIEW_EXE, path );
#endif
}
@ -353,10 +376,11 @@ void KICAD_MANAGER_FRAME::SaveSettings( wxConfigBase* aCfg )
*/
void KICAD_MANAGER_FRAME::PrintPrjInfo()
{
wxString msg;
msg.Printf( _( "Working dir: %s\nProject: %s\n" ),
wxString msg = wxString::Format( _(
"Working dir: %s\nProject: %s\n" ),
GetChars( wxGetCwd() ),
GetChars( m_ProjectFileName.GetFullPath() ) );
GetChars( m_ProjectFileName.GetFullPath() )
);
PrintMsg( msg );
}

View File

@ -62,7 +62,7 @@ if( USE_KIWAY_DLLS )
${PL_EDITOR_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=PL_EDITOR_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_wks\";BUILD_KIWAY_DLL"
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PL_EDITOR;PGM_DATA_FILE_EXT=\"kicad_wks\";BUILD_KIWAY_DLL"
)
target_link_libraries( pl_editor
#singletop # replaces common, giving us restrictive control and link warnings.

View File

@ -62,7 +62,7 @@ static struct IFACE : public KIFACE_I
{
switch( aClassId )
{
case PL_EDITOR_FRAME_TYPE:
case FRAME_PL_EDITOR:
{
PL_EDITOR_FRAME* frame = new PL_EDITOR_FRAME( aKiway, aParent );

View File

@ -54,7 +54,7 @@
#define PL_EDITOR_FRAME_NAME wxT( "PlEditorFrame" )
PL_EDITOR_FRAME::PL_EDITOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
EDA_DRAW_FRAME( aKiway, aParent, PL_EDITOR_FRAME_TYPE, wxT( "PlEditorFrame" ),
EDA_DRAW_FRAME( aKiway, aParent, FRAME_PL_EDITOR, wxT( "PlEditorFrame" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PL_EDITOR_FRAME_NAME )
{
m_FrameName = PL_EDITOR_FRAME_NAME;

View File

@ -512,7 +512,7 @@ if( USE_KIWAY_DLLS )
${PCBNEW_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp pcbnew.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL"
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\";BUILD_KIWAY_DLL"
)
target_link_libraries( pcbnew
#singletop # replaces common, giving us restrictive control and link warnings.
@ -614,7 +614,7 @@ else() # milestone A) kills this off:
${PCBNEW_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=PCB_FRAME_TYPE;PGM_DATA_FILE_EXT=\"kicad_pcb\""
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_PCB;PGM_DATA_FILE_EXT=\"kicad_pcb\""
)
target_link_libraries( pcbnew
3d-viewer

View File

@ -129,7 +129,7 @@ BEGIN_EVENT_TABLE( PCB_BASE_FRAME, EDA_DRAW_FRAME )
END_EVENT_TABLE()
PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, ID_DRAWFRAME_TYPE aFrameType,
PCB_BASE_FRAME::PCB_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize,
long aStyle, const wxString & aFrameName ) :
EDA_DRAW_FRAME( aKiway, aParent, aFrameType, aTitle, aPos, aSize, aStyle, aFrameName )

View File

@ -211,7 +211,7 @@ bool PCB_BASE_FRAME::InvokeDialogGrid()
if( ret == wxID_OK )
{
if( GetGridOrigin() != grid_origin && IsType( PCB_FRAME_TYPE ) )
if( GetGridOrigin() != grid_origin && IsType( FRAME_PCB ) )
OnModify(); // because grid origin is saved in board, show as modified
SetGridOrigin( grid_origin );

View File

@ -196,7 +196,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
KIFACE_I& kf = Kiface();
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() );
editor->Show( true );
editor->Zoom_Automatique( false );
@ -224,7 +224,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
KIFACE_I& kf = Kiface();
viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() );
viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() );
viewer->Show( true );
viewer->Zoom_Automatique( false );
@ -845,7 +845,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
KIFACE_I& kf = Kiface();
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() );
}
editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() );

View File

@ -80,7 +80,7 @@ void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC )
{
KIFACE_I& kf = Kiface();
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_EDITOR, &Kiway(), kf.StartFlags() );
}
editor->Load_Module_From_BOARD( Module );

View File

@ -108,7 +108,7 @@ void PCB_BASE_FRAME::RotateTextModule( TEXTE_MODULE* Text, wxDC* DC )
if( module && module->GetFlags() == 0 && Text->GetFlags() == 0 ) // prepare undo command
{
if( IsType( PCB_FRAME_TYPE ) )
if( IsType( FRAME_PCB ) )
SaveCopyInUndoList( module, UR_CHANGED );
}
@ -236,7 +236,7 @@ void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
double tmp = Text->GetOrientation();
Text->SetOrientation( TextInitialOrientation );
if( IsType( PCB_FRAME_TYPE ) )
if( IsType( FRAME_PCB ) )
SaveCopyInUndoList( Module, UR_CHANGED );
else
SaveCopyInUndoList( Module, UR_MODEDIT );

View File

@ -121,7 +121,7 @@ static wxAcceleratorEntry accels[] =
FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway, FOOTPRINT_EDIT_FRAME* aParent,
wxSemaphore* semaphore, long style ) :
PCB_BASE_FRAME( aKiway, aParent, FOOTPRINT_WIZARD_FRAME_TYPE,
PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_FOOTPRINT_WIZARD,
_( "Footprint Wizard" ),
wxDefaultPosition, wxDefaultSize, style, FOOTPRINT_WIZARD_FRAME_NAME )
{

View File

@ -273,7 +273,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
KIFACE_I& kf = Kiface();
viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() );
viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, FRAME_PCB_MODULE_VIEWER, &Kiway(), kf.StartFlags() );
viewer->Show( true );
viewer->Zoom_Automatique( false );
}

View File

@ -153,7 +153,7 @@ END_EVENT_TABLE()
#define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" )
FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, PCB_EDIT_FRAME* aParent ) :
PCB_BASE_FRAME( aKiway, aParent, MODULE_EDITOR_FRAME_TYPE, wxEmptyString,
PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_EDITOR, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() )
{

View File

@ -119,7 +119,7 @@ static wxAcceleratorEntry accels[] =
FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent, wxSemaphore* aSemaphore ) :
PCB_BASE_FRAME( aKiway, aParent, MODULE_VIEWER_FRAME_TYPE, _( "Footprint Library Browser" ),
PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB_MODULE_VIEWER, _( "Footprint Library Browser" ),
wxDefaultPosition, wxDefaultSize,
!aSemaphore ?
KICAD_DEFAULT_DRAWFRAME_STYLE :

View File

@ -299,7 +299,7 @@ END_EVENT_TABLE()
#define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" )
PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
PCB_BASE_FRAME( aKiway, aParent, PCB_FRAME_TYPE, wxT( "Pcbnew" ), wxDefaultPosition,
PCB_BASE_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition,
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME )
{
m_FrameName = PCB_EDIT_FRAME_NAME;

View File

@ -110,7 +110,7 @@ static struct IFACE : public KIFACE_I
switch( aClassId )
{
case PCB_FRAME_TYPE:
case FRAME_PCB:
{
PCB_EDIT_FRAME* frame = new PCB_EDIT_FRAME( aKiway, aParent );
@ -130,7 +130,7 @@ static struct IFACE : public KIFACE_I
}
break;
case MODULE_EDITOR_FRAME_TYPE:
case FRAME_PCB_MODULE_EDITOR:
{
// yuck:
PCB_EDIT_FRAME* editor = dynamic_cast<PCB_EDIT_FRAME*>( aParent );
@ -147,7 +147,7 @@ static struct IFACE : public KIFACE_I
}
break;
case MODULE_VIEWER_FRAME_TYPE:
case FRAME_PCB_MODULE_VIEWER:
{
// yuck:
PCB_BASE_FRAME* editor = dynamic_cast<PCB_BASE_FRAME*>( aParent );

View File

@ -263,7 +263,7 @@ void BOARD_PRINTOUT_CONTROLLER::DrawPage()
// 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 to the center of the page:
if( m_Parent->IsType( MODULE_EDITOR_FRAME_TYPE ) )
if( m_Parent->IsType( FRAME_PCB_MODULE_EDITOR ) )
{
boardBoundingBox.Move( wxPoint( pageSizeIU.x/2, pageSizeIU.y/2 ) );
}