Added grag labels patch

This commit is contained in:
jean-pierre charras 2010-07-17 13:14:57 +02:00
parent 30a54500b3
commit 28a3e5840f
15 changed files with 389 additions and 474 deletions

View File

@ -605,23 +605,10 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
for( Struct = screen->EEDrawList; Struct != NULL; Struct = Struct->Next() ) for( Struct = screen->EEDrawList; Struct != NULL; Struct = Struct->Next() )
Struct->m_Flags = 0; Struct->m_Flags = 0;
// Sel .m_Flags to selected for a wire or bus in selected area if there is for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
// only one item:
if( pickedlist->GetCount() == 1 )
{ {
Struct = (SCH_ITEM*) pickedlist->GetPickedItem( 0 ); Struct = (SCH_ITEM*) pickedlist->GetPickedItem( ii );
if( Struct->Type() == DRAW_SEGMENT_STRUCT_TYPE ) Struct->m_Flags = SELECTED;
Struct->m_Flags = SELECTED;
}
// Sel .m_Flags to selected for a wire or bus in selected area for a list
// of items:
else
{
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{
Struct = (SCH_ITEM*) pickedlist->GetPickedItem( ii );
Struct->m_Flags = SELECTED;
}
} }
if( screen->m_BlockLocate.m_Command != BLOCK_DRAG ) if( screen->m_BlockLocate.m_Command != BLOCK_DRAG )
@ -653,6 +640,18 @@ static void CollectStructsToDrag( SCH_SCREEN* screen )
for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ ) for( unsigned ii = 0; ii < pickedlist->GetCount(); ii++ )
{ {
Struct = (SCH_ITEM*) (SCH_ITEM*) pickedlist->GetPickedItem( ii ); Struct = (SCH_ITEM*) (SCH_ITEM*) pickedlist->GetPickedItem( ii );
if( ( Struct->Type() == TYPE_SCH_LABEL )
|| ( Struct->Type() == TYPE_SCH_GLOBALLABEL )
|| ( Struct->Type() == TYPE_SCH_HIERLABEL ) )
{
#undef STRUCT
#define STRUCT ( (SCH_TEXT*) Struct )
if( !screen->m_BlockLocate.Inside( STRUCT->m_Pos ) )
{
AddPickedItem( screen, STRUCT->m_Pos );
}
}
if( Struct->Type() == TYPE_SCH_COMPONENT ) if( Struct->Type() == TYPE_SCH_COMPONENT )
{ {
// Add all pins of the selected component to list // Add all pins of the selected component to list

View File

@ -54,42 +54,21 @@ void TestLabelForDangling( SCH_TEXT* label,
DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ); DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList );
/* Returns TRUE if the point P is on the segment S. /* Returns true if the point P is on the segment S. */
* The segment is assumed horizontal or vertical. bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint )
*/
bool SegmentIntersect( int Sx1, int Sy1, int Sx2, int Sy2,
int Px1, int Py1 )
{ {
int Sxmin, Sxmax, Symin, Symax; wxPoint vectSeg = aSegEnd - aSegStart; // Vector from S1 to S2
wxPoint vectPoint = aTestPoint - aSegStart; // Vector from S1 to P
if( Sx1 == Sx2 ) /* Line S is vertical. */ // Use long long here to avoid overflow in calculations
{ if( (long long)vectSeg.x * vectPoint.y - (long long)vectSeg.y * vectPoint.x )
Symin = MIN( Sy1, Sy2 ); return false; /* Cross product non-zero, vectors not parallel */
Symax = MAX( Sy1, Sy2 );
if( Px1 != Sx1 ) if( ((long long)vectSeg.x * vectPoint.x + (long long)vectSeg.y * vectPoint.y) <
return FALSE; ((long long)vectPoint.x * vectPoint.x + (long long)vectPoint.y * vectPoint.y) )
return false; /* Point not on segment */
if( Py1 >= Symin && Py1 <= Symax ) return true;
return TRUE;
else
return FALSE;
}
else if( Sy1 == Sy2 ) /* Line S is horizontal. */
{
Sxmin = MIN( Sx1, Sx2 );
Sxmax = MAX( Sx1, Sx2 );
if( Py1 != Sy1 )
return FALSE;
if( Px1 >= Sxmin && Px1 <= Sxmax )
return TRUE;
else
return FALSE;
}
else
return FALSE;
} }
@ -133,7 +112,7 @@ void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC )
break; break;
if( STRUCT->GetLayer() == LAYER_BUS ) if( STRUCT->GetLayer() == LAYER_BUS )
{ {
STRUCT->m_StartIsDangling = STRUCT->m_EndIsDangling = FALSE; STRUCT->m_StartIsDangling = STRUCT->m_EndIsDangling = false;
break; break;
} }
break; break;
@ -168,9 +147,9 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList,
NEGATE( pinpos.y ); // In libraries Y axis is bottom to top NEGATE( pinpos.y ); // In libraries Y axis is bottom to top
// and in schematic Y axis is top to bottom // and in schematic Y axis is top to bottom
else // calculate the pin position in schematic else // calculate the pin position in schematic
pinpos = TransformCoordinate( DrawLibItem->m_Transform, pinpos ) pinpos = TransformCoordinate( DrawLibItem->m_Transform, pinpos )
+ DrawLibItem->m_Pos; + DrawLibItem->m_Pos;
if( pos == pinpos ) if( pos == pinpos )
return Pin; return Pin;
@ -182,7 +161,7 @@ void TestWireForDangling( SCH_LINE* DrawRef, WinEDA_SchematicFrame* frame,
wxDC* DC ) wxDC* DC )
{ {
DanglingEndHandle* terminal_item; DanglingEndHandle* terminal_item;
bool Sdangstate = TRUE, Edangstate = TRUE; bool Sdangstate = true, Edangstate = true;
for( terminal_item = ItemList; terminal_item != NULL; for( terminal_item = ItemList; terminal_item != NULL;
terminal_item = terminal_item->m_Pnext ) terminal_item = terminal_item->m_Pnext )
@ -192,13 +171,13 @@ void TestWireForDangling( SCH_LINE* DrawRef, WinEDA_SchematicFrame* frame,
if( (DrawRef->m_Start.x == terminal_item->m_Pos.x) if( (DrawRef->m_Start.x == terminal_item->m_Pos.x)
&& (DrawRef->m_Start.y == terminal_item->m_Pos.y) ) && (DrawRef->m_Start.y == terminal_item->m_Pos.y) )
Sdangstate = FALSE; Sdangstate = false;
if( (DrawRef->m_End.x == terminal_item->m_Pos.x) if( (DrawRef->m_End.x == terminal_item->m_Pos.x)
&& (DrawRef->m_End.y == terminal_item->m_Pos.y) ) && (DrawRef->m_End.y == terminal_item->m_Pos.y) )
Edangstate = FALSE; Edangstate = false;
if( (Sdangstate == FALSE) && (Edangstate == FALSE) ) if( (Sdangstate == false) && (Edangstate == false) )
break; break;
} }
@ -220,7 +199,7 @@ void TestLabelForDangling( SCH_TEXT* label, WinEDA_SchematicFrame* frame,
wxDC* DC ) wxDC* DC )
{ {
DanglingEndHandle* terminal_item; DanglingEndHandle* terminal_item;
bool dangstate = TRUE; bool dangstate = true;
for( terminal_item = ItemList; terminal_item != NULL; for( terminal_item = ItemList; terminal_item != NULL;
terminal_item = terminal_item->m_Pnext ) terminal_item = terminal_item->m_Pnext )
@ -235,16 +214,14 @@ void TestLabelForDangling( SCH_TEXT* label, WinEDA_SchematicFrame* frame,
case SHEET_LABEL_END: case SHEET_LABEL_END:
if( ( label->m_Pos.x == terminal_item->m_Pos.x ) if( ( label->m_Pos.x == terminal_item->m_Pos.x )
&& ( label->m_Pos.y == terminal_item->m_Pos.y ) ) && ( label->m_Pos.y == terminal_item->m_Pos.y ) )
dangstate = FALSE; dangstate = false;
break; break;
case WIRE_START_END: case WIRE_START_END:
case BUS_START_END: case BUS_START_END:
dangstate = !SegmentIntersect( terminal_item->m_Pos.x, dangstate = !SegmentIntersect( terminal_item->m_Pos,
terminal_item->m_Pos.y, terminal_item->m_Pnext->m_Pos,
terminal_item->m_Pnext->m_Pos.x, label->m_Pos );
terminal_item->m_Pnext->m_Pos.y,
label->m_Pos.x, label->m_Pos.y );
terminal_item = terminal_item->m_Pnext; terminal_item = terminal_item->m_Pnext;
break; break;
@ -256,7 +233,7 @@ void TestLabelForDangling( SCH_TEXT* label, WinEDA_SchematicFrame* frame,
break; break;
} }
if( dangstate == FALSE ) if( dangstate == false )
break; break;
} }
@ -322,7 +299,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList )
|| (STRUCT->GetLayer() == LAYER_WIRE ) ) || (STRUCT->GetLayer() == LAYER_WIRE ) )
{ {
item = new DanglingEndHandle( item = new DanglingEndHandle(
(STRUCT->GetLayer() == LAYER_BUS) ? (STRUCT->GetLayer() == LAYER_BUS) ?
BUS_START_END : WIRE_START_END ); BUS_START_END : WIRE_START_END );
item->m_Item = DrawItem; item->m_Item = DrawItem;
@ -334,7 +311,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList )
lastitem = item; lastitem = item;
item = item =
new DanglingEndHandle( (STRUCT->GetLayer() == LAYER_BUS) ? new DanglingEndHandle( (STRUCT->GetLayer() == LAYER_BUS) ?
BUS_END_END : WIRE_END_END ); BUS_END_END : WIRE_END_END );
item->m_Item = DrawItem; item->m_Item = DrawItem;
item->m_Pos = STRUCT->m_End; item->m_Pos = STRUCT->m_End;
@ -387,7 +364,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList )
break; break;
for( LIB_PIN* Pin = Entry->GetNextPin(); Pin != NULL; for( LIB_PIN* Pin = Entry->GetNextPin(); Pin != NULL;
Pin = Entry->GetNextPin( Pin ) ) Pin = Entry->GetNextPin( Pin ) )
{ {
wxASSERT( Pin->Type() == COMPONENT_PIN_DRAW_TYPE ); wxASSERT( Pin->Type() == COMPONENT_PIN_DRAW_TYPE );
@ -417,8 +394,7 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) DrawItem; SCH_SHEET* sheet = (SCH_SHEET*) DrawItem;
BOOST_FOREACH( SCH_SHEET_PIN pinsheet, sheet->GetSheetPins() ) BOOST_FOREACH( SCH_SHEET_PIN pinsheet, sheet->GetSheetPins() ) {
{
wxASSERT( pinsheet.Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ); wxASSERT( pinsheet.Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE );
item = new DanglingEndHandle( SHEET_LABEL_END ); item = new DanglingEndHandle( SHEET_LABEL_END );

View File

@ -578,10 +578,13 @@ void WinEDA_SchematicFrame::OnHotKey( wxDC* DC, int hotkey,
wxPostEvent( this, eventMoveOrDragComponent ); wxPostEvent( this, eventMoveOrDragComponent );
break; break;
case TYPE_SCH_TEXT:
case TYPE_SCH_LABEL: case TYPE_SCH_LABEL:
case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL: case TYPE_SCH_HIERLABEL:
wxPostEvent( this, eventMoveOrDragComponent );
break;
case TYPE_SCH_TEXT:
case DRAW_PART_TEXT_STRUCT_TYPE: case DRAW_PART_TEXT_STRUCT_TYPE:
case DRAW_BUSENTRY_STRUCT_TYPE: case DRAW_BUSENTRY_STRUCT_TYPE:
if( HK_Descr->m_Idcommand != HK_DRAG ) if( HK_Descr->m_Idcommand != HK_DRAG )

View File

@ -1031,9 +1031,7 @@ static void SegmentToPointConnect( NETLIST_OBJECT* Jonction,
continue; continue;
} }
if( SegmentIntersect( Segment->m_Start.x, Segment->m_Start.y, if( SegmentIntersect( Segment->m_Start, Segment->m_End, Jonction->m_Start ) )
Segment->m_End.x, Segment->m_End.y,
Jonction->m_Start.x, Jonction->m_Start.y ) )
{ {
/* Propagation Netcode has all the objects of the same Netcode. */ /* Propagation Netcode has all the objects of the same Netcode. */
if( IsBus == 0 ) if( IsBus == 0 )

View File

@ -342,6 +342,9 @@ void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel )
msg = AddHotkeyName( _( "Move Global Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Move Global Label" ), s_Schematic_Hokeys_Descr,
HK_MOVE_COMPONENT_OR_ITEM ); HK_MOVE_COMPONENT_OR_ITEM );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_text_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_text_xpm );
msg = AddHotkeyName( _( "Drag Global Label" ), s_Schematic_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_CMP_REQUEST, msg, move_text_xpm );
msg = AddHotkeyName( _( "Copy Global Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Copy Global Label" ), s_Schematic_Hokeys_Descr,
HK_COPY_COMPONENT_OR_LABEL ); HK_COPY_COMPONENT_OR_LABEL );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, copy_button ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, copy_button );
@ -376,6 +379,9 @@ void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* HLabel )
msg = AddHotkeyName( _( "Move Hierarchical Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Move Hierarchical Label" ), s_Schematic_Hokeys_Descr,
HK_MOVE_COMPONENT_OR_ITEM ); HK_MOVE_COMPONENT_OR_ITEM );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_text_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_text_xpm );
msg = AddHotkeyName( _( "Drag Hierarchical Label" ), s_Schematic_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_CMP_REQUEST, msg, move_text_xpm );
msg = AddHotkeyName( _( "Copy Hierarchical Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Copy Hierarchical Label" ), s_Schematic_Hokeys_Descr,
HK_COPY_COMPONENT_OR_LABEL ); HK_COPY_COMPONENT_OR_LABEL );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, copy_button ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, copy_button );
@ -409,6 +415,9 @@ void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label )
msg = AddHotkeyName( _( "Move Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Move Label" ), s_Schematic_Hokeys_Descr,
HK_MOVE_COMPONENT_OR_ITEM ); HK_MOVE_COMPONENT_OR_ITEM );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_text_xpm ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_MOVE_ITEM_REQUEST, msg, move_text_xpm );
msg = AddHotkeyName( _( "Drag Label" ), s_Schematic_Hokeys_Descr,
HK_DRAG );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_DRAG_CMP_REQUEST, msg, move_text_xpm );
msg = AddHotkeyName( _( "Copy Label" ), s_Schematic_Hokeys_Descr, msg = AddHotkeyName( _( "Copy Label" ), s_Schematic_Hokeys_Descr,
HK_COPY_COMPONENT_OR_LABEL ); HK_COPY_COMPONENT_OR_LABEL );
ADD_MENUITEM( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, copy_button ); ADD_MENUITEM( PopMenu, ID_POPUP_SCH_COPY_ITEM, msg, copy_button );

View File

@ -17,9 +17,7 @@
#include "class_pin.h" #include "class_pin.h"
/* Local Variables : */ /* Local functions : */
static void Plot_Hierarchical_PIN_Sheet( PLOTTER* plotter,
SCH_SHEET_PIN* Struct );
static void PlotTextField( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem, static void PlotTextField( PLOTTER* plotter, SCH_COMPONENT* DrawLibItem,
int FieldNumber, bool IsMulti, int DrawMode ); int FieldNumber, bool IsMulti, int DrawMode );
@ -304,46 +302,6 @@ static void PlotTextStruct( PLOTTER* plotter, SCH_TEXT* aSchText )
} }
static void Plot_Hierarchical_PIN_Sheet( PLOTTER* plotter,
SCH_SHEET_PIN* aHierarchical_PIN )
{
EDA_Colors txtcolor = UNSPECIFIED_COLOR;
int posx, tposx, posy, size;
static std::vector <wxPoint> Poly;
txtcolor = ReturnLayerColor( aHierarchical_PIN->GetLayer() );
posx = aHierarchical_PIN->m_Pos.x;
posy = aHierarchical_PIN->m_Pos.y;
size = aHierarchical_PIN->m_Size.x;
GRTextHorizJustifyType side;
if( aHierarchical_PIN->m_Edge )
{
tposx = posx - size;
side = GR_TEXT_HJUSTIFY_RIGHT;
}
else
{
tposx = posx + size + (size / 8);
side = GR_TEXT_HJUSTIFY_LEFT;
}
int thickness = aHierarchical_PIN->GetPenSize();
plotter->set_current_line_width( thickness );
plotter->text( wxPoint( tposx, posy ), txtcolor, aHierarchical_PIN->m_Text,
TEXT_ORIENT_HORIZ, wxSize( size, size ),
side, GR_TEXT_VJUSTIFY_CENTER, thickness,
aHierarchical_PIN->m_Italic, aHierarchical_PIN->m_Bold );
/* Draw the associated graphic symbol */
aHierarchical_PIN->CreateGraphicShape( Poly, aHierarchical_PIN->m_Pos );
plotter->poly( Poly.size(), &Poly[0].x, NO_FILL );
}
static void PlotSheetStruct( PLOTTER* plotter, SCH_SHEET* Struct ) static void PlotSheetStruct( PLOTTER* plotter, SCH_SHEET* Struct )
{ {
EDA_Colors txtcolor = UNSPECIFIED_COLOR; EDA_Colors txtcolor = UNSPECIFIED_COLOR;
@ -399,9 +357,9 @@ static void PlotSheetStruct( PLOTTER* plotter, SCH_SHEET* Struct )
plotter->set_color( ReturnLayerColor( Struct->m_Layer ) ); plotter->set_color( ReturnLayerColor( Struct->m_Layer ) );
/* Draw texts : SheetLabel */ /* Draw texts : SheetLabel */
BOOST_FOREACH( SCH_SHEET_PIN& label, Struct->GetSheetPins() ) BOOST_FOREACH( SCH_SHEET_PIN& pin_sheet, Struct->GetSheetPins() )
{ {
label.Plot( plotter ); pin_sheet.Plot( plotter );
} }
} }

View File

@ -31,7 +31,7 @@ wxString DataBaseGetName( WinEDA_DrawFrame* frame, wxString& Keys,
/*********************/ /*********************/
/* DANGLING_ENDS.CPP */ /* DANGLING_ENDS.CPP */
/*********************/ /*********************/
bool SegmentIntersect( int Sx1, int Sy1, int Sx2, int Sy2, int Px1, int Py1 ); bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint );
/****************/ /****************/
/* BUS_WIRE_JUNCTION.CPP */ /* BUS_WIRE_JUNCTION.CPP */

View File

@ -414,7 +414,11 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_SCH_MOVE_CMP_REQUEST: case ID_POPUP_SCH_MOVE_CMP_REQUEST:
// Ensure the struct is a component (could be a struct of a // Ensure the struct is a component (could be a struct of a
// component, like Field, text..) or a hierachical sheet // component, like Field, text..) or a hierachical sheet
// or a label
if( (screen->GetCurItem()->Type() != TYPE_SCH_COMPONENT) if( (screen->GetCurItem()->Type() != TYPE_SCH_COMPONENT)
&& (screen->GetCurItem()->Type() != TYPE_SCH_LABEL)
&& (screen->GetCurItem()->Type() != TYPE_SCH_GLOBALLABEL)
&& (screen->GetCurItem()->Type() != TYPE_SCH_HIERLABEL)
&& (screen->GetCurItem()->Type() != DRAW_SHEET_STRUCT_TYPE) ) && (screen->GetCurItem()->Type() != DRAW_SHEET_STRUCT_TYPE) )
screen->SetCurItem( LocateSmallestComponent( screen ) ); screen->SetCurItem( LocateSmallestComponent( screen ) );
if( screen->GetCurItem() == NULL ) if( screen->GetCurItem() == NULL )

View File

@ -71,8 +71,6 @@ enum main_id
ID_V_TOOLBAR, ID_V_TOOLBAR,
ID_OPT_TOOLBAR, ID_OPT_TOOLBAR,
ID_AUX_TOOLBAR, ID_AUX_TOOLBAR,
ID_AUX_V_TOOLBAR,
ID_TOOLBAR_UNUSED,
ID_GENERAL_HELP, ID_GENERAL_HELP,
ID_LOCAL_HELP, ID_LOCAL_HELP,

View File

@ -269,7 +269,7 @@ public:
void ReCreateHToolbar(); void ReCreateHToolbar();
void ReCreateAuxiliaryToolbar(); void ReCreateAuxiliaryToolbar();
void ReCreateVToolbar(); void ReCreateVToolbar();
void ReCreateAuxVToolbar(); void ReCreateMicrowaveVToolbar();
void ReCreateOptToolbar(); void ReCreateOptToolbar();
void ReCreateMenuBar(); void ReCreateMenuBar();
WinEDAChoiceBox* ReCreateLayerBox( WinEDA_Toolbar* parent ); WinEDAChoiceBox* ReCreateLayerBox( WinEDA_Toolbar* parent );

View File

@ -23,38 +23,33 @@ static wxSize ShapeSize;
static int PolyShapeType; static int PolyShapeType;
static void Exit_Self( WinEDA_DrawPanel* Panel, wxDC* DC ); static void Exit_Self( WinEDA_DrawPanel* Panel, wxDC* DC );
static EDGE_MODULE* gen_arc( MODULE* aModule, static void gen_arc( std::vector <wxPoint>& aBuffer,
EDGE_MODULE* PtSegm, wxPoint aStartPoint,
int cX, wxPoint aCenter,
int cY, int a_ArcAngle );
int angle ); static void ShowBoundingBoxMicroWaveInductor( WinEDA_DrawPanel* panel,
static void ShowBoundingBoxMicroWaveInductor( WinEDA_DrawPanel* panel, wxDC* DC,
wxDC* DC, bool erase );
bool erase );
int BuildCornersList_S_Shape( std::vector <wxPoint>& aBuffer,
wxPoint aStartPoint, wxPoint aEndPoint,
int aLength, int aWidth );
class SELFPCB class SELFPCB
{ {
public: public:
int forme; // Shape: coil, spiral, etc .. int forme; // Shape: coil, spiral, etc ..
int orient; // 0..3600
int valeur; // Value.
wxPoint m_Start; wxPoint m_Start;
wxPoint m_End; wxPoint m_End;
wxSize m_Size; wxSize m_Size;
D_PAD* pt_pad_start, * pt_pad_end;
int lng; // Trace length. int lng; // Trace length.
int m_Width; int m_Width; // Trace width.
int nbrin; // Number of segments.
int lbrin; // Length of segments.
int rayon; // Radius between segments.
int delta; // distance between pads
}; };
static SELFPCB Mself; static SELFPCB Mself;
static int Self_On; static int Self_On;
static int Bl_X0, Bl_Y0, Bl_Xf, Bl_Yf;
/* This function shows on screen the bounding box of the inductor that will be /* This function shows on screen the bounding box of the inductor that will be
@ -62,41 +57,50 @@ static int Bl_X0, Bl_Y0, Bl_Xf, Bl_Yf;
*/ */
static void ShowBoundingBoxMicroWaveInductor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) static void ShowBoundingBoxMicroWaveInductor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{ {
int deltaX, deltaY; /* Calculate the orientation and size of the box containing the inductor:
* the box is a rectangle with height = lenght/2
/* Calculate the orientation and size of the window: * the shape is defined by a rectangle, nor necessary horizontal or vertical
* - Orient = vertical or horizontal (maximum dimensions)
* - Size.x = Size.y / 2
*/ */
GRSetDrawMode( DC, GR_XOR ); GRSetDrawMode( DC, GR_XOR );
wxPoint poly[5];
wxPoint pt = Mself.m_End - Mself.m_Start;
int angle = -wxRound( atan2( (double) pt.y, (double) pt.x ) * 1800.0 / M_PI );
int len = wxRound( sqrt( (double) pt.x * pt.x + (double) pt.y * pt.y ) );
// calculate corners
pt.x = 0; pt.y = len / 4;
RotatePoint( &pt, angle );
poly[0] = Mself.m_Start + pt;
poly[1] = Mself.m_End + pt;
pt.x = 0; pt.y = -len / 4;
RotatePoint( &pt, angle );
poly[2] = Mself.m_End + pt;
poly[3] = Mself.m_Start + pt;
poly[4] = poly[0];
if( erase ) if( erase )
{ {
GRRect( &panel->m_ClipBox, DC, Bl_X0, Bl_Y0, Bl_Xf, Bl_Yf, YELLOW ); GRPoly( &panel->m_ClipBox, DC, 5, poly, false, 0, YELLOW, YELLOW );
} }
deltaX = ( panel->GetScreen()->m_Curseur.x - Mself.m_Start.x ) / 4; Mself.m_End = panel->GetScreen()->m_Curseur;
deltaY = ( panel->GetScreen()->m_Curseur.y - Mself.m_Start.y ) / 4; pt = Mself.m_End - Mself.m_Start;
angle = -wxRound( atan2( (double) pt.y, (double) pt.x ) * 1800.0 / M_PI );
len = wxRound( sqrt( (double) pt.x * pt.x + (double) pt.y * pt.y ) );
Mself.orient = 900; // calculate new corners
if( abs( deltaX ) > abs( deltaY ) ) pt.x = 0; pt.y = len / 4;
Mself.orient = 0; RotatePoint( &pt, angle );
poly[0] = Mself.m_Start + pt;
poly[1] = Mself.m_End + pt;
pt.x = 0; pt.y = -len / 4;
RotatePoint( &pt, angle );
poly[2] = Mself.m_End + pt;
poly[3] = Mself.m_Start + pt;
poly[4] = poly[0];
if( Mself.orient == 0 ) GRPoly( &panel->m_ClipBox, DC, 5, poly, false, 0, YELLOW, YELLOW );
{
Bl_X0 = Mself.m_Start.x;
Bl_Y0 = Mself.m_Start.y - deltaX;
Bl_Xf = panel->GetScreen()->m_Curseur.x;
Bl_Yf = Mself.m_Start.y + deltaX;
}
else
{
Bl_X0 = Mself.m_Start.x - deltaY;
Bl_Y0 = Mself.m_Start.y;
Bl_Xf = Mself.m_Start.x + deltaY;
Bl_Yf = panel->GetScreen()->m_Curseur.y;
}
GRRect( &panel->m_ClipBox, DC, Bl_X0, Bl_Y0, Bl_Xf, Bl_Yf, YELLOW );
} }
@ -121,6 +125,7 @@ void WinEDA_PcbFrame::Begin_Self( wxDC* DC )
} }
Mself.m_Start = GetScreen()->m_Curseur; Mself.m_Start = GetScreen()->m_Curseur;
Mself.m_End = Mself.m_Start;
Self_On = 1; Self_On = 1;
@ -128,12 +133,6 @@ void WinEDA_PcbFrame::Begin_Self( wxDC* DC )
GetScreen()->m_O_Curseur = GetScreen()->m_Curseur; GetScreen()->m_O_Curseur = GetScreen()->m_Curseur;
UpdateStatusBar(); UpdateStatusBar();
Bl_X0 = Mself.m_Start.x;
Bl_Y0 = Mself.m_Start.y;
Bl_Xf = Bl_X0;
Bl_Yf = Bl_Y0;
DrawPanel->ManageCurseur = ShowBoundingBoxMicroWaveInductor; DrawPanel->ManageCurseur = ShowBoundingBoxMicroWaveInductor;
DrawPanel->ForceCloseManageCurseur = Exit_Self; DrawPanel->ForceCloseManageCurseur = Exit_Self;
DrawPanel->ManageCurseur( DrawPanel, DC, 0 ); DrawPanel->ManageCurseur( DrawPanel, DC, 0 );
@ -143,29 +142,27 @@ void WinEDA_PcbFrame::Begin_Self( wxDC* DC )
/* Create a self-shaped coil /* Create a self-shaped coil
* - Length Mself.lng * - Length Mself.lng
* - Extremities Mself.m_Start and Mself.m_End * - Extremities Mself.m_Start and Mself.m_End
* - Constraint: m_Start.x = m_End.x (self Vertical)
* Or m_Start.y = m_End.y (self Horizontal)
* *
* We must determine: * We must determine:
* Mself.nbrin = number of segments perpendicular to the direction * Mself.nbrin = number of segments perpendicular to the direction
* (The coil nbrin will demicercles + 1 + 2 1 / 4 circle) * (The coil nbrin will demicercles + 1 + 2 1 / 4 circle)
* Mself.lbrin = length of a strand * Mself.lbrin = length of a strand
* Mself.rayon = radius of rounded parts of the coil * Mself.radius = radius of rounded parts of the coil
* Mself.delta = segments extremities connection between him and the coil even * Mself.delta = segments extremities connection between him and the coil even
* *
* The equations are * The equations are
* Mself.m_Size.x = 2 * Mself.rayon + Mself.lbrin * Mself.m_Size.x = 2 * Mself.radius + Mself.lbrin
* Mself.m_Size.y * Mself.delta = 2 + 2 * Mself.nbrin * Mself.rayon * Mself.m_Size.y * Mself.delta = 2 + 2 * Mself.nbrin * Mself.radius
* Mself.lng = 2 * Mself.delta / / connections to the coil * Mself.lng = 2 * Mself.delta / / connections to the coil
+ (Mself.nbrin-2) * Mself.lbrin / / length of the strands except 1st and last + (Mself.nbrin-2) * Mself.lbrin / / length of the strands except 1st and last
+ (Mself.nbrin 1) * (PI * Mself.rayon) / / length of rounded + (Mself.nbrin 1) * (PI * Mself.radius) / / length of rounded
* Mself.lbrin + / 2 - Melf.rayon * 2) / / length of 1st and last bit * Mself.lbrin + / 2 - Melf.radius * 2) / / length of 1st and last bit
* *
* The constraints are: * The constraints are:
* Nbrin >= 2 * Nbrin >= 2
* Mself.rayon < Mself.m_Size.x * Mself.radius < Mself.m_Size.x
* Mself.m_Size.y = Mself.rayon * 4 + 2 * Mself.raccord * Mself.m_Size.y = Mself.radius * 4 + 2 * Mself.raccord
* Mself.lbrin> Mself.rayon * 2 * Mself.lbrin> Mself.radius * 2
* *
* The calculation is conducted in the following way: * The calculation is conducted in the following way:
* Initially: * Initially:
@ -178,13 +175,11 @@ void WinEDA_PcbFrame::Begin_Self( wxDC* DC )
*/ */
MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC ) MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
{ {
EDGE_MODULE* PtSegm, * LastSegm, * FirstSegm, * newedge; D_PAD* PtPad;
MODULE* Module; int ll;
D_PAD* PtPad; double fcoeff;
int ii, ll, lextbrin; bool abort = FALSE;
double fcoeff; wxString msg;
bool abort = FALSE;
wxString msg;
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
@ -200,24 +195,9 @@ MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
Mself.m_End = GetScreen()->m_Curseur; Mself.m_End = GetScreen()->m_Curseur;
/* Fitting of parameters to simplify the calculation: wxPoint pt = Mself.m_End - Mself.m_Start;
* The starting point must be coord departure from the end point */ int min_len = wxRound( sqrt( (double) pt.x * pt.x + (double) pt.y * pt.y ) );
if( Mself.orient == 0 ) // Horizontal Mself.lng = min_len;
{
Mself.m_End.y = Mself.m_Start.y;
if( Mself.m_Start.x > Mself.m_End.x )
EXCHG( Mself.m_Start.x, Mself.m_End.x );
Mself.m_Size.y = Mself.m_End.x - Mself.m_Start.x;
Mself.lng = Mself.m_Size.y;
}
else // Vertical
{
Mself.m_End.x = Mself.m_Start.x;
if( Mself.m_Start.y > Mself.m_End.y )
EXCHG( Mself.m_Start.y, Mself.m_End.y );
Mself.m_Size.y = Mself.m_End.y - Mself.m_Start.y;
Mself.lng = Mself.m_Size.y;
}
/* Enter the desired length. */ /* Enter the desired length. */
if( !g_UserUnit ) if( !g_UserUnit )
@ -244,53 +224,28 @@ MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
Mself.lng = wxRound( fval * fcoeff ); Mself.lng = wxRound( fval * fcoeff );
/* Control values (ii = minimum length) */ /* Control values (ii = minimum length) */
if( Mself.lng < Mself.m_Size.y ) if( Mself.lng < min_len )
{ {
DisplayError( this, _( "Requested length < minimum length" ) ); DisplayError( this, _( "Requested length < minimum length" ) );
return NULL; return NULL;
} }
/* Calculate the elements. */ /* Calculate the elements. */
Mself.m_Width = GetBoard()->GetCurrentTrackWidth(); Mself.m_Width = GetBoard()->GetCurrentTrackWidth();
Mself.m_Size.x = Mself.m_Size.y / 2;
// Choose a reasonable starting value for the radius of the arcs. std::vector <wxPoint> buffer;
Mself.rayon = MIN( Mself.m_Width * 5, Mself.m_Size.x / 4 ); ll = BuildCornersList_S_Shape( buffer, Mself.m_Start, Mself.m_End,
Mself.lng, Mself.m_Width );
for( Mself.nbrin = 2; ; Mself.nbrin++ ) if( !ll )
{ {
Mself.delta = DisplayError( this, _( "Requested length too large" ) );
( Mself.m_Size.y - ( Mself.rayon * 2 * Mself.nbrin ) ) / 2; return NULL;
if( Mself.delta < Mself.m_Size.y / 10 ) // Reduce radius.
{
Mself.delta = Mself.m_Size.y / 10;
Mself.rayon =
( Mself.m_Size.y - 2 * Mself.delta ) / ( 2 * Mself.nbrin );
if( Mself.rayon < Mself.m_Width ) // Radius too small.
{
Affiche_Message( _( "Unable to create line: Requested length is too big" ) );
return NULL;
}
}
Mself.lbrin = Mself.m_Size.x - ( Mself.rayon * 2 );
lextbrin = ( Mself.lbrin / 2 ) - Mself.rayon;
ll = 2 * lextbrin; // Length of first and last
// segment.
ll += 2 * Mself.delta; // Length of coil connections.
ll += Mself.nbrin * ( Mself.lbrin - 2 ); // Length of other segments.
ll += ( ( Mself.nbrin + 1 ) * 314 * Mself.rayon ) / 100;
msg.Printf( _( "Segment count = %d, length = " ), Mself.nbrin );
wxString stlen;
valeur_param( ll, stlen );
msg += stlen;
Affiche_Message( msg );
if( ll >= Mself.lng )
break;
} }
/* Generate module. */ /* Generate module. */
Module = Create_1_Module( DC, wxEmptyString ); MODULE* Module;
Module = Create_1_Module( NULL, wxEmptyString );
if( Module == NULL ) if( Module == NULL )
return NULL; return NULL;
@ -298,172 +253,33 @@ MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
Module->m_LibRef = wxT( "MuSelf" ); Module->m_LibRef = wxT( "MuSelf" );
Module->m_Attributs = MOD_VIRTUAL | MOD_CMS; Module->m_Attributs = MOD_VIRTUAL | MOD_CMS;
Module->m_Flags = 0; Module->m_Flags = 0;
Module->m_Pos = Mself.m_End;
Module->Draw( DrawPanel, DC, GR_XOR ); /* Generate segments. */
for( unsigned jj = 1; jj < buffer.size(); jj++ )
/* Generate special features. */
FirstSegm = PtSegm = new EDGE_MODULE( Module );
Module->m_Drawings.PushBack( PtSegm );
PtSegm->m_Start = Mself.m_Start;
PtSegm->m_End.x = Mself.m_Start.x;
PtSegm->m_End.y = PtSegm->m_Start.y + Mself.delta;
PtSegm->m_Width = Mself.m_Width;
PtSegm->SetLayer( Module->GetLayer() );
PtSegm->m_Shape = S_SEGMENT;
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.PushBack( newedge );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
PtSegm = gen_arc( Module,
PtSegm,
PtSegm->m_End.x - Mself.rayon,
PtSegm->m_End.y,
-900 );
if( lextbrin )
{ {
newedge = new EDGE_MODULE( Module ); EDGE_MODULE* PtSegm;
newedge->Copy( PtSegm ); PtSegm = new EDGE_MODULE( Module );
PtSegm->m_Start = buffer[jj - 1];
Module->m_Drawings.PushBack( newedge ); PtSegm->m_End = buffer[jj];
PtSegm->m_Width = Mself.m_Width;
PtSegm = newedge; PtSegm->SetLayer( Module->GetLayer() );
PtSegm->m_Start = PtSegm->m_End; PtSegm->m_Shape = S_SEGMENT;
PtSegm->m_End.x -= lextbrin; PtSegm->m_Start0 = PtSegm->m_Start - Module->m_Pos;
PtSegm->m_End0 = PtSegm->m_End - Module->m_Pos;
Module->m_Drawings.PushBack( PtSegm );
} }
/* Create coil. */ /* Place a pad on each end of coil. */
for( ii = 1; ii < Mself.nbrin; ii++ )
{
int arc_angle;
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.PushBack( newedge );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
if( ii & 1 ) /* odd order arcs are greater than 0 */
arc_angle = 1800;
else
arc_angle = -1800;
PtSegm = gen_arc( Module, PtSegm, PtSegm->m_End.x,
PtSegm->m_End.y + Mself.rayon, arc_angle );
if( ii < Mself.nbrin - 1 )
{
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.Insert( newedge, PtSegm->Next() );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
if( ii & 1 )
PtSegm->m_End.x += Mself.lbrin;
else
PtSegm->m_End.x -= Mself.lbrin;
}
}
/* Create last segment. */
if( ii & 1 )
{
if( lextbrin )
{
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.Insert( newedge, PtSegm->Next() );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
PtSegm->m_End.x -= lextbrin;
}
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.PushBack( newedge );
PtSegm = newedge;
PtSegm->m_Start.x = PtSegm->m_End.x; PtSegm->m_Start.y =
PtSegm->m_End.y;
PtSegm = gen_arc( Module,
PtSegm,
PtSegm->m_End.x,
PtSegm->m_End.y + Mself.rayon,
900 );
}
else
{
if( lextbrin )
{
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.Insert( newedge, PtSegm->Next() );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
PtSegm->m_End.x += lextbrin;
}
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.PushBack( newedge );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
PtSegm = gen_arc( Module,
PtSegm,
PtSegm->m_End.x,
PtSegm->m_End.y + Mself.rayon,
-900 );
}
newedge = new EDGE_MODULE( Module );
newedge->Copy( PtSegm );
Module->m_Drawings.Insert( newedge, PtSegm->Next() );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
PtSegm->m_End = Mself.m_End;
/* Rotate the coil if it has a horizontal orientation. */
LastSegm = PtSegm;
if( Mself.orient == 0 )
{
for( PtSegm = FirstSegm;
PtSegm != NULL;
PtSegm = (EDGE_MODULE*) PtSegm->Next() )
{
RotatePoint( &PtSegm->m_Start.x, &PtSegm->m_Start.y,
FirstSegm->m_Start.x, FirstSegm->m_Start.y, 900 );
if( PtSegm != LastSegm )
RotatePoint( &PtSegm->m_End.x, &PtSegm->m_End.y,
FirstSegm->m_Start.x, FirstSegm->m_Start.y, 900 );
}
}
Module->m_Pos = LastSegm->m_End;
/* Place pad on each end of coil. */
PtPad = new D_PAD( Module ); PtPad = new D_PAD( Module );
Module->m_Pads.PushFront( PtPad ); Module->m_Pads.PushFront( PtPad );
PtPad->SetPadName( wxT( "1" ) ); PtPad->SetPadName( wxT( "1" ) );
PtPad->m_Pos = LastSegm->m_End; PtPad->m_Pos = Mself.m_End;
PtPad->m_Pos0 = PtPad->m_Pos - Module->m_Pos; PtPad->m_Pos0 = PtPad->m_Pos - Module->m_Pos;
PtPad->m_Size.x = PtPad->m_Size.y = LastSegm->m_Width; PtPad->m_Size.x = PtPad->m_Size.y = Mself.m_Width;
PtPad->m_Masque_Layer = g_TabOneLayerMask[LastSegm->GetLayer()]; PtPad->m_Masque_Layer = g_TabOneLayerMask[Module->GetLayer()];
PtPad->m_Attribut = PAD_SMD; PtPad->m_Attribut = PAD_SMD;
PtPad->m_PadShape = PAD_CIRCLE; PtPad->m_PadShape = PAD_CIRCLE;
PtPad->m_Rayon = PtPad->m_Size.x / 2; PtPad->m_Rayon = PtPad->m_Size.x / 2;
@ -475,27 +291,21 @@ MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
PtPad = newpad; PtPad = newpad;
PtPad->SetPadName( wxT( "2" ) ); PtPad->SetPadName( wxT( "2" ) );
PtPad->m_Pos = FirstSegm->m_Start; PtPad->m_Pos = Mself.m_Start;
PtPad->m_Pos0 = PtPad->m_Pos - Module->m_Pos; PtPad->m_Pos0 = PtPad->m_Pos - Module->m_Pos;
/* Modify text positions. */ /* Modify text positions. */
Module->DisplayInfo( this ); Module->DisplayInfo( this );
Module->m_Value->m_Pos.x = Module->m_Reference->m_Pos.x = Module->m_Value->m_Pos.x = Module->m_Reference->m_Pos.x =
( FirstSegm->m_Start.x + LastSegm->m_End.x ) / 2; ( Mself.m_Start.x + Mself.m_End.x ) / 2;
Module->m_Value->m_Pos.y = Module->m_Reference->m_Pos.y = Module->m_Value->m_Pos.y = Module->m_Reference->m_Pos.y =
( FirstSegm->m_Start.y + LastSegm->m_End.y ) / 2; ( Mself.m_Start.y + Mself.m_End.y ) / 2;
Module->m_Reference->m_Pos.y -= Module->m_Reference->m_Size.y; Module->m_Reference->m_Pos.y -= Module->m_Reference->m_Size.y;
Module->m_Value->m_Pos.y += Module->m_Value->m_Size.y; Module->m_Value->m_Pos.y += Module->m_Value->m_Size.y;
Module->m_Reference->m_Pos0 = Module->m_Reference->m_Pos - Module->m_Pos; Module->m_Reference->m_Pos0 = Module->m_Reference->m_Pos - Module->m_Pos;
Module->m_Value->m_Pos0 = Module->m_Value->m_Pos - Module->m_Pos; Module->m_Value->m_Pos0 = Module->m_Value->m_Pos - Module->m_Pos;
/* Initial segment coordinates. */
for( PtSegm = FirstSegm; PtSegm; PtSegm = PtSegm->Next() )
{
PtSegm->m_Start0 = PtSegm->m_Start - Module->m_Pos;
PtSegm->m_End0 = PtSegm->m_End - Module->m_Pos;
}
Module->Set_Rectangle_Encadrement(); Module->Set_Rectangle_Encadrement();
Module->Draw( DrawPanel, DC, GR_OR ); Module->Draw( DrawPanel, DC, GR_OR );
@ -504,60 +314,215 @@ MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
} }
/* Generate an arc EDGE_MODULE: /** gen_arc
* Center cX, cY * Generate an arc using arc approximation by lines:
* Angle "angle" * Center aCenter
* Starting point gives the structure pointed to by PtSegm, which must * Angle "angle" (in 0.1 deg)
* Returns a pointer to the structure EDGE_MODULE generated. * @param aBuffer = a buffer to store points.
* @param aStartPoint = starting point of arc.
* @param aCenter = arc centre.
* @param a_ArcAngle = arc length in 0.1 degrees.
*/ */
static EDGE_MODULE* gen_arc( MODULE* aModule, static void gen_arc( std::vector <wxPoint>& aBuffer,
EDGE_MODULE* PtSegm, wxPoint aStartPoint,
int cX, wxPoint aCenter,
int cY, int a_ArcAngle )
int angle )
{ {
int ii, nb_seg; #define SEGM_COUNT_PER_360DEG 16
double alpha, beta, fsin, fcos; wxPoint first_point = aStartPoint - aCenter;
int x0, xr0, y0, yr0; int seg_count = ( (abs( a_ArcAngle ) ) * SEGM_COUNT_PER_360DEG) / 3600;
EDGE_MODULE* newedge;
angle = -angle; if( seg_count == 0 )
y0 = PtSegm->m_Start.x - cX; seg_count = 1;
x0 = PtSegm->m_Start.y - cY;
nb_seg = ( abs( angle ) ) / 225; double increment_angle = (double) a_ArcAngle * 3.14159 / 1800 / seg_count;
if( nb_seg == 0 ) // Creates nb_seg point to approximate arc by segments:
nb_seg = 1; for( int ii = 1; ii <= seg_count; ii++ )
alpha = ( (double) angle * 3.14159 / 1800 ) / nb_seg;
for( ii = 1; ii <= nb_seg; ii++ )
{ {
if( ii > 1 ) double rot_angle = increment_angle * ii;
double fcos = cos( rot_angle );
double fsin = sin( rot_angle );
wxPoint currpt;
// Rotate current point:
currpt.x = wxRound( ( first_point.x * fcos + first_point.y * fsin ) );
currpt.y = wxRound( ( first_point.y * fcos - first_point.x * fsin ) );
wxPoint corner = aCenter + currpt;
aBuffer.push_back( corner );
}
}
/** Function BuildCornersList_S_Shape
* Create a path like a S-shaped coil
* @param aBuffer = a vector <wxPoint>& buffer where to put points
* @param aEndPoint = ending point of the path
* @param aLength = full lenght of the path
* @param aWidth = witdth of lines
*/
int BuildCornersList_S_Shape( std::vector <wxPoint>& aBuffer,
wxPoint aStartPoint, wxPoint aEndPoint,
int aLength, int aWidth )
{
/* We must determine:
* segm_count = number of segments perpendicular to the direction
* segm_len = length of a strand
* radius = radius of rounded parts of the coil
* stubs_len = length of the 2 stubs( segments parallel to the direction)
* connecting the start point to the start point of the S shape
* and the ending point to the end point of the S shape
* The equations are (assuming the area size of the entire shape is Size:
* Size.x = 2 * radius + segm_len
* Size.y = (segm_count + 2 ) * 2 * radius + 2 * stubs_len
* Mself.lng = 2 * delta // connections to the coil
* + (segm_count-2) * segm_len // length of the strands except 1st and last
* + (segm_count) * (PI * radius) // length of rounded
* segm_len + / 2 - radius * 2) // length of 1st and last bit
*
* The constraints are:
* segm_count >= 2
* radius < m_Size.x
* Size.y = (radius * 4) + (2 * stubs_len)
* segm_len > radius * 2
*
* The calculation is conducted in the following way:
* first:
* segm_count = 2
* radius = 4 * Size.x (arbitrarily fixed value)
* Then:
* Increasing the number of segments to the desired length
* (radius decreases if necessary)
*/
wxSize size;
// This scale factor adjust the arc lenght to handle
// the arc to segment approximation.
// because we use SEGM_COUNT_PER_360DEG segment to approximate a circle,
// the trace len must be corrected when calculated using arcs
// this factor adjust calculations and must be canged if SEGM_COUNT_PER_360DEG is modified
// because trace using segment is shorter the corresponding arc
// ADJUST_SIZE is the ratio between tline len and the arc len for an arc
// of 360/ADJUST_SIZE angle
#define ADJUST_SIZE 0.988
wxPoint pt = aEndPoint - aStartPoint;
int angle = -wxRound( atan2( (double) pt.y, (double) pt.x ) * 1800.0 / M_PI );
int min_len = wxRound( sqrt( (double) pt.x * pt.x + (double) pt.y * pt.y ) );
int segm_len = 0; // lenght of segments
int full_len; // full len of shape (sum of lenght of all segments + arcs)
/* Note: calculations are made for a vertical coil (more easy calculations)
* and after points are rotated to their actual position
* So the main direction is the Y axis.
* the 2 stubs are on the Y axis
* the others segments are parallel to the X axis.
*/
// Calculate the size of area (for a vertical shape)
size.x = min_len / 2;
size.y = min_len;
// Choose a reasonable starting value for the radius of the arcs.
int radius = MIN( aWidth * 5, size.x / 4 );
int segm_count; // number of full len segments
// the half size segments (first and last segment) are not counted here
int stubs_len = 0; // lenght of first or last segment (half size of others segments)
for( segm_count = 0; ; segm_count++ )
{
stubs_len = ( size.y - ( radius * 2 * (segm_count + 2 ) ) ) / 2;
if( stubs_len < size.y / 10 ) // Reduce radius.
{ {
newedge = new EDGE_MODULE( aModule ); stubs_len = size.y / 10;
radius = ( size.y - (2 * stubs_len) ) / ( 2 * (segm_count + 2) );
newedge->Copy( PtSegm ); if( radius < aWidth ) // Radius too small.
{
aModule->m_Drawings.PushBack( newedge ); // Unable to create line: Requested length value is too large for room
return 0;
PtSegm = newedge; }
PtSegm->m_Start = PtSegm->m_End;
} }
segm_len = size.x - ( radius * 2 );
full_len = 2 * stubs_len; // Length of coil connections.
full_len += segm_len * segm_count; // Length of full length segments.
full_len += wxRound( ( segm_count + 2 ) * M_PI * ADJUST_SIZE * radius ); // Ard arcs len
full_len += segm_len - (2 * radius); // Length of first and last segments
// (half size segments len = segm_len/2 - radius).
beta = ( alpha * ii ); if( full_len >= aLength )
fcos = cos( beta ); fsin = sin( beta ); break;
xr0 = (int) ( x0 * fcos + y0 * fsin );
yr0 = (int) ( y0 * fcos - x0 * fsin );
PtSegm->m_End.x = cX + yr0;
PtSegm->m_End.y = cY + xr0;
} }
return PtSegm; // Adjust len by adjusting segm_len:
int delta_size = full_len - aLength;
// reduce len of the segm_count segments + 2 half size segments (= 1 full size segment)
segm_len -= delta_size / (segm_count+1);
// Generate first line (the first stub) and first arc (90 deg arc)
pt = aStartPoint;
aBuffer.push_back( pt );
pt.y += stubs_len;
aBuffer.push_back( pt );
wxPoint centre = pt;
centre.x -= radius;
gen_arc( aBuffer, pt, centre, -900 );
pt = aBuffer.back();
int half_size_seg_len = segm_len / 2 - radius;
if( half_size_seg_len )
{
pt.x -= half_size_seg_len;
aBuffer.push_back( pt );
}
/* Create shape. */
int ii;
int sign = 1;
segm_count += 1; // increase segm_count to create the last half_size segment
for( ii = 0; ii < segm_count; ii++ )
{
int arc_angle;
if( ii & 1 ) /* odd order arcs are greater than 0 */
sign = -1;
else
sign = 1;
arc_angle = 1800 * sign;
centre = pt;
centre.y += radius;
gen_arc( aBuffer, pt, centre, arc_angle );
pt = aBuffer.back();
pt.x += segm_len * sign;
aBuffer.push_back( pt );
}
// The last point is false:
// it is the end of a full size segment, but must be
// the end of the second half_size segment. Change it.
sign *= -1;
aBuffer.back().x = aStartPoint.x + radius * sign;
// create last arc
pt = aBuffer.back();
centre = pt;
centre.y += radius;
gen_arc( aBuffer, pt, centre, 900 * sign ); pt = aBuffer.back();
// Rotate point
angle += 900;
for( unsigned jj = 0; jj < aBuffer.size(); jj++ )
{
RotatePoint( &aBuffer[jj].x, &aBuffer[jj].y,
aStartPoint.x, aStartPoint.y, angle );
}
// push last point (end point)
aBuffer.push_back( aEndPoint );
return 1;
} }
@ -576,8 +541,8 @@ MODULE* WinEDA_PcbFrame::Create_MuWaveBasicShape( const wxString& name,
if( Module == NULL ) if( Module == NULL )
return NULL; return NULL;
Module->m_TimeStamp = GetTimeStamp(); Module->m_TimeStamp = GetTimeStamp();
Module->m_Value->m_Size = wxSize( 30, 30 ); Module->m_Value->m_Size = wxSize( 30, 30 );
Module->m_Value->m_Pos0.y = -30; Module->m_Value->m_Pos0.y = -30;
Module->m_Value->m_Pos.y += Module->m_Value->m_Pos0.y; Module->m_Value->m_Pos.y += Module->m_Value->m_Pos0.y;
Module->m_Reference->m_Size = wxSize( 30, 30 ); Module->m_Reference->m_Size = wxSize( 30, 30 );
@ -591,8 +556,8 @@ MODULE* WinEDA_PcbFrame::Create_MuWaveBasicShape( const wxString& name,
Module->m_Pads.PushFront( pad ); Module->m_Pads.PushFront( pad );
pad->m_Size.x = pad->m_Size.y = GetBoard()->GetCurrentTrackWidth(); pad->m_Size.x = pad->m_Size.y = GetBoard()->GetCurrentTrackWidth();
pad->m_Pos = Module->m_Pos; pad->m_Pos = Module->m_Pos;
pad->m_PadShape = PAD_RECT; pad->m_PadShape = PAD_RECT;
pad->m_Attribut = PAD_SMD; pad->m_Attribut = PAD_SMD;
pad->m_Masque_Layer = LAYER_FRONT; pad->m_Masque_Layer = LAYER_FRONT;
@ -817,10 +782,10 @@ private:
BEGIN_EVENT_TABLE( WinEDA_SetParamShapeFrame, wxDialog ) BEGIN_EVENT_TABLE( WinEDA_SetParamShapeFrame, wxDialog )
EVT_BUTTON( wxID_OK, WinEDA_SetParamShapeFrame::OnOkClick ) EVT_BUTTON( wxID_OK, WinEDA_SetParamShapeFrame::OnOkClick )
EVT_BUTTON( wxID_CANCEL, WinEDA_SetParamShapeFrame::OnCancelClick ) EVT_BUTTON( wxID_CANCEL, WinEDA_SetParamShapeFrame::OnCancelClick )
EVT_BUTTON( ID_READ_SHAPE_FILE, EVT_BUTTON( ID_READ_SHAPE_FILE,
WinEDA_SetParamShapeFrame::ReadDataShapeDescr ) WinEDA_SetParamShapeFrame::ReadDataShapeDescr )
END_EVENT_TABLE() END_EVENT_TABLE()
WinEDA_SetParamShapeFrame::WinEDA_SetParamShapeFrame( WinEDA_PcbFrame* parent, WinEDA_SetParamShapeFrame::WinEDA_SetParamShapeFrame( WinEDA_PcbFrame* parent,
@ -850,11 +815,14 @@ WinEDA_SetParamShapeFrame::WinEDA_SetParamShapeFrame( WinEDA_PcbFrame* parent,
Button = Button =
new wxButton( this, ID_READ_SHAPE_FILE, new wxButton( this, ID_READ_SHAPE_FILE,
_( "Read Shape Description File..." ) ); _( "Read Shape Description File..." ) );
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 ); RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
wxString shapelist[3] = { _( "Normal" ), _( "Symmetrical" ), wxString shapelist[3] =
_( "Mirrored" ) }; {
_( "Normal" ), _( "Symmetrical" ),
_( "Mirrored" )
};
m_ShapeOptionCtrl = new wxRadioBox( this, -1, _( "Shape Option" ), m_ShapeOptionCtrl = new wxRadioBox( this, -1, _( "Shape Option" ),
wxDefaultPosition, wxDefaultSize, 3, wxDefaultPosition, wxDefaultSize, 3,
shapelist, 1, shapelist, 1,
@ -870,7 +838,7 @@ WinEDA_SetParamShapeFrame::WinEDA_SetParamShapeFrame( WinEDA_PcbFrame* parent,
} }
void WinEDA_SetParamShapeFrame::OnCancelClick( wxCommandEvent& WXUNUSED( event ) ) void WinEDA_SetParamShapeFrame::OnCancelClick( wxCommandEvent& WXUNUSED(event) )
{ {
if( PolyEdges ) if( PolyEdges )
free( PolyEdges ); free( PolyEdges );
@ -967,7 +935,7 @@ void WinEDA_SetParamShapeFrame::ReadDataShapeDescr( wxCommandEvent& event )
int index = ptbuf - PolyEdges; int index = ptbuf - PolyEdges;
bufsize *= 2; bufsize *= 2;
ptbuf = PolyEdges = (double*) realloc( ptbuf = PolyEdges = (double*) realloc(
PolyEdges, bufsize * 2 * PolyEdges, bufsize * 2 *
sizeof(double) ); sizeof(double) );
ptbuf += index; ptbuf += index;
} }
@ -1013,7 +981,7 @@ MODULE* WinEDA_PcbFrame::Create_MuWavePolygonShape()
int ii, npoints; int ii, npoints;
WinEDA_SetParamShapeFrame* frame = new WinEDA_SetParamShapeFrame( WinEDA_SetParamShapeFrame* frame = new WinEDA_SetParamShapeFrame(
this, wxPoint( -1, -1 ) ); this, wxPoint( -1, -1 ) );
int ok = frame->ShowModal(); int ok = frame->ShowModal();

View File

@ -378,7 +378,6 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
DrawPanel->DrawGridAxis( DC, GR_XOR ); DrawPanel->DrawGridAxis( DC, GR_XOR );
GetScreen()->m_GridOrigin = GetScreen()->m_Curseur; GetScreen()->m_GridOrigin = GetScreen()->m_Curseur;
DrawPanel->DrawGridAxis( DC, GR_COPY ); DrawPanel->DrawGridAxis( DC, GR_COPY );
GetScreen()->SetModify();
break; break;
default: default:

View File

@ -319,7 +319,7 @@ WinEDA_PcbFrame::WinEDA_PcbFrame( wxWindow* father,
ReCreateVToolbar(); ReCreateVToolbar();
ReCreateOptToolbar(); ReCreateOptToolbar();
ReCreateAuxVToolbar(); ReCreateMicrowaveVToolbar();
m_auimgr.SetManagedWindow( this ); m_auimgr.SetManagedWindow( this );
@ -370,6 +370,9 @@ WinEDA_PcbFrame::WinEDA_PcbFrame( wxWindow* father,
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR, m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_MANAGE_LAYERS_VERTICAL_TOOLBAR,
m_show_layer_manager_tools ); m_show_layer_manager_tools );
m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools ); m_auimgr.GetPane( wxT( "m_LayersManagerToolBar" ) ).Show( m_show_layer_manager_tools );
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_EXTRA_VERTICAL_TOOLBAR1,
m_show_microwave_tools );
m_auimgr.GetPane( wxT( "m_AuxVToolBar" ) ).Show( m_show_microwave_tools );
} }
if( DrawPanel ) if( DrawPanel )
@ -542,8 +545,7 @@ void WinEDA_PcbFrame::SaveSettings()
config->Write( PCB_SHOW_FULL_RATSNET_OPT, tmp ); config->Write( PCB_SHOW_FULL_RATSNET_OPT, tmp );
config->Write( PCB_MAGNETIC_PADS_OPT, (long) g_MagneticPadOption ); config->Write( PCB_MAGNETIC_PADS_OPT, (long) g_MagneticPadOption );
config->Write( PCB_MAGNETIC_TRACKS_OPT, (long) g_MagneticTrackOption ); config->Write( PCB_MAGNETIC_TRACKS_OPT, (long) g_MagneticTrackOption );
config->Write( SHOW_MICROWAVE_TOOLS, config->Write( SHOW_MICROWAVE_TOOLS, (long) m_show_microwave_tools );
( m_AuxVToolBar && m_AuxVToolBar->IsShown() ) ? true : false );
config->Write( SHOW_LAYER_MANAGER_TOOLS, (long)m_show_layer_manager_tools ); config->Write( SHOW_LAYER_MANAGER_TOOLS, (long)m_show_layer_manager_tools );
} }

View File

@ -14,6 +14,7 @@
enum pcbnew_ids enum pcbnew_ids
{ {
ID_MAIN_MENUBAR = ID_END_LIST, ID_MAIN_MENUBAR = ID_END_LIST,
ID_MICROWAVE_V_TOOLBAR,
ID_OPEN_MODULE_EDITOR, ID_OPEN_MODULE_EDITOR,
ID_READ_NETLIST, ID_READ_NETLIST,
ID_PCB_CIRCLE_BUTT, ID_PCB_CIRCLE_BUTT,

View File

@ -476,13 +476,13 @@ void WinEDA_PcbFrame::ReCreateVToolbar()
/* Create the auxiliary vertical right toolbar, showing tools for /* Create the auxiliary vertical right toolbar, showing tools for
* microwave applications * microwave applications
*/ */
void WinEDA_PcbFrame::ReCreateAuxVToolbar() void WinEDA_PcbFrame::ReCreateMicrowaveVToolbar()
{ {
if( m_AuxVToolBar ) if( m_AuxVToolBar )
return; return;
m_AuxVToolBar = new WinEDA_Toolbar( TOOLBAR_TOOL, this, m_AuxVToolBar = new WinEDA_Toolbar( TOOLBAR_TOOL, this,
ID_AUX_V_TOOLBAR, FALSE ); ID_MICROWAVE_V_TOOLBAR, FALSE );
// Set up toolbar // Set up toolbar
m_AuxVToolBar->AddTool( ID_PCB_MUWAVE_TOOL_SELF_CMD, wxEmptyString, m_AuxVToolBar->AddTool( ID_PCB_MUWAVE_TOOL_SELF_CMD, wxEmptyString,