symbdraw.cpp 26.3 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 8 9 10 11 12 13 14 15 16 17 18 19 20 21


#include "fctsys.h"
#include "gr_basic.h"

#include "common.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "trigo.h"

#include "protos.h"

#include "id.h"

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

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


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


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

plyatov's avatar
plyatov committed
44
/* Update the current draw item
45
 */
plyatov's avatar
plyatov committed
46
{
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    g_FlDrawSpecificConvert = m_CommonConvert->GetValue() ? FALSE : TRUE;
    g_FlDrawSpecificUnit    = m_CommonUnit->GetValue() ? FALSE : TRUE;
    if( m_Filled )
        FlSymbol_Fill = m_Filled->GetSelection();
    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 );

        DrawLibraryDrawStruct( m_Parent->DrawPanel, &dc, CurrentLibEntry, 0, 0,
                               CurrentDrawItem, CurrentUnit, g_XorMode );

        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  )
        {
74
            switch( CurrentDrawItem->Type() )
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
            {
            case COMPONENT_ARC_DRAW_TYPE:
                ( (LibDrawArc*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
                ( (LibDrawArc*) CurrentDrawItem )->m_Width = m_GraphicShapeWidthCtrl->GetValue();
                break;

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

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

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

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

103
		m_Parent->GetScreen()->SetModify();
104 105 106 107 108 109 110 111 112 113

        DrawLibraryDrawStruct( m_Parent->DrawPanel, &dc, CurrentLibEntry, 0, 0,
                               CurrentDrawItem, CurrentUnit, g_XorMode );
    }

    Close();

    if( CurrentDrawItem )
        CurrentDrawItem->Display_Infos_DrawEntry( m_Parent );
    m_Parent->ReDrawPanel();
plyatov's avatar
plyatov committed
114 115
}

116

plyatov's avatar
plyatov committed
117
/**********************************************************/
118 119
void WinEDA_LibeditFrame::EditGraphicSymbol( wxDC*              DC,
                                             LibEDA_BaseStruct* DrawItem )
plyatov's avatar
plyatov committed
120
/**********************************************************/
121

plyatov's avatar
plyatov committed
122
/* Install the dialog box for editing a graphical item properties
123
 */
plyatov's avatar
plyatov committed
124
{
125 126 127 128 129 130
    if( DrawItem == NULL )
        return;

    WinEDA_bodygraphics_PropertiesFrame* frame = new WinEDA_bodygraphics_PropertiesFrame( this );

    frame->ShowModal(); frame->Destroy();
plyatov's avatar
plyatov committed
131 132 133 134
}


/****************************************************************/
135
static void AbortSymbolTraceOn( WinEDA_DrawPanel* Panel, wxDC* DC )
plyatov's avatar
plyatov committed
136 137
/****************************************************************/
{
138 139 140 141 142 143 144 145
    StateDrawArc = 0;
    Panel->ManageCurseur = NULL;
    Panel->ForceCloseManageCurseur = NULL;
    if( CurrentDrawItem == NULL )
        return;

    if( CurrentDrawItem->m_Flags & IS_NEW )
    {
146
        if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
147 148 149 150 151 152
        {
            Panel->m_Parent->RedrawActiveWindow( DC, TRUE );
        }
        else
            DrawLibraryDrawStruct( Panel, DC, CurrentLibEntry, 0, 0,
                                   CurrentDrawItem, CurrentUnit, g_XorMode );
153
		SAFE_DELETE( CurrentDrawItem );
154 155 156 157 158 159 160 161 162 163 164 165 166
    }
    else
    {
        wxPoint             curpos;
        curpos = Panel->GetScreen()->m_Curseur;
        Panel->GetScreen()->m_Curseur = StartCursor;
        RedrawWhileMovingCursor( Panel, DC, TRUE );
        Panel->GetScreen()->m_Curseur = curpos;
        DrawLibraryDrawStruct( Panel, DC, CurrentLibEntry, 0, 0,
                               CurrentDrawItem, CurrentUnit, GR_DEFAULT_DRAWMODE );

        CurrentDrawItem->m_Flags = 0;
    }
plyatov's avatar
plyatov committed
167 168 169 170
}


/*********************************************************************/
171
LibEDA_BaseStruct* WinEDA_LibeditFrame::CreateGraphicItem( wxDC* DC )
plyatov's avatar
plyatov committed
172
/*********************************************************************/
173

plyatov's avatar
plyatov committed
174
/* Routine de creation d'un nouvel element type LibraryDrawStruct
175 176
 *  POLYLINE
 *  ARC
dickelbeck's avatar
dickelbeck committed
177 178
 *  PAD_CIRCLE
 *  PAD_RECTANGLE
179
 */
plyatov's avatar
plyatov committed
180
{
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 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
    int  DrawType;
    int* ptpoly;

    if( CurrentDrawItem )
        return NULL;

    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;
227 228
		ArcStartX    = ArcEndX = GetScreen()->m_Curseur.x;
		ArcStartY    = ArcEndY = -( GetScreen()->m_Curseur.y );
229 230 231 232 233 234 235 236 237 238 239
        StateDrawArc = 1;
        Arc->m_Fill  = FlSymbol_Fill;
        Arc->m_Width = g_LibSymbolDefaultLineWidth;
    }
        break;

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

        CurrentDrawItem = Circle;
240 241
		Circle->m_Pos.x = GetScreen()->m_Curseur.x;
		Circle->m_Pos.y = -( GetScreen()->m_Curseur.y );
242 243 244 245 246 247 248 249 250 251
        Circle->m_Fill  = FlSymbol_Fill;
        Circle->m_Width = g_LibSymbolDefaultLineWidth;
    }
        break;

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

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

    case COMPONENT_POLYLINE_DRAW_TYPE:
    {
        LibDrawPolyline* polyline = new LibDrawPolyline();

        CurrentDrawItem = polyline;
        polyline->n = 2;
        ptpoly = (int*) MyZMalloc( 4 * sizeof(int) );
        polyline->PolyList = ptpoly;
268 269
		ptpoly[0] = ptpoly[2] = GetScreen()->m_Curseur.x;
		ptpoly[1] = ptpoly[3] = -( GetScreen()->m_Curseur.y );
270 271 272 273 274 275 276 277 278 279
        polyline->m_Fill  = FlSymbol_Fill;
        polyline->m_Width = g_LibSymbolDefaultLineWidth;
    }
        break;

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

        CurrentDrawItem  = Segment;
280 281
		Segment->m_Pos.x = GetScreen()->m_Curseur.x;
		Segment->m_Pos.y = -( GetScreen()->m_Curseur.y );
282 283 284 285 286 287 288 289 290 291 292 293
        Segment->m_End   = Segment->m_Pos;
        Segment->m_Width = g_LibSymbolDefaultLineWidth;
    }
        break;

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

        CurrentDrawItem = Text;
        Text->m_Size.x  = Text->m_Size.y = g_LastTextSize;
        Text->m_Horiz   = g_LastTextOrient;
294 295
		Text->m_Pos.x   = GetScreen()->m_Curseur.x;
		Text->m_Pos.y   = -( GetScreen()->m_Curseur.y );
296 297 298
        EditSymbolText( NULL, Text );
        if( Text->m_Text.IsEmpty() )
        {
299
			SAFE_DELETE( Text );
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
            CurrentDrawItem = NULL;
            DrawPanel->ManageCurseur = NULL;
            DrawPanel->ForceCloseManageCurseur = NULL;
        }
        else
        {
            StartMoveDrawSymbol( DC );
            DrawLibraryDrawStruct( DrawPanel, DC, CurrentLibEntry, 0, 0,
                                   Text, CurrentUnit, g_XorMode );
        }
    }
        break;
    }

    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
327 328 329 330
}


/********************************************************/
331
void WinEDA_LibeditFrame::GraphicItemBeginDraw( wxDC* DC )
plyatov's avatar
plyatov committed
332
/********************************************************/
333

plyatov's avatar
plyatov committed
334
/* Routine de creation d'un nouvel element type LibraryDrawStruct
335
 */
plyatov's avatar
plyatov committed
336
{
337 338 339
    if( CurrentDrawItem == NULL )
        return;

340
    switch( CurrentDrawItem->Type() )
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
    {
    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:
    {
365
		wxPoint pos = GetScreen()->m_Curseur;
366 367 368 369 370 371 372 373 374 375
        ( (LibDrawPolyline*) CurrentDrawItem )->AddPoint( pos );
    }
        break;

    case COMPONENT_LINE_DRAW_TYPE:
        break;

    default:
        ;
    }
plyatov's avatar
plyatov committed
376 377
}

378

plyatov's avatar
plyatov committed
379
/**************************************************************************/
380
static void RedrawWhileMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
plyatov's avatar
plyatov committed
381
/**************************************************************************/
382

383
/* Redraw the graphoc shape while moving
384
 */
plyatov's avatar
plyatov committed
385
{
386
	BASE_SCREEN* Screen = panel->m_Parent->GetScreen();
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
    int          mx, my;

    /* Erase shape in the old positon*/
    if( erase )
    {
        mx = ItemPreviousPos.x - StartCursor.x,
        my = ItemPreviousPos.y - StartCursor.y;

        DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, mx, my,
                               CurrentDrawItem, CurrentUnit, g_XorMode );
    }

    /* Redraw moved shape */
    mx = Screen->m_Curseur.x - StartCursor.x,
    my = Screen->m_Curseur.y - StartCursor.y;
    DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, mx, my,
                           CurrentDrawItem, CurrentUnit, g_XorMode );
    ItemPreviousPos = Screen->m_Curseur;
plyatov's avatar
plyatov committed
405 406 407 408
}


/*****************************************************************/
409
void MoveLibDrawItemAt( LibEDA_BaseStruct* DrawItem, wxPoint newpos )
plyatov's avatar
plyatov committed
410 411
/*****************************************************************/
{
412 413 414
    int    mx = newpos.x, my = newpos.y;
    wxSize size;

415
    switch( DrawItem->Type() )
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
    {
    case COMPONENT_ARC_DRAW_TYPE:
    {
        int dx = mx - ( (LibDrawArc*) CurrentDrawItem )->m_Pos.x;
        int dy = -my - ( (LibDrawArc*) CurrentDrawItem )->m_Pos.y;
        ( (LibDrawArc*) CurrentDrawItem )->m_Pos.x       = mx;
        ( (LibDrawArc*) CurrentDrawItem )->m_Pos.y       = -my;
        ( (LibDrawArc*) CurrentDrawItem )->m_ArcStart.x += dx;
        ( (LibDrawArc*) CurrentDrawItem )->m_ArcStart.y += dy;
        ( (LibDrawArc*) CurrentDrawItem )->m_ArcEnd.x   += dx;
        ( (LibDrawArc*) CurrentDrawItem )->m_ArcEnd.y   += dy;
        break;
    }

    case COMPONENT_CIRCLE_DRAW_TYPE:
        ( (LibDrawCircle*) CurrentDrawItem )->m_Pos.x = mx;
        ( (LibDrawCircle*) CurrentDrawItem )->m_Pos.y = -my;
        break;

    case COMPONENT_RECT_DRAW_TYPE:
        size.x = ( (LibDrawSquare*) CurrentDrawItem )->m_End.x -
                 ( (LibDrawSquare*) CurrentDrawItem )->m_Pos.x;
        size.y = ( (LibDrawSquare*) CurrentDrawItem )->m_End.y -
                 ( (LibDrawSquare*) CurrentDrawItem )->m_Pos.y;
        ( (LibDrawSquare*) CurrentDrawItem )->m_Pos.x = mx;
        ( (LibDrawSquare*) CurrentDrawItem )->m_Pos.y = -my;
        ( (LibDrawSquare*) CurrentDrawItem )->m_End.x = mx + size.x;
        ( (LibDrawSquare*) CurrentDrawItem )->m_End.y = -my + size.y;
        break;

    case COMPONENT_POLYLINE_DRAW_TYPE:
    {
        int  ii, imax = ( (LibDrawPolyline*) CurrentDrawItem )->n * 2;
        int* ptpoly = ( (LibDrawPolyline*) CurrentDrawItem )->PolyList;
        int  dx = mx - ptpoly[0];
        int  dy = -my - ptpoly[1];
        for( ii = 0; ii < imax; ii += 2 )
        {
            ptpoly[ii]     += dx;
            ptpoly[ii + 1] += dy;
        }
    }
        break;

    case COMPONENT_LINE_DRAW_TYPE:
        break;

    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
        ( (LibDrawText*) CurrentDrawItem )->m_Pos.x = mx;
        ( (LibDrawText*) CurrentDrawItem )->m_Pos.y = -my;
        break;

    default:
        ;
    }
plyatov's avatar
plyatov committed
471 472
}

473

plyatov's avatar
plyatov committed
474
/************************************************************/
475
void WinEDA_LibeditFrame::StartMoveDrawSymbol( wxDC* DC )
plyatov's avatar
plyatov committed
476 477
/************************************************************/
{
478 479
    if( CurrentDrawItem == NULL )
        return;
plyatov's avatar
plyatov committed
480

481
    SetCursor( wxCURSOR_HAND );
plyatov's avatar
plyatov committed
482

483
    CurrentDrawItem->m_Flags |= IS_MOVED;
484
	StartCursor = GetScreen()->m_Curseur;
plyatov's avatar
plyatov committed
485

486
    switch( CurrentDrawItem->Type() )
487 488 489 490
    {
    case COMPONENT_ARC_DRAW_TYPE:
        InitPosition = ( (LibDrawArc*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
491

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

496 497 498
    case COMPONENT_RECT_DRAW_TYPE:
        InitPosition = ( (LibDrawSquare*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
499

500 501 502 503
    case COMPONENT_POLYLINE_DRAW_TYPE:
        InitPosition.x = *( (LibDrawPolyline*) CurrentDrawItem )->PolyList;
        InitPosition.y = *( ( (LibDrawPolyline*) CurrentDrawItem )->PolyList + 1 );
        break;
plyatov's avatar
plyatov committed
504

505 506
    case COMPONENT_LINE_DRAW_TYPE:
        break;
plyatov's avatar
plyatov committed
507

508 509 510
    case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
        InitPosition = ( (LibDrawText*) CurrentDrawItem )->m_Pos;
        break;
plyatov's avatar
plyatov committed
511

512 513 514
    default:
        ;
    }
plyatov's avatar
plyatov committed
515

516
	ItemPreviousPos = GetScreen()->m_Curseur;
517 518 519 520
    DrawPanel->ManageCurseur = RedrawWhileMovingCursor;
    DrawPanel->ForceCloseManageCurseur = AbortSymbolTraceOn;
    DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
}
plyatov's avatar
plyatov committed
521 522 523 524 525 526


/****************************************************************/
/* Routine de Gestion des evenements souris lors de la creation */
/* d'un nouvel element type LibraryDrawStruct					*/
/****************************************************************/
527
static void SymbolDisplayDraw( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
plyatov's avatar
plyatov committed
528
{
529 530 531
    int          DrawMode = g_XorMode;
    int*         ptpoly;
    int          dx, dy;
532
	BASE_SCREEN* Screen = panel->m_Parent->GetScreen();
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
    int          mx = Screen->m_Curseur.x,
                 my = Screen->m_Curseur.y;

    GRSetDrawMode( DC, DrawMode );

    if( erase )
    {
        if( StateDrawArc == 1 )
        {
            int Color = ReturnLayerColor( LAYER_DEVICE );
            GRLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY, ArcEndX, -ArcEndY, 0, Color );
        }
        else
        {
            DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, 0, 0,
                                   CurrentDrawItem, CurrentUnit, DrawMode );
549
            if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
550 551 552 553 554 555 556 557 558 559 560 561 562 563
            {
                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 );
            }
        }
    }

564
    switch( CurrentDrawItem->Type() )
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
    {
    case COMPONENT_ARC_DRAW_TYPE:
        if( StateDrawArc == 1 )
        {
            ArcEndX = mx; ArcEndY = -my;
        }

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

    case COMPONENT_CIRCLE_DRAW_TYPE:
        dx = ( (LibDrawCircle*) CurrentDrawItem )->m_Pos.x - mx;
        dy = ( (LibDrawCircle*) CurrentDrawItem )->m_Pos.y + my;
        ( (LibDrawCircle*) CurrentDrawItem )->m_Rayon = (int) sqrt( (dx * dx) + (dy * dy) );
        ( (LibDrawCircle*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
        break;

    case COMPONENT_RECT_DRAW_TYPE:
        ( (LibDrawSquare*) CurrentDrawItem )->m_End.x = mx;
        ( (LibDrawSquare*) CurrentDrawItem )->m_End.y = -my;
        ( (LibDrawSquare*) CurrentDrawItem )->m_Fill  = FlSymbol_Fill;
        break;

    case COMPONENT_POLYLINE_DRAW_TYPE:
        ptpoly    = ( (LibDrawPolyline*) CurrentDrawItem )->PolyList;
        ptpoly   += 2 * ( ( (LibDrawPolyline*) CurrentDrawItem )->n - 1 );
        ptpoly[0] = mx;
        ptpoly[1] = -my;
        ( (LibDrawPolyline*) CurrentDrawItem )->m_Fill = FlSymbol_Fill;
        break;

    case COMPONENT_LINE_DRAW_TYPE:
        ( (LibDrawSegment*) CurrentDrawItem )->m_End.x = mx;
        ( (LibDrawSegment*) CurrentDrawItem )->m_End.y = -my;
        break;

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

    default:
        ;
    }

    if( StateDrawArc == 1 )
    {
        int Color = ReturnLayerColor( LAYER_DEVICE );
        GRLine( &panel->m_ClipBox, DC, ArcStartX, -ArcStartY, ArcEndX, -ArcEndY, 0, Color );
    }
    else
    {
        DrawLibraryDrawStruct( panel, DC, CurrentLibEntry, 0, 0,
                               CurrentDrawItem, CurrentUnit, DrawMode );
621
        if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
622 623 624 625 626 627 628 629 630 631 632 633
        {
            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
634 635 636 637
}


/******************************************************/
638
void WinEDA_LibeditFrame::EndDrawGraphicItem( wxDC* DC )
plyatov's avatar
plyatov committed
639
/******************************************************/
640

plyatov's avatar
plyatov committed
641
/* Place la structure courante en liste des structures du composant
642 643 644 645 646
 *  courant, si elle existe et redessine toujours celle ci
 *  Parametres: (tous globaux)
 *      CurrentDrawItem
 *      CurrentLibEntry
 */
plyatov's avatar
plyatov committed
647
{
648 649 650 651 652
    if( CurrentLibEntry == NULL )
        return;
    if( CurrentDrawItem == NULL )
        return;

653
    if( CurrentDrawItem->Type() == COMPONENT_ARC_DRAW_TYPE )
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673
    {
        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 );
        CurrentDrawItem->Pnext      = CurrentLibEntry->m_Drawings;
        CurrentLibEntry->m_Drawings = CurrentDrawItem;

674
        switch( CurrentDrawItem->Type() )
675 676 677 678 679 680 681 682 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
        {
        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 );
    }

    DrawLibEntry( DrawPanel, DC, CurrentLibEntry, 0, 0, CurrentUnit,
                  CurrentConvert, GR_DEFAULT_DRAWMODE );

    CurrentDrawItem->m_Flags = 0;
    CurrentDrawItem = NULL;

723
	GetScreen()->SetModify();
724 725 726

    DrawPanel->ManageCurseur = NULL;
    DrawPanel->ForceCloseManageCurseur = NULL;
plyatov's avatar
plyatov committed
727 728 729 730
}


/***************************************************************/
731
static void ComputeArc( LibDrawArc* DrawItem, wxPoint ArcCentre )
plyatov's avatar
plyatov committed
732
/***************************************************************/
733

plyatov's avatar
plyatov committed
734
/* routine d'ajustage des parametres de l'arc en cours de trace
735 736 737 738 739
 *  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
740
{
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
    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;
    angle = (int) (atan2( dy, dx ) * 1800 / M_PI);
    RotatePoint( &dx, &dy, angle );  /* Le segment dx, dy est horizontal */
                                     /* -> dx = longueur, dy = 0 */
    RotatePoint( &cX, &cY, angle );
    cX = dx / 2;    /* cX, cY est sur la mediane du segment 0,0 a dx,0 */

    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;

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

    DrawItem->t1 = (int) (atan2( dy, dx ) * 1800 / M_PI);

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

773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
    DrawItem->t2 = (int) (atan2( dy, dx ) * 1800 / M_PI);

    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 );
794
    g_EDA_Appl->m_LibeditFrame->PrintMsg( msg );
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809

    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
810 811
}

812

plyatov's avatar
plyatov committed
813
/***************************************************/
814
void WinEDA_LibeditFrame::DeleteDrawPoly( wxDC* DC )
plyatov's avatar
plyatov committed
815
/**************************************************/
816

plyatov's avatar
plyatov committed
817
/* Used for deleting last entered segment while creating a Polyline
818
 */
plyatov's avatar
plyatov committed
819
{
820 821
    if( CurrentDrawItem == NULL )
        return;
822
    if( CurrentDrawItem->Type() != COMPONENT_POLYLINE_DRAW_TYPE )
823 824 825 826 827 828 829 830 831 832 833 834
        return;

    int*             ptpoly;
    LibDrawPolyline* Poly = (LibDrawPolyline*) CurrentDrawItem;

    DrawLibraryDrawStruct( DrawPanel, DC, CurrentLibEntry, 0, 0,
                           CurrentDrawItem, CurrentUnit, g_XorMode );

    while( Poly->n > 2 )    // First segment is kept, only its end point is changed
    {
        Poly->n--;
        ptpoly = Poly->PolyList + ( 2 * (Poly->n - 1) );
835 836
		if( (ptpoly[0] != GetScreen()->m_Curseur.x)
				   || (ptpoly[1] != -GetScreen()->m_Curseur.y) )
837
        {
838 839
			ptpoly[0] = GetScreen()->m_Curseur.x;
			ptpoly[1] = -( GetScreen()->m_Curseur.y);
840 841 842 843 844 845 846 847 848
            break;
        }
    }

    int allocsize = 2 * sizeof(int) * Poly->n;
    Poly->PolyList = (int*) realloc( Poly->PolyList, allocsize );

    DrawLibraryDrawStruct( DrawPanel, DC, CurrentLibEntry, 0, 0,
                           CurrentDrawItem, CurrentUnit, g_XorMode );
plyatov's avatar
plyatov committed
849
}