symbdraw.cpp 26.2 KB
Newer Older
1 2 3 4 5
/*********************************************************************/
/*			EESchema - symbdraw.cpp									 */
/* Create, move .. graphic shapes used to build and draw a component */
/* (lines, arcs ..													 */
/*********************************************************************/
plyatov's avatar
plyatov committed
6 7

#include "fctsys.h"
8
#include "gr_basic.h"
9
#include "appl_wxstruct.h"
plyatov's avatar
plyatov committed
10
#include "common.h"
11 12
#include "class_drawpanel.h"
#include "confirm.h"
plyatov's avatar
plyatov committed
13 14 15 16 17 18 19 20
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "trigo.h"
#include "protos.h"
#include "id.h"

/* Routines locales */
21 22
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void ComputeArc( LibDrawArc* DrawItem, wxPoint ArcCentre );
23 24 25
static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel,
                                     wxDC*             DC,
                                     bool              erase );
26
static void MoveLibDrawItemAt( LibEDA_BaseStruct* DrawItem, wxPoint newpos );
plyatov's avatar
plyatov committed
27 28

/* Variables locales */
29
static int     StateDrawArc, ArcStartX, ArcStartY, ArcEndX, ArcEndY;
plyatov's avatar
plyatov committed
30
static wxPoint InitPosition, StartCursor, ItemPreviousPos;
31
static FILL_T  FlSymbol_Fill = NO_FILL;
plyatov's avatar
plyatov committed
32 33


34 35 36
/************************************/
/* class WinEDA_PartPropertiesFrame */
/************************************/
plyatov's avatar
plyatov committed
37 38 39 40 41
#include "dialog_cmp_graphic_properties.cpp"


/************************************************************/
void WinEDA_bodygraphics_PropertiesFrame::
42
bodygraphics_PropertiesAccept( wxCommandEvent& event )
plyatov's avatar
plyatov committed
43
/************************************************************/
44

plyatov's avatar
plyatov committed
45
/* Update the current draw item
46
 */
plyatov's avatar
plyatov committed
47
{
48 49
    g_FlDrawSpecificConvert = m_CommonConvert->GetValue() ? FALSE : TRUE;
    g_FlDrawSpecificUnit    = m_CommonUnit->GetValue() ? FALSE : TRUE;
50

51
    if( m_Filled )
52 53
        FlSymbol_Fill = (FILL_T) m_Filled->GetSelection();

54 55 56 57 58 59 60 61 62 63
    g_LibSymbolDefaultLineWidth = m_GraphicShapeWidthCtrl->GetValue();

    if( CurrentDrawItem )
    {
        if( !(CurrentDrawItem->m_Flags & IS_NEW) )  // if IS_NEW, copy for undo is done before place
            m_Parent->SaveCopyInUndoList( CurrentLibEntry );
        wxClientDC dc( m_Parent->DrawPanel );

        m_Parent->DrawPanel->PrepareGraphicContext( &dc );

64 65 66 67 68 69
        DrawLibraryDrawStruct( m_Parent->DrawPanel,
                               &dc,
                               CurrentLibEntry,
                               wxPoint( 0, 0 ),
                               CurrentDrawItem,
                               g_XorMode );
70 71 72 73 74 75 76 77 78 79 80

        if( g_FlDrawSpecificUnit )
            CurrentDrawItem->m_Unit = CurrentUnit;
        else
            CurrentDrawItem->m_Unit = 0;
        if( g_FlDrawSpecificConvert )
            CurrentDrawItem->m_Convert = CurrentConvert;
        else
            CurrentDrawItem->m_Convert = 0;
        if( m_Filled  )
        {
81
            switch( CurrentDrawItem->Type() )
82 83 84
            {
            case COMPONENT_ARC_DRAW_TYPE:
                ( (LibDrawArc*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
85 86
                ( (LibDrawArc*) CurrentDrawItem )->m_Width =
                    m_GraphicShapeWidthCtrl->GetValue();
87 88 89 90
                break;

            case COMPONENT_CIRCLE_DRAW_TYPE:
                ( (LibDrawCircle*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
91 92
                ( (LibDrawCircle*) CurrentDrawItem )->m_Width =
                    m_GraphicShapeWidthCtrl->GetValue();
93 94 95 96
                break;

            case COMPONENT_RECT_DRAW_TYPE:
                ( (LibDrawSquare*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
97 98
                ( (LibDrawSquare*) CurrentDrawItem )->m_Width =
                    m_GraphicShapeWidthCtrl->GetValue();
99 100 101
                break;

            case  COMPONENT_POLYLINE_DRAW_TYPE:
102 103 104 105 106
                ( (LibDrawPolyline*) CurrentDrawItem )->m_Fill =
                    FlSymbol_Fill;
                ( (LibDrawPolyline*) CurrentDrawItem )->m_Width =
                    m_GraphicShapeWidthCtrl->
                    GetValue();
107 108 109 110 111 112 113 114
                break;

            default:
                break;
            }
        }
        CurrentLibEntry->SortDrawItems();

115
        m_Parent->GetScreen()->SetModify();
116

117 118 119 120 121 122
        DrawLibraryDrawStruct( m_Parent->DrawPanel,
                               &dc,
                               CurrentLibEntry,
                               wxPoint( 0, 0 ),
                               CurrentDrawItem,
                               g_XorMode );
123 124 125 126 127 128
    }

    Close();

    if( CurrentDrawItem )
        CurrentDrawItem->Display_Infos_DrawEntry( m_Parent );
129
    m_Parent->DrawPanel->Refresh();
plyatov's avatar
plyatov committed
130 131
}

132

plyatov's avatar
plyatov committed
133
/**********************************************************/
134 135
void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC*              DC,
                                             LibEDA_BaseStruct* DrawItem )
plyatov's avatar
plyatov committed
136
/**********************************************************/
137

plyatov's avatar
plyatov committed
138
/* Install the dialog box for editing a graphical item properties
139
 */
plyatov's avatar
plyatov committed
140
{
141 142 143
    if( DrawItem == NULL )
        return;

144 145
    WinEDA_bodygraphics_PropertiesFrame* frame =
        new WinEDA_bodygraphics_PropertiesFrame( this );
146 147

    frame->ShowModal(); frame->Destroy();
plyatov's avatar
plyatov committed
148 149 150 151
}


/****************************************************************/
152
static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC )
plyatov's avatar
plyatov committed
153 154
/****************************************************************/
{
155 156 157 158 159 160 161 162
    StateDrawArc = 0;
    Panel->ManageCurseur = NULL;
    Panel->ForceCloseManageCurseur = NULL;
    if( CurrentDrawItem == NULL )
        return;

    if( CurrentDrawItem->m_Flags & IS_NEW )
    {
163
        if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
164 165 166 167
        {
            Panel->m_Parent->RedrawActiveWindow( DC, TRUE );
        }
        else
168
            DrawLibraryDrawStruct( Panel, DC, CurrentLibEntry, wxPoint( 0, 0 ),
charras's avatar
charras committed
169
                                   CurrentDrawItem, g_XorMode );
170
        SAFE_DELETE( CurrentDrawItem );
171 172 173 174 175 176 177 178
    }
    else
    {
        wxPoint             curpos;
        curpos = Panel->GetScreen()->m_Curseur;
        Panel->GetScreen()->m_Curseur = StartCursor;
        RedrawWhileMovingCursor( Panel, DC, TRUE );
        Panel->GetScreen()->m_Curseur = curpos;
179
        DrawLibraryDrawStruct( Panel, DC, CurrentLibEntry, wxPoint( 0, 0 ),
charras's avatar
charras committed
180
                               CurrentDrawItem, GR_DEFAULT_DRAWMODE );
181 182 183

        CurrentDrawItem->m_Flags = 0;
    }
plyatov's avatar
plyatov committed
184 185 186 187
}


/*********************************************************************/
188
LibEDA_BaseStruct* WinEDA_LibeditFrame::CreateGraphicItem( wxDC* DC )
plyatov's avatar
plyatov committed
189
/*********************************************************************/
190

plyatov's avatar
plyatov committed
191
/* Routine de creation d'un nouvel element type LibraryDrawStruct
192 193
 *  POLYLINE
 *  ARC
dickelbeck's avatar
dickelbeck committed
194 195
 *  PAD_CIRCLE
 *  PAD_RECTANGLE
196
 */
plyatov's avatar
plyatov committed
197
{
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    int  DrawType;

    DrawPanel->m_IgnoreMouseEvents = TRUE;

    // Creation du nouvel element
    switch( m_ID_current_state )
    {
    case ID_LIBEDIT_BODY_LINE_BUTT:
        DrawType = COMPONENT_POLYLINE_DRAW_TYPE;
        break;

    case ID_LIBEDIT_BODY_ARC_BUTT:
        DrawType = COMPONENT_ARC_DRAW_TYPE;
        break;

    case ID_LIBEDIT_BODY_CIRCLE_BUTT:
        DrawType = COMPONENT_CIRCLE_DRAW_TYPE;
        break;

    case ID_LIBEDIT_BODY_RECT_BUTT:
        DrawType = COMPONENT_RECT_DRAW_TYPE;
        break;

    case ID_LIBEDIT_BODY_TEXT_BUTT:
        DrawType = COMPONENT_GRAPHIC_TEXT_DRAW_TYPE;
        break;

    default:
        DisplayError( this, wxT( "SymbolBeginDrawItem Internal err: Id error" ) );
        return NULL;
    }

    DrawPanel->ManageCurseur = SymbolDisplayDraw;
    DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;

    switch( DrawType )
    {
    case COMPONENT_ARC_DRAW_TYPE:
    {
        LibDrawArc* Arc = new LibDrawArc();

        CurrentDrawItem = Arc;
240 241
        ArcStartX    = ArcEndX = GetScreen()->m_Curseur.x;
        ArcStartY    = ArcEndY = -( GetScreen()->m_Curseur.y );
242 243 244 245
        StateDrawArc = 1;
        Arc->m_Fill  = FlSymbol_Fill;
        Arc->m_Width = g_LibSymbolDefaultLineWidth;
    }
246
    break;
247 248 249 250 251 252

    case COMPONENT_CIRCLE_DRAW_TYPE:
    {
        LibDrawCircle* Circle = new LibDrawCircle();

        CurrentDrawItem = Circle;
253 254
        Circle->m_Pos.x = GetScreen()->m_Curseur.x;
        Circle->m_Pos.y = -( GetScreen()->m_Curseur.y );
255 256 257
        Circle->m_Fill  = FlSymbol_Fill;
        Circle->m_Width = g_LibSymbolDefaultLineWidth;
    }
258
    break;
259 260 261 262 263 264

    case COMPONENT_RECT_DRAW_TYPE:
    {
        LibDrawSquare* Square = new LibDrawSquare();

        CurrentDrawItem = Square;
265 266
        Square->m_Pos.x = GetScreen()->m_Curseur.x;
        Square->m_Pos.y = -( GetScreen()->m_Curseur.y );
267 268 269 270
        Square->m_End   = Square->m_Pos;
        Square->m_Fill  = FlSymbol_Fill;
        Square->m_Width = g_LibSymbolDefaultLineWidth;
    }
271
    break;
272 273 274 275 276

    case COMPONENT_POLYLINE_DRAW_TYPE:
    {
        LibDrawPolyline* polyline = new LibDrawPolyline();
        CurrentDrawItem = polyline;
charras's avatar
charras committed
277 278 279 280
        wxPoint point = GetScreen()->m_Curseur;
        NEGATE( point.y );
        polyline->AddPoint( point );    // Start point of the current segment
        polyline->AddPoint( point );    // End point of the current segment
281 282 283
        polyline->m_Fill  = FlSymbol_Fill;
        polyline->m_Width = g_LibSymbolDefaultLineWidth;
    }
284
    break;
285 286 287 288 289 290

    case COMPONENT_LINE_DRAW_TYPE:
    {
        LibDrawSegment* Segment = new LibDrawSegment();

        CurrentDrawItem  = Segment;
291 292
        Segment->m_Pos.x = GetScreen()->m_Curseur.x;
        Segment->m_Pos.y = -( GetScreen()->m_Curseur.y );
293 294 295
        Segment->m_End   = Segment->m_Pos;
        Segment->m_Width = g_LibSymbolDefaultLineWidth;
    }
296
    break;
297 298 299 300 301 302 303

    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
    {
        LibDrawText* Text = new LibDrawText();

        CurrentDrawItem = Text;
        Text->m_Size.x  = Text->m_Size.y = g_LastTextSize;
304
        Text->m_Orient  = g_LastTextOrient;
305 306
        Text->m_Pos.x   = GetScreen()->m_Curseur.x;
        Text->m_Pos.y   = -( GetScreen()->m_Curseur.y );
307 308 309
        EditSymbolText( NULL, Text );
        if( Text->m_Text.IsEmpty() )
        {
310
            SAFE_DELETE( Text );
311 312 313 314 315 316 317
            CurrentDrawItem = NULL;
            DrawPanel->ManageCurseur = NULL;
            DrawPanel->ForceCloseManageCurseur = NULL;
        }
        else
        {
            StartMoveDrawSymbol( DC );
318 319
            DrawLibraryDrawStruct( DrawPanel, DC, CurrentLibEntry,
                                   wxPoint( 0, 0 ),
charras's avatar
charras committed
320
                                   Text, g_XorMode );
321 322
        }
    }
323
    break;
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
    }

    if( CurrentDrawItem )
    {
        CurrentDrawItem->m_Flags |= IS_NEW;
        if( g_FlDrawSpecificUnit )
            CurrentDrawItem->m_Unit = CurrentUnit;
        if( g_FlDrawSpecificConvert )
            CurrentDrawItem->m_Convert = CurrentConvert;
    }

    DrawPanel->MouseToCursorSchema();
    DrawPanel->m_IgnoreMouseEvents = FALSE;

    return CurrentDrawItem;
plyatov's avatar
plyatov committed
339 340 341 342
}


/********************************************************/
343
void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC )
plyatov's avatar
plyatov committed
344
/********************************************************/
345

plyatov's avatar
plyatov committed
346
/* Routine de creation d'un nouvel element type LibraryDrawStruct
347
 */
plyatov's avatar
plyatov committed
348
{
349 350 351
    if( CurrentDrawItem == NULL )
        return;

352
    switch( CurrentDrawItem->Type() )
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
    {
    case COMPONENT_ARC_DRAW_TYPE:
        if( StateDrawArc == 1 )
        {
            SymbolDisplayDraw( DrawPanel, DC, FALSE );
            StateDrawArc = 2;
            SymbolDisplayDraw( DrawPanel, DC, FALSE );
            break;
        }
        if( StateDrawArc > 1 )
        {
            EndDrawGraphicItem( DC );
            return;
        }
        break;

    case COMPONENT_CIRCLE_DRAW_TYPE:
    case COMPONENT_RECT_DRAW_TYPE:
    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
        EndDrawGraphicItem( DC );
        return;

    case COMPONENT_POLYLINE_DRAW_TYPE:
    {
377
        wxPoint pos = GetScreen()->m_Curseur;
charras's avatar
charras committed
378
        NEGATE(pos.y);
379 380
        ( (LibDrawPolyline*) CurrentDrawItem )->AddPoint( pos );
    }
381
    break;
382 383 384 385 386 387 388

    case COMPONENT_LINE_DRAW_TYPE:
        break;

    default:
        ;
    }
plyatov's avatar
plyatov committed
389 390
}

391

plyatov's avatar
plyatov committed
392
/**************************************************************************/
393 394 395
static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel,
                                     wxDC*             DC,
                                     bool              erase )
plyatov's avatar
plyatov committed
396
/**************************************************************************/
397

398
/* Redraw the graphoc shape while moving
399
 */
plyatov's avatar
plyatov committed
400
{
401
    BASE_SCREEN* Screen = panel->GetScreen();
402
    wxPoint      pos;
403 404 405 406

    /* Erase shape in the old positon*/
    if( erase )
    {
charras's avatar
charras committed
407 408 409
        pos = ItemPreviousPos - StartCursor,
        DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, pos,
                               CurrentDrawItem, g_XorMode );
410 411 412
    }

    /* Redraw moved shape */
charras's avatar
charras committed
413 414 415
    pos = Screen->m_Curseur - StartCursor,
    DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, pos,
                           CurrentDrawItem, g_XorMode );
416
    ItemPreviousPos = Screen->m_Curseur;
plyatov's avatar
plyatov committed
417 418 419 420
}


/*****************************************************************/
421
void MoveLibDrawItemAt( LibEDA_BaseStruct* DrawItem, wxPoint newpos )
plyatov's avatar
plyatov committed
422 423
/*****************************************************************/
{
charras's avatar
charras committed
424 425
    NEGATE(newpos.y);
    wxPoint size;
426

427
    switch( DrawItem->Type() )
428 429 430
    {
    case COMPONENT_ARC_DRAW_TYPE:
    {
charras's avatar
charras committed
431 432 433 434
        wxPoint offset = newpos - ( (LibDrawArc*) CurrentDrawItem )->m_Pos;
        ( (LibDrawArc*) CurrentDrawItem )->m_Pos = newpos;
        ( (LibDrawArc*) CurrentDrawItem )->m_ArcStart += offset;
        ( (LibDrawArc*) CurrentDrawItem )->m_ArcEnd   += offset;
435 436 437 438
        break;
    }

    case COMPONENT_CIRCLE_DRAW_TYPE:
charras's avatar
charras committed
439
        ( (LibDrawCircle*) CurrentDrawItem )->m_Pos = newpos;
440 441 442
        break;

    case COMPONENT_RECT_DRAW_TYPE:
charras's avatar
charras committed
443 444 445
        size = ( (LibDrawSquare*) CurrentDrawItem )->m_End - ( (LibDrawSquare*) CurrentDrawItem )->m_Pos;
        ( (LibDrawSquare*) CurrentDrawItem )->m_Pos = newpos;
        ( (LibDrawSquare*) CurrentDrawItem )->m_End = newpos + size;
446 447 448 449
        break;

    case COMPONENT_POLYLINE_DRAW_TYPE:
    {
charras's avatar
charras committed
450 451
        int  ii, imax = ( (LibDrawPolyline*) CurrentDrawItem )->GetCornerCount();
        wxPoint offset = newpos - ( (LibDrawPolyline*) CurrentDrawItem )->m_PolyPoints[0];
452
        for( ii = 0; ii < imax; ii ++ )
charras's avatar
charras committed
453
            ( (LibDrawPolyline*) CurrentDrawItem )->m_PolyPoints[ii] += offset;
454
    }
455
    break;
456 457 458 459 460

    case COMPONENT_LINE_DRAW_TYPE:
        break;

    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
charras's avatar
charras committed
461
        ( (LibDrawText*) CurrentDrawItem )->m_Pos = newpos;
462 463 464 465 466
        break;

    default:
        ;
    }
plyatov's avatar
plyatov committed
467 468
}

469

plyatov's avatar
plyatov committed
470
/************************************************************/
471
void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC )
plyatov's avatar
plyatov committed
472 473
/************************************************************/
{
474 475
    if( CurrentDrawItem == NULL )
        return;
plyatov's avatar
plyatov committed
476

477
    SetCursor( wxCURSOR_HAND );
plyatov's avatar
plyatov committed
478

479
    CurrentDrawItem->m_Flags |= IS_MOVED;
480
    StartCursor = GetScreen()->m_Curseur;
plyatov's avatar
plyatov committed
481

482
    switch( CurrentDrawItem->Type() )
483 484 485 486
    {
    case COMPONENT_ARC_DRAW_TYPE:
        InitPosition = ( (LibDrawArc*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
487

488 489 490
    case COMPONENT_CIRCLE_DRAW_TYPE:
        InitPosition = ( (LibDrawCircle*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
491

492 493 494
    case COMPONENT_RECT_DRAW_TYPE:
        InitPosition = ( (LibDrawSquare*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
495

496
    case COMPONENT_POLYLINE_DRAW_TYPE:
charras's avatar
charras committed
497
        InitPosition = ( (LibDrawPolyline*) CurrentDrawItem )->m_PolyPoints[0];
498
        break;
plyatov's avatar
plyatov committed
499

500 501
    case COMPONENT_LINE_DRAW_TYPE:
        break;
plyatov's avatar
plyatov committed
502

503 504 505
    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
        InitPosition = ( (LibDrawText*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
506

507 508 509
    default:
        ;
    }
plyatov's avatar
plyatov committed
510

511
    ItemPreviousPos = GetScreen()->m_Curseur;
512 513 514 515
    DrawPanel->ManageCurseur = RedrawWhileMovingCursor;
    DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
    DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
}
plyatov's avatar
plyatov committed
516 517 518 519 520 521


/****************************************************************/
/* Routine de Gestion des evenements souris lors de la creation */
/* d'un nouvel element type LibraryDrawStruct					*/
/****************************************************************/
522
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
plyatov's avatar
plyatov committed
523
{
524 525
    int          DrawMode = g_XorMode;
    int          dx, dy;
526
    BASE_SCREEN* Screen = panel->GetScreen();
charras's avatar
charras committed
527 528 529
    wxPoint curr_pos = Screen->m_Curseur;

    NEGATE(curr_pos.y);
530 531 532 533 534 535 536 537

    GRSetDrawMode( DC, DrawMode );

    if( erase )
    {
        if( StateDrawArc == 1 )
        {
            int Color = ReturnLayerColor( LAYER_DEVICE );
538 539 540 541 542 543 544 545
            GRLine( &panel->m_ClipBox,
                    DC,
                    ArcStartX,
                    -ArcStartY,
                    ArcEndX,
                    -ArcEndY,
                    0,
                    Color );
546 547 548
        }
        else
        {
549
            DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, wxPoint( 0, 0 ),
charras's avatar
charras committed
550
                                   CurrentDrawItem, DrawMode );
551
            if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
552 553 554 555 556 557 558 559 560 561 562 563 564 565
            {
                int Color = ReturnLayerColor( LAYER_DEVICE );
                GRDashedLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY,
                              ( (LibDrawArc*) CurrentDrawItem )->m_Pos.x,
                              -( (LibDrawArc*) CurrentDrawItem )->m_Pos.y,
                              0, Color );
                GRDashedLine( &panel->m_ClipBox, DC, ArcEndX, -ArcEndY,
                              ( (LibDrawArc*) CurrentDrawItem )->m_Pos.x,
                              -( (LibDrawArc*) CurrentDrawItem )->m_Pos.y,
                              0, Color );
            }
        }
    }

566
    switch( CurrentDrawItem->Type() )
567 568 569 570
    {
    case COMPONENT_ARC_DRAW_TYPE:
        if( StateDrawArc == 1 )
        {
charras's avatar
charras committed
571
            ArcEndX = curr_pos.x; ArcEndY = curr_pos.y;
572 573 574 575 576 577 578 579 580 581
        }

        if( StateDrawArc == 2 )
        {
            ComputeArc( (LibDrawArc*) CurrentDrawItem, Screen->m_Curseur );
        }
        ( (LibDrawArc*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
        break;

    case COMPONENT_CIRCLE_DRAW_TYPE:
charras's avatar
charras committed
582 583
        dx = ( (LibDrawCircle*) CurrentDrawItem )->m_Pos.x - curr_pos.x;
        dy = ( (LibDrawCircle*) CurrentDrawItem )->m_Pos.y - curr_pos.y;
584 585 586
        ( (LibDrawCircle*) CurrentDrawItem )->m_Rayon =
            (int) sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
        ( (LibDrawCircle*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
587 588 589
        break;

    case COMPONENT_RECT_DRAW_TYPE:
charras's avatar
charras committed
590
        ( (LibDrawSquare*) CurrentDrawItem )->m_End = curr_pos;
591 592 593 594
        ( (LibDrawSquare*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
        break;

    case COMPONENT_POLYLINE_DRAW_TYPE:
charras's avatar
charras committed
595 596 597
    {
        unsigned idx = ( (LibDrawPolyline*) CurrentDrawItem )->GetCornerCount() - 1;
        ( (LibDrawPolyline*) CurrentDrawItem )->m_PolyPoints[idx] = curr_pos;
598
        ( (LibDrawPolyline*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
charras's avatar
charras committed
599
    }
600 601 602
        break;

    case COMPONENT_LINE_DRAW_TYPE:
charras's avatar
charras committed
603
        ( (LibDrawSegment*) CurrentDrawItem )->m_End = curr_pos;
604 605 606 607 608 609 610 611 612 613 614 615
        break;

    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:      /* Traite par des routines specifiques */
        break;

    default:
        ;
    }

    if( StateDrawArc == 1 )
    {
        int Color = ReturnLayerColor( LAYER_DEVICE );
616 617 618 619 620 621 622 623
        GRLine( &panel->m_ClipBox,
                DC,
                ArcStartX,
                -ArcStartY,
                ArcEndX,
                -ArcEndY,
                0,
                Color );
624 625 626
    }
    else
    {
627
        DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, wxPoint( 0, 0 ),
charras's avatar
charras committed
628
                               CurrentDrawItem, DrawMode );
629
        if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
630 631 632 633 634 635 636 637 638 639 640 641
        {
            int Color = ReturnLayerColor( LAYER_DEVICE );
            GRDashedLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY,
                          ( (LibDrawArc*) CurrentDrawItem )->m_Pos.x,
                          -( (LibDrawArc*) CurrentDrawItem )->m_Pos.y,
                          0, Color );
            GRDashedLine( &panel->m_ClipBox, DC, ArcEndX, -ArcEndY,
                          ( (LibDrawArc*) CurrentDrawItem )->m_Pos.x,
                          -( (LibDrawArc*) CurrentDrawItem )->m_Pos.y,
                          0, Color );
        }
    }
plyatov's avatar
plyatov committed
642 643 644 645
}


/******************************************************/
646
void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
plyatov's avatar
plyatov committed
647
/******************************************************/
648

plyatov's avatar
plyatov committed
649
/* Place la structure courante en liste des structures du composant
650 651 652 653 654
 *  courant, si elle existe et redessine toujours celle ci
 *  Parametres: (tous globaux)
 *      CurrentDrawItem
 *      CurrentLibEntry
 */
plyatov's avatar
plyatov committed
655
{
656 657 658 659 660
    if( CurrentLibEntry == NULL )
        return;
    if( CurrentDrawItem == NULL )
        return;

661
    if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
    {
        if( StateDrawArc == 1 ) /* Trace d'arc en cours: doit etre termine */
        {
            DisplayError( this, wxT( "Arc in progress.." ), 10 ); return;
        }
        else
        {
            if( (CurrentDrawItem->m_Flags & IS_MOVED) == 0 )
                SymbolDisplayDraw( DrawPanel, DC, FALSE );
        }
    }

    StateDrawArc = 0;

    if( CurrentDrawItem->m_Flags & IS_NEW )
    {
        SaveCopyInUndoList( CurrentLibEntry );
679
        CurrentDrawItem->SetNext( CurrentLibEntry->m_Drawings );
680 681
        CurrentLibEntry->m_Drawings = CurrentDrawItem;

682
        switch( CurrentDrawItem->Type() )
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
        {
        case COMPONENT_ARC_DRAW_TYPE:
            ( (LibDrawArc*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
            break;

        case COMPONENT_CIRCLE_DRAW_TYPE:
            ( (LibDrawCircle*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
            break;

        case COMPONENT_RECT_DRAW_TYPE:
            ( (LibDrawSquare*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
            break;

        case COMPONENT_POLYLINE_DRAW_TYPE:
            ( (LibDrawPolyline*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
            break;

        case COMPONENT_PIN_DRAW_TYPE:
        case COMPONENT_LINE_DRAW_TYPE:
        case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
            break;

        default:
            ;
        }

        CurrentLibEntry->SortDrawItems();
    }

    if( m_ID_current_state )
        SetCursor( wxCURSOR_PENCIL );
    else
        SetCursor( wxCURSOR_ARROW );

    if( (CurrentDrawItem->m_Flags & IS_MOVED) )
    {
        wxPoint pos;
        pos.x = GetScreen()->m_Curseur.x + InitPosition.x - StartCursor.x,
        pos.y = GetScreen()->m_Curseur.y - InitPosition.y - StartCursor.y;
        MoveLibDrawItemAt( CurrentDrawItem, pos );
    }

725
    DrawLibEntry( DrawPanel, DC, CurrentLibEntry, wxPoint( 0, 0 ), CurrentUnit,
726 727 728 729 730
                  CurrentConvert, GR_DEFAULT_DRAWMODE );

    CurrentDrawItem->m_Flags = 0;
    CurrentDrawItem = NULL;

731
    GetScreen()->SetModify();
732 733 734

    DrawPanel->ManageCurseur = NULL;
    DrawPanel->ForceCloseManageCurseur = NULL;
plyatov's avatar
plyatov committed
735 736 737 738
}


/***************************************************************/
739
static void ComputeArc( LibDrawArc* DrawItem, wxPoint ArcCentre )
plyatov's avatar
plyatov committed
740
/***************************************************************/
741

plyatov's avatar
plyatov committed
742
/* routine d'ajustage des parametres de l'arc en cours de trace
743 744 745 746 747
 *  calcule le centre, rayon, angles pour que l'arc en cours
 *  passe par les points ArcStartX,Y et ArcEndX,Y avec le centre le plus proche
 *  de la pos souris
 *  Remarque: le centre n'est evidemment pas sur la grille
 */
plyatov's avatar
plyatov committed
748
{
749 750 751 752 753 754 755 756 757 758 759
    int dx, dy;
    int cX, cY;     /* Coord centre de l'arc */
    int angle;

    cX = ArcCentre.x; cY = ArcCentre.y;

    cY = -cY;   /* Attention a l'orientation de l'axe Y */

    /* calcul de cX et cY pour que l'arc passe par ArcStartX,Y et ArcEndX,Y */
    dx    = ArcEndX - ArcStartX; dy = ArcEndY - ArcStartY;
    cX   -= ArcStartX; cY -= ArcStartY;
760 761 762
    angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
    RotatePoint( &dx, &dy, angle );     /* Le segment dx, dy est horizontal */
                                        /* -> dx = longueur, dy = 0 */
763
    RotatePoint( &cX, &cY, angle );
764
    cX = dx / 2;                        /* cX, cY est sur la mediane du segment 0,0 a dx,0 */
765 766 767 768 769 770 771 772 773

    RotatePoint( &cX, &cY, -angle );
    cX += ArcStartX; cY += ArcStartY;

    DrawItem->m_Pos.x = cX; DrawItem->m_Pos.y = cY;

    dx = ArcStartX - DrawItem->m_Pos.x;
    dy = ArcStartY - DrawItem->m_Pos.y;

774
    DrawItem->m_Rayon = (int) sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
775

776
    DrawItem->t1 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
777 778 779

    dx = ArcEndX - DrawItem->m_Pos.x;
    dy = ArcEndY - DrawItem->m_Pos.y;
plyatov's avatar
plyatov committed
780

781
    DrawItem->t2 = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801

    DrawItem->m_ArcStart.x = ArcStartX;
    DrawItem->m_ArcStart.y = ArcStartY;
    DrawItem->m_ArcEnd.x   = ArcEndX;
    DrawItem->m_ArcEnd.y   = ArcEndY;

    NORMALIZE_ANGLE( DrawItem->t1 );
    NORMALIZE_ANGLE( DrawItem->t2 );  // angles = 0 .. 3600

    // limitation val abs a < 1800 (1/2 cercle) pour eviter Pbs d'affichage en miroir
    // car en trace on suppose que l'arc fait moins de 180 deg pour trouver
    // son orientation apres rot, miroir...
    if( (DrawItem->t2 - DrawItem->t1) > 1800 )
        DrawItem->t2 -= 3600;
    else if( (DrawItem->t2 - DrawItem->t1) <= -1800 )
        DrawItem->t2 += 3600;

    wxString msg;
    angle = DrawItem->t2 - DrawItem->t1;
    msg.Printf( _( "Arc %.1f deg" ), (float) angle / 10 );
802 803 804
    WinEDA_SchematicFrame* frame =
        (WinEDA_SchematicFrame*) wxGetApp().GetTopWindow();
    frame->m_LibeditFrame->PrintMsg( msg );
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819

    while( (DrawItem->t2 - DrawItem->t1) >= 1800 )
    {
        DrawItem->t2--;
        DrawItem->t1++;
    }

    while( (DrawItem->t1 - DrawItem->t2) >= 1800 )
    {
        DrawItem->t2++;
        DrawItem->t1--;
    }

    NORMALIZE_ANGLE( DrawItem->t1 );
    NORMALIZE_ANGLE( DrawItem->t2 );
plyatov's avatar
plyatov committed
820 821
}

822

plyatov's avatar
plyatov committed
823
/***************************************************/
824
void WinEDA_LibeditFrame::DeleteDrawPoly( wxDC* DC )
plyatov's avatar
plyatov committed
825
/**************************************************/
826

plyatov's avatar
plyatov committed
827
/* Used for deleting last entered segment while creating a Polyline
828
 */
plyatov's avatar
plyatov committed
829
{
830 831
    if( CurrentDrawItem == NULL )
        return;
832
    if( CurrentDrawItem->Type() != COMPONENT_POLYLINE_DRAW_TYPE )
833 834 835 836
        return;

    LibDrawPolyline* Poly = (LibDrawPolyline*) CurrentDrawItem;

837
    DrawLibraryDrawStruct( DrawPanel, DC, CurrentLibEntry, wxPoint( 0, 0 ),
charras's avatar
charras committed
838
                           CurrentDrawItem, g_XorMode );
839

charras's avatar
charras committed
840
    while ( Poly->GetCornerCount() > 2 )    // First segment is kept, only its end point is changed
841
    {
charras's avatar
charras committed
842 843 844 845 846
        Poly->m_PolyPoints.pop_back();
        unsigned idx =  Poly->GetCornerCount() - 1;
        wxPoint point = GetScreen()->m_Curseur;
        NEGATE( point.y );
        if( Poly->m_PolyPoints[idx] != point )
847
        {
charras's avatar
charras committed
848
            Poly->m_PolyPoints[idx] = point;
849 850 851 852
            break;
        }
    }

853
    DrawLibraryDrawStruct( DrawPanel, DC, CurrentLibEntry, wxPoint( 0, 0 ),
charras's avatar
charras committed
854
                           CurrentDrawItem, g_XorMode );
plyatov's avatar
plyatov committed
855
}