kicad/share/drawpanel.cpp

1122 lines
31 KiB
C++
Raw Normal View History

/******************************************/
/* drawpanel.cpp - WinEDA_DrawPanel class */
/******************************************/
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
#ifdef __GNUG__
#pragma implementation
#endif
#include "fctsys.h"
#include "common.h"
#include "macros.h"
#include "id.h"
// Local defines
#define CURSOR_SIZE 12 // Cursor size in pixels
2007-05-06 16:03:28 +00:00
// Events used by WinEDA_DrawPanel
2007-08-15 02:43:57 +00:00
BEGIN_EVENT_TABLE( WinEDA_DrawPanel, EDA_DRAW_PANEL )
EVT_LEAVE_WINDOW( WinEDA_DrawPanel::OnMouseLeaving )
EVT_MOUSE_EVENTS( WinEDA_DrawPanel::OnMouseEvent )
EVT_CHAR( WinEDA_DrawPanel::OnKeyEvent )
EVT_CHAR_HOOK( WinEDA_DrawPanel::OnKeyEvent )
EVT_PAINT( WinEDA_DrawPanel::OnPaint )
EVT_SIZE( WinEDA_DrawPanel::OnSize )
EVT_ERASE_BACKGROUND( WinEDA_DrawPanel::OnEraseBackground )
EVT_SCROLLWIN( WinEDA_DrawPanel::OnScroll )
EVT_ACTIVATE( WinEDA_DrawPanel::OnActivate )
EVT_MENU_RANGE( ID_POPUP_ZOOM_START_RANGE, ID_POPUP_ZOOM_END_RANGE,
WinEDA_DrawPanel::Process_Popup_Zoom )
2007-05-06 16:03:28 +00:00
END_EVENT_TABLE()
/************************************************************************/
/* WinEDA_DrawPanel basic functions (WinEDA_DrawPanel is the main panel)*/
/************************************************************************/
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
WinEDA_DrawPanel::WinEDA_DrawPanel( WinEDA_DrawFrame* parent, int id,
const wxPoint& pos, const wxSize& size ) :
EDA_DRAW_PANEL( parent, id, pos, size,
wxBORDER | wxNO_FULL_REPAINT_ON_RESIZE )
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
m_Parent = parent;
m_Ident = m_Parent->m_Ident;
m_Scroll_unit = 1;
m_ScrollButt_unit = 40;
SetBackgroundColour( wxColour( ColorRefs[g_DrawBgColor].m_Red,
ColorRefs[g_DrawBgColor].m_Green,
ColorRefs[g_DrawBgColor].m_Blue ) );
EnableScrolling( TRUE, TRUE );
m_ClipBox.SetSize( size );
m_ClipBox.SetX( 0 );
m_ClipBox.SetY( 0 );
m_CanStartBlock = -1; // Command block can start if >= 0
m_AbortEnable = m_AbortRequest = FALSE;
m_AutoPAN_Enable = TRUE;
2007-09-15 04:25:54 +00:00
m_IgnoreMouseEvents = 0;
2007-08-22 05:11:01 +00:00
ManageCurseur = NULL;
ForceCloseManageCurseur = NULL;
if( m_Parent->m_Parent->m_EDA_Config )
m_AutoPAN_Enable = m_Parent->m_Parent->m_EDA_Config->Read( wxT( "AutoPAN" ), TRUE );
m_AutoPAN_Request = FALSE;
m_Block_Enable = FALSE;
m_PanelDefaultCursor = m_PanelCursor = wxCURSOR_ARROW;
m_CursorLevel = 0;
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/*********************************************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::Trace_Curseur( wxDC* DC, int color )
2007-05-06 16:03:28 +00:00
/*********************************************************************************/
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/*
* Draw the schematic cursor which is usually on grid
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
if( m_CursorLevel != 0 )
{
return;
}
if( DC == NULL )
return;
wxPoint Cursor = GetScreen()->m_Curseur;
2007-08-22 05:11:01 +00:00
GRSetDrawMode( DC, GR_XOR );
if( g_CursorShape == 1 ) /* Trace d'un reticule */
{
int dx = m_ClipBox.GetWidth() * GetZoom();
2007-08-22 05:11:01 +00:00
int dy = m_ClipBox.GetHeight() * GetZoom();
2007-08-22 05:11:01 +00:00
GRLine( &m_ClipBox, DC, Cursor.x - dx, Cursor.y,
Cursor.x + dx, Cursor.y, 0, color ); // axe Y
GRLine( &m_ClipBox, DC, Cursor.x, Cursor.y - dx,
Cursor.x, Cursor.y + dy, 0, color ); // axe X
}
else
{
int len = CURSOR_SIZE * GetZoom();
2007-08-22 05:11:01 +00:00
GRLine( &m_ClipBox, DC, Cursor.x - len, Cursor.y,
Cursor.x + len, Cursor.y, 0, color );
GRLine( &m_ClipBox, DC, Cursor.x, Cursor.y - len,
Cursor.x, Cursor.y + len, 0, color );
}
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/*******************************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::CursorOff( wxDC* DC )
2007-05-06 16:03:28 +00:00
/*******************************************************************/
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/*
2007-08-22 05:11:01 +00:00
* Remove the grid cursor from the display in preparation for other drawing operations
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
Trace_Curseur( DC );
--m_CursorLevel;
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/*******************************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::CursorOn( wxDC* DC )
2007-05-06 16:03:28 +00:00
/*******************************************************************/
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/*
2007-08-22 05:11:01 +00:00
* Display the grid cursor
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
++m_CursorLevel;
Trace_Curseur( DC );
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
if( m_CursorLevel > 0 ) // Shouldn't happen, but just in case ..
m_CursorLevel = 0;
2007-05-06 16:03:28 +00:00
}
/***********************************/
2007-09-01 12:00:30 +00:00
int WinEDA_DrawPanel::GetZoom()
2007-05-06 16:03:28 +00:00
/***********************************/
{
2007-08-22 05:11:01 +00:00
return GetScreen()->GetZoom();
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/***************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::SetZoom( int zoom )
2007-05-06 16:03:28 +00:00
/***************************************/
{
2007-08-22 05:11:01 +00:00
GetScreen()->SetZoom( zoom );
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/************************************/
2007-09-01 12:00:30 +00:00
wxSize WinEDA_DrawPanel::GetGrid()
2007-05-06 16:03:28 +00:00
/************************************/
{
2007-08-22 05:11:01 +00:00
return GetScreen()->GetGrid();
2007-05-06 16:03:28 +00:00
}
/******************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::PrepareGraphicContext( wxDC* DC )
2007-05-06 16:03:28 +00:00
/******************************************************/
{
2007-08-22 05:11:01 +00:00
GRResetPenAndBrush( DC );
DC->SetBackgroundMode( wxTRANSPARENT );
2007-05-06 16:03:28 +00:00
#ifdef WX_ZOOM
2007-08-22 05:11:01 +00:00
int zoom = GetZoom();
double f_scale = 1.0 / (double) zoom;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
DC->SetUserScale( f_scale, f_scale );
PrepareDC( *DC );
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
SetBoundaryBox();
2007-05-06 16:03:28 +00:00
}
/*********************************************************************/
2007-08-22 05:11:01 +00:00
wxPoint WinEDA_DrawPanel::CalcAbsolutePosition( const wxPoint& rel_pos )
2007-05-06 16:03:28 +00:00
/*********************************************************************/
2007-08-22 05:11:01 +00:00
/** Function CalcAbsolutePosition
* @return absolute position in pixels, considering the scroll amount
* @param rel_pos = relative position (screen position) in pixel
* ( relative position = position in the panel draw area on screen )
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint pos;
2007-05-06 16:03:28 +00:00
#ifdef WX_ZOOM
2007-08-22 05:11:01 +00:00
CalcUnscrolledPosition( rel_pos.x, rel_pos.y, &pos.x, &pos.y );
2007-05-06 16:03:28 +00:00
#else
2007-08-22 05:11:01 +00:00
int ii, jj;
GetViewStart( &pos.x, &pos.y ); // pos is the origin in scroll units
2007-08-22 05:11:01 +00:00
GetScrollPixelsPerUnit( &ii, &jj );
pos.x *= ii;
pos.y *= jj; // pos is the origin in pixel units
2007-08-22 05:11:01 +00:00
pos.x += rel_pos.x;
pos.y += rel_pos.y;
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
return pos;
2007-05-06 16:03:28 +00:00
}
/**********************************************************************/
2007-08-22 05:11:01 +00:00
wxPoint WinEDA_DrawPanel::CursorRealPosition( const wxPoint& ScreenPos )
2007-05-06 16:03:28 +00:00
/**********************************************************************/
2007-08-22 05:11:01 +00:00
/** CursorRealPosition (used to calculate the cursor position in internal units)
* @return position (in internal units)
* @param ScreenPos = absolute position in pixels
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint curpos;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
curpos = GetScreen()->CursorRealPosition( ScreenPos );
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
return curpos;
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/********************************************************/
2007-08-22 05:11:01 +00:00
bool WinEDA_DrawPanel::IsPointOnDisplay( wxPoint ref_pos )
2007-05-06 16:03:28 +00:00
/********************************************************/
2007-08-22 05:11:01 +00:00
/** Funcion IsPointOnDisplay
* @param ref_pos is the position to test in pixels, relative to the panel.
* @return TRUE if ref_pos is a point currently visible on screen
* FALSE if ref_pos is out of screen
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint pos;
EDA_Rect display_rect;
SetBoundaryBox();
display_rect = m_ClipBox;
// Reduction legere des dimension de l'ecran utile pour eviter cadrage
// en limite d'ecran
#define PIXEL_MARGIN 8
display_rect.Inflate( -PIXEL_MARGIN, -PIXEL_MARGIN );
// Conversion en coord physiques
pos = CalcAbsolutePosition( display_rect.GetPosition() );
2007-08-22 05:11:01 +00:00
pos.x *= GetZoom();
pos.y *= GetZoom();
2007-08-22 05:11:01 +00:00
pos.x += GetScreen()->m_DrawOrg.x;
pos.y += GetScreen()->m_DrawOrg.y;
display_rect.SetX( pos.x );
2007-10-09 12:29:02 +00:00
display_rect.SetY( pos.y );
2007-08-22 05:11:01 +00:00
display_rect.SetWidth( display_rect.GetWidth() * GetZoom() );
display_rect.SetHeight( display_rect.GetHeight() * GetZoom() );
return display_rect.Inside( ref_pos );
2007-05-06 16:03:28 +00:00
}
/********************************************************/
2007-09-01 12:00:30 +00:00
wxPoint WinEDA_DrawPanel::CursorScreenPosition()
2007-05-06 16:03:28 +00:00
/********************************************************/
2007-08-22 05:11:01 +00:00
/** CursorScreenPosition
* @return relative position in pixels of du curseur
* ( relative position = position in the panel draw area on screen )
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint curpos = GetScreen()->m_Curseur;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
curpos.x -= GetScreen()->m_DrawOrg.x;
curpos.y -= GetScreen()->m_DrawOrg.y;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
curpos.x /= GetZoom();
curpos.y /= GetZoom();
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
return curpos;
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/*********************************************************/
2007-09-01 12:00:30 +00:00
wxPoint WinEDA_DrawPanel::GetScreenCenterRealPosition()
2007-05-06 16:03:28 +00:00
/*********************************************************/
/** Function GetScreenCenterRealPosition()
* @return position (in internal units) of the current area centre showed on screen
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxSize size;
wxPoint realpos;
2007-05-06 16:03:28 +00:00
size = GetClientSize();
size.x /= 2;
2007-10-09 12:29:02 +00:00
size.y /= 2;
2007-05-06 16:03:28 +00:00
realpos = CalcAbsolutePosition( wxPoint( size.x, size.y ) );
2007-08-22 05:11:01 +00:00
realpos.x *= GetZoom();
realpos.y *= GetZoom();
2007-08-22 05:11:01 +00:00
realpos.x += GetScreen()->m_DrawOrg.x;
realpos.y += GetScreen()->m_DrawOrg.y;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
return realpos;
2007-05-06 16:03:28 +00:00
}
/**********************************************/
2007-09-01 12:00:30 +00:00
void WinEDA_DrawPanel::MouseToCursorSchema()
2007-05-06 16:03:28 +00:00
/**********************************************/
2007-08-22 05:11:01 +00:00
/* Move the mouse cursor to the current schematic cursor
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint Mouse = CursorScreenPosition();
MouseTo( Mouse );
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/****************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::MouseTo( const wxPoint& Mouse )
2007-05-06 16:03:28 +00:00
/****************************************************/
2007-08-22 05:11:01 +00:00
/** Move the mouse cursor to the position "Mouse"
* @param Mouse = new mouse cursor position
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint mouse;
2007-05-06 16:03:28 +00:00
#ifdef WX_ZOOM
2007-08-22 05:11:01 +00:00
CalcScrolledPosition( Mouse.x, Mouse.y, &mouse.x, &mouse.y );
2007-05-06 16:03:28 +00:00
#else
2007-08-22 05:11:01 +00:00
mouse = Mouse;
mouse.x -= GetScreen()->m_StartVisu.x;
mouse.y -= GetScreen()->m_StartVisu.y;
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
GRMouseWarp( this, mouse );
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/********************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnActivate( wxActivateEvent& event )
2007-05-06 16:03:28 +00:00
/********************************************************/
/**
* Called on window activation.
* init the member m_CanStartBlock to avoid a block start command
* on activation (because a left mouse buton can be pressed and no block command wanted
* This happens when enter on a hierarchycat sheet on double click
*/
2007-05-06 16:03:28 +00:00
{
m_CanStartBlock = -1; // Block Command can't start
2007-08-22 05:11:01 +00:00
event.Skip();
2007-05-06 16:03:28 +00:00
}
/***********************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnEraseBackground( wxEraseEvent& event )
2007-05-06 16:03:28 +00:00
/***********************************************************/
{
2007-08-22 05:11:01 +00:00
event.Skip();
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/*********************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnScroll( wxScrollWinEvent& event )
2007-05-06 16:03:28 +00:00
/*********************************************************/
{
2007-08-22 05:11:01 +00:00
int id = event.GetEventType();
int dir, value = 0;
int x, y;
GetViewStart( &x, &y );
dir = event.GetOrientation(); // wxHORIZONTAL or wxVERTICAL
2007-08-22 05:11:01 +00:00
if( id == wxEVT_SCROLLWIN_LINEUP )
value = -m_ScrollButt_unit;
else if( id == wxEVT_SCROLLWIN_LINEDOWN )
value = m_ScrollButt_unit;
else if( id == wxEVT_SCROLLWIN_THUMBTRACK )
{
value = event.GetPosition();
if( dir == wxHORIZONTAL )
Scroll( value, -1 );
else
Scroll( -1, value );
return;
}
else
{
event.Skip();
return;
}
if( dir == wxHORIZONTAL )
{
Scroll( x + value, -1 );
}
else
{
Scroll( -1, y + value );
}
event.Skip();
2007-05-06 16:03:28 +00:00
}
/*************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnSize( wxSizeEvent& event )
2007-05-06 16:03:28 +00:00
/*************************************************/
{
2007-08-22 05:11:01 +00:00
SetBoundaryBox();
event.Skip();
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/******************************************/
2007-09-01 12:00:30 +00:00
void WinEDA_DrawPanel::SetBoundaryBox()
2007-05-06 16:03:28 +00:00
/******************************************/
/** Function SetBoundaryBox()
* set the m_ClipBox member to the current displayed rectangle dimensions
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
BASE_SCREEN* Screen = GetScreen();;
wxPoint org;
int ii, jj;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
Screen->m_SizeVisu = GetClientSize();
GetViewStart( &org.x, &org.y );
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
GetScrollPixelsPerUnit( &ii, &jj );
org.x *= ii; org.y *= jj;
Screen->m_StartVisu = org;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
m_ClipBox.SetOrigin( org );
m_ClipBox.SetSize( GetClientSize() );
2007-05-06 16:03:28 +00:00
#ifdef WX_ZOOM
2007-08-22 05:11:01 +00:00
m_ClipBox.m_Pos.x *= GetZoom();
m_ClipBox.m_Pos.y *= GetZoom();
m_ClipBox.m_Size.x *= GetZoom();
m_ClipBox.m_Size.y *= GetZoom();
2007-05-06 16:03:28 +00:00
#else
2007-08-22 05:11:01 +00:00
m_ClipBox.m_Pos.x -= GetScreen()->m_StartVisu.x;
m_ClipBox.m_Pos.y -= GetScreen()->m_StartVisu.y;
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
m_ScrollButt_unit = MIN( Screen->m_SizeVisu.x, Screen->m_SizeVisu.y ) / 4;
if( m_ScrollButt_unit < 2 )
m_ScrollButt_unit = 2;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
Screen->m_ScrollbarPos.x = GetScrollPos( wxHORIZONTAL );
Screen->m_ScrollbarPos.y = GetScrollPos( wxVERTICAL );
2007-05-06 16:03:28 +00:00
}
/*********************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::EraseScreen( wxDC* DC )
2007-05-06 16:03:28 +00:00
/*********************************************/
{
2007-08-22 05:11:01 +00:00
GRSetDrawMode( DC, GR_COPY );
GRSFilledRect( &m_ClipBox, DC, m_ClipBox.GetX(), m_ClipBox.GetY(),
m_ClipBox.GetRight(), m_ClipBox.GetBottom(),
g_DrawBgColor, g_DrawBgColor );
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/***************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnPaint( wxPaintEvent& event )
2007-05-06 16:03:28 +00:00
/***************************************************/
{
2007-08-22 05:11:01 +00:00
wxPaintDC paintDC( this );
EDA_Rect tmp;
wxRect PaintClipBox;
wxPoint org;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
PrepareGraphicContext( &paintDC );
tmp = m_ClipBox;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
org = m_ClipBox.GetOrigin();
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
wxRegionIterator upd( GetUpdateRegion() ); // get the update rect list
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
while( upd )
{
PaintClipBox = upd.GetRect();
upd++;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
PaintClipBox.x += org.x;
PaintClipBox.y += org.y;
2007-05-06 16:03:28 +00:00
#ifdef WX_ZOOM
m_ClipBox.m_Pos.x = PaintClipBox.x * GetZoom();
2007-08-22 05:11:01 +00:00
m_ClipBox.m_Pos.y = PaintClipBox.y * GetZoom();
2007-08-22 05:11:01 +00:00
m_ClipBox.m_Size.x = PaintClipBox.m_Size.x * GetZoom();
2007-08-22 05:11:01 +00:00
m_ClipBox.m_Size.y = PaintClipBox.m_Size.y * GetZoom();
2007-08-22 05:11:01 +00:00
PaintClipBox = m_ClipBox;
2007-05-06 16:03:28 +00:00
#else
2007-08-22 05:11:01 +00:00
m_ClipBox.SetX( PaintClipBox.GetX() );
m_ClipBox.SetY( PaintClipBox.GetY() );
m_ClipBox.SetWidth( PaintClipBox.GetWidth() );
m_ClipBox.SetHeight( PaintClipBox.GetHeight() );
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
wxDCClipper* dcclip = new wxDCClipper( paintDC, PaintClipBox );
ReDraw( &paintDC, TRUE );
delete dcclip;
}
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
m_ClipBox = tmp;
event.Skip();
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/****************************************************/
2007-08-15 02:43:57 +00:00
void WinEDA_DrawPanel::ReDraw( wxDC* DC, bool erasebg )
2007-05-06 16:03:28 +00:00
/****************************************************/
{
2007-08-22 05:11:01 +00:00
BASE_SCREEN* Screen = GetScreen();
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
if( Screen == NULL )
2007-08-15 02:43:57 +00:00
return;
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
if( (g_DrawBgColor != WHITE) && (g_DrawBgColor != BLACK) )
2007-08-15 02:43:57 +00:00
g_DrawBgColor = BLACK;
2007-08-22 05:11:01 +00:00
if( g_DrawBgColor == WHITE )
{
g_XorMode = GR_NXOR;
g_GhostColor = BLACK;
}
else
{
g_XorMode = GR_XOR;
g_GhostColor = WHITE;
}
2007-05-06 16:03:28 +00:00
#ifdef WX_ZOOM
2007-08-22 05:11:01 +00:00
int zoom = GetZoom();
double f_scale = 1.0 / (double) zoom;
DC->SetUserScale( f_scale, f_scale );
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
if( erasebg )
PrepareGraphicContext( DC );
DC->SetFont( *g_StdFont );
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
SetBackgroundColour( wxColour( ColorRefs[g_DrawBgColor].m_Red,
ColorRefs[g_DrawBgColor].m_Green,
ColorRefs[g_DrawBgColor].m_Blue ) );
2007-05-06 16:03:28 +00:00
2007-08-22 05:11:01 +00:00
GRResetPenAndBrush( DC );
DC->SetBackground( *wxBLACK_BRUSH );
DC->SetBackgroundMode( wxTRANSPARENT );
m_Parent->RedrawActiveWindow( DC, erasebg );
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/***********************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::DrawBackGround( wxDC* DC )
2007-05-06 16:03:28 +00:00
/***********************************************/
2007-08-22 05:11:01 +00:00
/** Function DrawBackGround
* @param DC = current Device Context
* Draws X , Y axis
* draws the grid
* - the grid is drawn only if the zoom level allows a good visibility
* - the grid is always centered on the screen centre
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
int Color = BLUE;
BASE_SCREEN* screen = GetScreen();
int ii, jj, xg, yg, color;
wxSize pas_grille_affichee;
bool drawgrid = FALSE;
int zoom = GetZoom();
wxSize size;
wxPoint org;
double pasx, pasy;
color = g_GridColor;
2007-08-22 05:11:01 +00:00
GRSetDrawMode( DC, GR_COPY );
/* The grid must be visible. this is possible only is grid value
* and zoom value are sufficient
*/
2007-08-22 05:11:01 +00:00
drawgrid = m_Parent->m_Draw_Grid;
2007-08-22 05:11:01 +00:00
pas_grille_affichee = screen->GetGrid();
ii = pas_grille_affichee.x / zoom;
if( ii < 5 )
{
pas_grille_affichee.x *= 2;
2007-10-09 12:29:02 +00:00
ii *= 2;
2007-08-22 05:11:01 +00:00
}
if( ii < 5 )
drawgrid = FALSE; // The gris is small
2007-08-22 05:11:01 +00:00
ii = pas_grille_affichee.y / zoom;
if( ii < 5 )
{
pas_grille_affichee.y *= 2;
2007-10-09 12:29:02 +00:00
ii *= 2;
2007-08-22 05:11:01 +00:00
}
if( ii < 5 )
drawgrid = FALSE; // The gris is small
2007-08-22 05:11:01 +00:00
GetViewStart( &org.x, &org.y );
GetScrollPixelsPerUnit( &ii, &jj );
org.x *= ii;
2007-10-09 12:29:02 +00:00
org.y *= jj;
2007-08-22 05:11:01 +00:00
screen->m_StartVisu = org;
org.x *= zoom;
2007-09-01 12:00:30 +00:00
org.y *= zoom;
org.x += screen->m_DrawOrg.x;
2007-09-01 12:00:30 +00:00
org.y += screen->m_DrawOrg.y;
2007-08-22 05:11:01 +00:00
size = GetClientSize();
size.x *= zoom;
2007-09-01 12:00:30 +00:00
size.y *= zoom;
pasx = screen->m_UserGrid.x * m_Parent->m_InternalUnits;
pasy = screen->m_UserGrid.y * m_Parent->m_InternalUnits;
2007-08-22 05:11:01 +00:00
if( screen->m_UserGridUnit != INCHES )
{
pasx /= 25.4;
2007-09-01 12:00:30 +00:00
pasy /= 25.4;
2007-08-22 05:11:01 +00:00
}
if( drawgrid )
{
m_Parent->PutOnGrid( &org );
GRSetColorPen( DC, color );
for( ii = 0; ; ii++ )
{
xg = screen->m_UserGridIsON ? (int) ( (ii * pasx) + 0.5 )
: ii * pas_grille_affichee.x;
2007-08-22 05:11:01 +00:00
int xpos = org.x + xg;
2007-08-22 05:11:01 +00:00
for( jj = 0; ; jj++ )
{
yg = screen->m_UserGridIsON ? (int) ( (jj * pasy) + 0.5 )
: jj * pas_grille_affichee.y;
GRPutPixel( &m_ClipBox, DC, xpos, org.y + yg, color );
if( yg > size.y )
break;
}
if( xg > size.x )
break;
}
}
/* Draw axis */
2007-08-22 05:11:01 +00:00
if( m_Parent->m_Draw_Axis )
{
/* Draw the Y axis */
2007-08-22 05:11:01 +00:00
GRDashedLine( &m_ClipBox, DC, 0, -screen->ReturnPageSize().y,
0, screen->ReturnPageSize().y, 0, Color );
/* Draw the X axis */
2007-08-22 05:11:01 +00:00
GRDashedLine( &m_ClipBox, DC, -screen->ReturnPageSize().x, 0,
screen->ReturnPageSize().x, 0, 0, Color );
}
/* Draw auxiliary axis */
2007-08-22 05:11:01 +00:00
if( m_Parent->m_Draw_Auxiliary_Axis )
{
m_Draw_Auxiliary_Axis( DC, FALSE );
}
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/********************************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::m_Draw_Auxiliary_Axis( wxDC* DC, int drawmode )
2007-05-06 16:03:28 +00:00
/********************************************************************/
/** m_Draw_Auxiliary_Axis
* Draw the Auxiliary Axis, used in pcbnew which as origin coordinates
* for gerber and excellon files
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
if( m_Parent->m_Auxiliary_Axis_Position.x == 0
&& m_Parent->m_Auxiliary_Axis_Position.y == 0 )
2007-08-22 05:11:01 +00:00
return;
int Color = DARKRED;
BASE_SCREEN* screen = GetScreen();
GRSetDrawMode( DC, drawmode );
/* Draw the Y axis */
2007-08-22 05:11:01 +00:00
GRDashedLine( &m_ClipBox, DC,
m_Parent->m_Auxiliary_Axis_Position.x, -screen->ReturnPageSize().y,
m_Parent->m_Auxiliary_Axis_Position.x, screen->ReturnPageSize().y,
0, Color );
/* Draw the X axis */
2007-08-22 05:11:01 +00:00
GRDashedLine( &m_ClipBox, DC,
-screen->ReturnPageSize().x, m_Parent->m_Auxiliary_Axis_Position.y,
screen->ReturnPageSize().x, m_Parent->m_Auxiliary_Axis_Position.y,
0, Color );
2007-05-06 16:03:28 +00:00
}
2007-08-15 02:43:57 +00:00
2007-05-06 16:03:28 +00:00
/*******************************************************/
bool WinEDA_DrawPanel::OnRightClick( wxMouseEvent& event )
2007-05-06 16:03:28 +00:00
/*******************************************************/
2007-08-22 05:11:01 +00:00
/** Build and display a Popup menu on a right mouse button click
* @return true if a popup menu is shown, or false
2007-08-22 05:11:01 +00:00
*/
2007-05-06 16:03:28 +00:00
{
2007-08-22 05:11:01 +00:00
wxPoint pos;
wxMenu MasterMenu;
pos.x = event.GetX();
2007-08-22 05:11:01 +00:00
pos.y = event.GetY();
if( !m_Parent->OnRightClick( pos, &MasterMenu ) )
return false;
2007-08-22 05:11:01 +00:00
AddMenuZoom( &MasterMenu );
2007-08-22 05:11:01 +00:00
m_IgnoreMouseEvents = TRUE;
PopupMenu( &MasterMenu, pos );
MouseToCursorSchema();
m_IgnoreMouseEvents = FALSE;
return true;
2007-05-06 16:03:28 +00:00
}
/******************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnMouseLeaving( wxMouseEvent& event )
2007-05-06 16:03:28 +00:00
/*******************************************************/
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
// Called when the canvas receives a mouse event leaving frame. //
{
2007-08-22 05:11:01 +00:00
if( ManageCurseur == NULL ) // Pas de commande encours
m_AutoPAN_Request = FALSE;
if( !m_AutoPAN_Enable || !m_AutoPAN_Request || m_IgnoreMouseEvents )
return;
// Auto pan if mouse is leave working aera:
wxSize size = GetClientSize();
if( ( size.x < event.GetX() )
|| ( size.y < event.GetY() )
|| ( event.GetX() <= 0) || ( event.GetY() <= 0 ) )
m_Parent->OnZoom( ID_POPUP_ZOOM_CENTER );
2007-05-06 16:03:28 +00:00
}
/******************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnMouseEvent( wxMouseEvent& event )
2007-05-06 16:03:28 +00:00
/*******************************************************/
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
// Called when the canvas receives a mouse event. //
{
2007-08-22 05:11:01 +00:00
int localrealbutt = 0, localbutt = 0, localkey = 0;
BASE_SCREEN* screen = GetScreen();
static WinEDA_DrawPanel* LastPanel;
static bool IgnoreNextLeftButtonRelease = false;
2007-08-22 05:11:01 +00:00
if( event.Leaving() || event.Entering() )
{
m_CanStartBlock = -1;
}
if( ManageCurseur == NULL ) // No command in progress
2007-08-22 05:11:01 +00:00
m_AutoPAN_Request = FALSE;
if( m_Parent->m_FrameIsActive )
SetFocus();
else
return;
// Mouse Wheel is a zoom command:
if( event.m_wheelRotation )
{
// This is a zoom in ou out command
if( event.GetWheelRotation() > 0 )
{
if( event.ShiftDown() )
localkey = EDA_PANNING_UP_KEY;
else if( event.ControlDown() )
localkey = EDA_PANNING_LEFT_KEY;
else
localkey = EDA_ZOOM_IN_FROM_MOUSE;
2007-08-22 05:11:01 +00:00
}
else
{
if( event.ShiftDown() )
localkey = EDA_PANNING_DOWN_KEY;
else if( event.ControlDown() )
localkey = EDA_PANNING_RIGHT_KEY;
else
localkey = EDA_ZOOM_OUT_FROM_MOUSE;
2007-08-22 05:11:01 +00:00
}
}
if( !event.IsButton() && !event.Moving()
&& !event.Dragging() && !localkey )
{
return;
}
if( event.RightDown() )
{
OnRightClick( event );
2007-09-11 04:11:48 +00:00
return;
2007-08-22 05:11:01 +00:00
}
if( m_IgnoreMouseEvents )
return;
if( event.LeftIsDown() )
localrealbutt |= GR_M_LEFT_DOWN;
2007-08-22 05:11:01 +00:00
if( event.MiddleIsDown() )
localrealbutt |= GR_M_MIDDLE_DOWN;
if( event.LeftDown() )
localbutt = GR_M_LEFT_DOWN;
if( event.ButtonDClick( 1 ) )
localbutt = GR_M_LEFT_DOWN | GR_M_DCLICK;
2007-08-22 05:11:01 +00:00
if( event.MiddleDown() )
localbutt = GR_M_MIDDLE_DOWN;
2007-08-22 05:11:01 +00:00
if( event.ButtonDClick( 2 ) )
{
}
; // Unused
localrealbutt |= localbutt; /* compensation defaut wxGTK */
/* Compute absolute m_MousePosition in pixel units: */
screen->m_MousePositionInPixels = CalcAbsolutePosition( wxPoint( event.GetX(), event.GetY() ) );
2007-08-22 05:11:01 +00:00
/* Compute absolute m_MousePosition in user units: */
screen->m_MousePosition = CursorRealPosition( screen->m_MousePositionInPixels );
wxClientDC DC( this );
int kbstat = 0;
DC.SetBackground( *wxBLACK_BRUSH );
PrepareGraphicContext( &DC );
g_KeyPressed = localkey;
if( event.ShiftDown() )
kbstat |= GR_KB_SHIFT;
if( event.ControlDown() )
kbstat |= GR_KB_CTRL;
if( event.AltDown() )
kbstat |= GR_KB_ALT;
g_MouseOldButtons = localrealbutt;
// Calling Double Click and Click functions :
2007-08-22 05:11:01 +00:00
if( localbutt == (int) (GR_M_LEFT_DOWN | GR_M_DCLICK) )
{
2007-08-22 05:11:01 +00:00
m_Parent->OnLeftDClick( &DC, screen->m_MousePositionInPixels );
IgnoreNextLeftButtonRelease = true;
}
2007-10-09 12:29:02 +00:00
else if( event.LeftUp() )
{
if( screen->BlockLocate.m_State==STATE_NO_BLOCK && !IgnoreNextLeftButtonRelease )
m_Parent->OnLeftClick( &DC, screen->m_MousePositionInPixels );
2007-10-09 12:29:02 +00:00
IgnoreNextLeftButtonRelease = false;
}
2007-08-22 05:11:01 +00:00
if( event.ButtonUp( 2 ) && (screen->BlockLocate.m_State == STATE_NO_BLOCK) )
{
2007-09-11 04:11:48 +00:00
// The middle button has been relached, with no block command:
2007-08-22 05:11:01 +00:00
// We use it for a zoom center command
g_KeyPressed = localkey = EDA_ZOOM_CENTER_FROM_MOUSE;
2007-08-22 05:11:01 +00:00
}
/* Calling the general function on mouse changes (and pseudo key commands) */
2007-08-22 05:11:01 +00:00
m_Parent->GeneralControle( &DC, screen->m_MousePositionInPixels );
/*******************************/
/* Control of block commands : */
/*******************************/
// Command block can't start if mouse is dragging a new panel
if( LastPanel != this )
m_CanStartBlock = -1;
// A new command block can start after a release buttons
// Avoid a false start block when a dialog box is demiss,
2007-08-22 05:11:01 +00:00
// or when changing panels in hierachy navigation
if( !event.LeftIsDown() && !event.MiddleIsDown() )
{
m_CanStartBlock = 0;
}
if( m_Block_Enable && !(localbutt & GR_M_DCLICK) )
{
if( (screen->BlockLocate.m_Command == BLOCK_IDLE)
|| (screen->BlockLocate.m_State == STATE_NO_BLOCK) )
{
m_CursorStartPos = screen->m_Curseur;
screen->BlockLocate.SetOrigin( m_CursorStartPos );
}
if( event.LeftDown() || event.MiddleDown() )
{
m_CursorStartPos = screen->m_Curseur;
if( screen->BlockLocate.m_State == STATE_BLOCK_MOVE )
{
m_AutoPAN_Request = FALSE;
m_Parent->HandleBlockPlace( &DC );
IgnoreNextLeftButtonRelease = true;
2007-08-22 05:11:01 +00:00
}
}
else if( (m_CanStartBlock >= 0 )
&& ( event.LeftIsDown() || event.MiddleIsDown() )
&& ManageCurseur == NULL
&& ForceCloseManageCurseur == NULL )
{
if( screen->BlockLocate.m_State == STATE_NO_BLOCK )
{
int cmd_type = kbstat;
2007-08-22 05:11:01 +00:00
if( event.MiddleIsDown() )
cmd_type |= MOUSE_MIDDLE;
2007-08-22 05:11:01 +00:00
if( !m_Parent->HandleBlockBegin( &DC, cmd_type, m_CursorStartPos ) )
{
2007-09-26 20:10:12 +00:00
// error
m_Parent->DisplayToolMsg(
wxT( "WinEDA_DrawPanel::OnMouseEvent() Block Error" ) );
2007-08-22 05:11:01 +00:00
}
else
{
m_AutoPAN_Request = TRUE;
SetCursor( m_PanelCursor = wxCURSOR_SIZING );
}
}
}
if( event.ButtonUp( 1 ) || event.ButtonUp( 2 ) )
{
/* Release the mouse button: end of block.
* The command can finish (DELETE) or have a next command
* (MOVE, COPY).
* However the block command is cancelled if the block size is small
2007-08-22 05:11:01 +00:00
*/
bool BlockIsSmall =
( ABS( screen->BlockLocate.GetWidth() / GetZoom() ) < 3)
&& ( ABS( screen->BlockLocate.GetHeight() / GetZoom() ) < 3);
if( (screen->BlockLocate.m_State != STATE_NO_BLOCK) && BlockIsSmall )
{
if( ForceCloseManageCurseur )
{
ForceCloseManageCurseur( this, &DC );
m_AutoPAN_Request = FALSE;
}
SetCursor( m_PanelCursor = m_PanelDefaultCursor );
}
else if( screen->BlockLocate.m_State == STATE_BLOCK_END )
{
m_AutoPAN_Request = FALSE;
m_Parent->HandleBlockEnd( &DC );
SetCursor( m_PanelCursor = m_PanelDefaultCursor );
if( screen->BlockLocate.m_State == STATE_BLOCK_MOVE )
{
m_AutoPAN_Request = TRUE;
SetCursor( m_PanelCursor = wxCURSOR_HAND );
}
}
}
}
// End of block command on a double click
// To avoid an unwanted block move command if the move is moved while double click
2007-08-22 05:11:01 +00:00
if( localbutt == (int) (GR_M_LEFT_DOWN | GR_M_DCLICK) )
{
if( screen->BlockLocate.m_Command != BLOCK_IDLE )
{
if( ForceCloseManageCurseur )
{
ForceCloseManageCurseur( this, &DC );
m_AutoPAN_Request = FALSE;
}
}
}
2007-05-06 16:03:28 +00:00
#if 0
2007-08-22 05:11:01 +00:00
wxString msg_debug;
msg_debug.Printf( " block state %d, cmd %d",
screen->BlockLocate.m_State, screen->BlockLocate.m_Command );
m_Parent->PrintMsg( msg_debug );
2007-05-06 16:03:28 +00:00
#endif
2007-08-22 05:11:01 +00:00
LastPanel = this;
m_Parent->SetToolbars();
2007-05-06 16:03:28 +00:00
}
2007-08-22 05:11:01 +00:00
2007-05-06 16:03:28 +00:00
/****************************************************/
2007-08-22 05:11:01 +00:00
void WinEDA_DrawPanel::OnKeyEvent( wxKeyEvent& event )
2007-05-06 16:03:28 +00:00
/****************************************************/
{
2007-08-22 05:11:01 +00:00
long key, localkey;
bool escape = FALSE;
key = localkey = event.GetKeyCode();
switch( localkey )
{
case WXK_CONTROL:
case WXK_CAPITAL:
case WXK_SHIFT:
case WXK_NUMLOCK:
case WXK_LBUTTON:
case WXK_RBUTTON:
case WXK_ALT:
2007-08-22 05:11:01 +00:00
return;
case WXK_ESCAPE:
escape = m_AbortRequest = TRUE;
break;
}
if( event.ControlDown() )
localkey |= GR_KB_CTRL;
if( event.AltDown() )
localkey |= GR_KB_ALT;
if( event.ShiftDown() && (key > 256) )
localkey |= GR_KB_SHIFT;
wxClientDC DC( this );
BASE_SCREEN* Screen = GetScreen();
PrepareGraphicContext( &DC );
g_KeyPressed = localkey;
if( escape )
{
if( ManageCurseur && ForceCloseManageCurseur )
{
SetCursor( m_PanelCursor = m_PanelDefaultCursor );
ForceCloseManageCurseur( this, &DC );
SetCursor( m_PanelCursor = m_PanelDefaultCursor );
}
else
2007-08-15 02:43:57 +00:00
{
m_PanelCursor = m_PanelDefaultCursor = wxCURSOR_ARROW;
2007-08-22 05:11:01 +00:00
m_Parent->SetToolID( 0, m_PanelCursor, wxEmptyString );
2007-08-15 02:43:57 +00:00
}
2007-08-22 05:11:01 +00:00
}
2007-05-06 16:03:28 +00:00
/* some key commands use the mouse position: refresh it */
#if wxCHECK_VERSION( 2, 8, 0 )
wxPoint mouse_pos = wxGetMousePosition(); // Get the mouse position on screen
wxPoint win_pos = GetScreenPosition(); // get the draw area (panel)position on screen
mouse_pos -= win_pos; // mouse_pos = is the mouse position relative to the panel
/* Compute absolute m_MousePosition in pixel units (i.e. considering the current scrool) : */
Screen->m_MousePositionInPixels = CalcAbsolutePosition( mouse_pos );
/* Compute absolute m_MousePosition in user units: */
Screen->m_MousePosition = CursorRealPosition( Screen->m_MousePositionInPixels );
#else
/* if wxGetMousePosition() does not exist,
* m_Cursor should be ok, use it to calculate the cursor position on screen
*/
Screen->m_MousePositionInPixels = CursorScreenPosition();
#endif
2007-12-06 16:58:12 +00:00
2007-08-22 05:11:01 +00:00
m_Parent->GeneralControle( &DC, Screen->m_MousePositionInPixels );
2007-08-22 05:11:01 +00:00
#if 0
event.Skip(); // Allow menu shortcut processing
#endif
2007-05-06 16:03:28 +00:00
}