KiCad PCB EDA Suite
sch_draw_panel.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014-2017 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 
26 #include <view/wx_view_controls.h>
27 #include <worksheet_viewitem.h>
28 
30 #include <sch_draw_panel.h>
31 #include <sch_view.h>
32 #include <sch_painter.h>
33 #include <sch_edit_frame.h>
35 
36 #include <functional>
37 
38 #include <sch_sheet.h>
39 #include <pgm_base.h>
40 
41 using namespace std::placeholders;
42 
43 
44 // Events used by EDA_DRAW_PANEL
45 // GAL TODO: some (most?) of these need to be implemented...
46 BEGIN_EVENT_TABLE( SCH_DRAW_PANEL, wxScrolledCanvas )
47 // EVT_LEAVE_WINDOW( EDA_DRAW_PANEL::OnMouseLeaving )
48 // EVT_ENTER_WINDOW( EDA_DRAW_PANEL::OnMouseEntering )
49 // EVT_MOUSEWHEEL( EDA_DRAW_PANEL::OnMouseWheel )
50 #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
51 // EVT_MAGNIFY( EDA_DRAW_PANEL::OnMagnify )
52 #endif
53 // EVT_MOUSE_EVENTS( EDA_DRAW_PANEL::OnMouseEvent )
54  EVT_CHAR( SCH_DRAW_PANEL::OnKeyEvent )
55  EVT_CHAR_HOOK( SCH_DRAW_PANEL::OnCharHook )
56  EVT_PAINT( SCH_DRAW_PANEL::onPaint )
57 // EVT_ERASE_BACKGROUND( EDA_DRAW_PANEL::OnEraseBackground )
58 // EVT_SCROLLWIN( EDA_DRAW_PANEL::OnScroll )
59 // EVT_ACTIVATE( EDA_DRAW_PANEL::OnActivate )
60 // EVT_MENU_RANGE( ID_PAN_UP, ID_PAN_RIGHT, EDA_DRAW_PANEL::OnPan )
61 END_EVENT_TABLE()
62 
63 SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId,
64  const wxPoint& aPosition, const wxSize& aSize,
65  KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
66  EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType ),
67  m_parent( aParentWindow )
68 {
69  m_defaultCursor = m_currentCursor = wxCURSOR_ARROW;
70  m_showCrossHair = true;
71  m_view = new KIGFX::SCH_VIEW( true );
72  m_view->SetGAL( m_gal );
73 
74  m_gal->SetWorldUnitLength( SCH_WORLD_UNIT );
75 
76  m_painter.reset( new KIGFX::SCH_PAINTER( m_gal ) );
77 
78  m_view->SetPainter( m_painter.get() );
79  m_view->SetScaleLimits( 50.0, 0.05 ); // This fixes the zoom in and zoom out limits
80  m_view->SetMirror( false, false );
81 
82  setDefaultLayerOrder();
83  setDefaultLayerDeps();
84 
85  view()->UpdateAllLayersOrder();
86 
87  // View controls is the first in the event handler chain, so the Tool Framework operates
88  // on updated viewport data.
89  m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this );
90 
91  const wxEventType events[] =
92  {
93  wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK,
94  wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
95  wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
96  wxEVT_MOTION, wxEVT_MOUSEWHEEL,
97  };
98 
99  for( auto e : events )
100  {
101  Connect( e, wxMouseEventHandler( SCH_DRAW_PANEL::OnMouseEvent ), NULL, this );
102  }
103 
104  Connect( wxEVT_CHAR, wxKeyEventHandler( SCH_DRAW_PANEL::OnKeyEvent ), NULL, this );
105  Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( SCH_DRAW_PANEL::OnCharHook ), NULL, this );
106 
107  Pgm().CommonSettings()->Read( ENBL_MOUSEWHEEL_PAN_KEY, &m_enableMousewheelPan, false );
108  Pgm().CommonSettings()->Read( ENBL_ZOOM_NO_CENTER_KEY, &m_enableZoomNoCenter, false );
109  Pgm().CommonSettings()->Read( ENBL_AUTO_PAN_KEY, &m_enableAutoPan, true );
110 
111  m_canStartBlock = -1; // Command block can start if >= 0
112  m_abortRequest = false;
113  m_ignoreMouseEvents = false;
114  // Be sure a mouse release button event will be ignored when creating the canvas
115  // if the mouse click was not made inside the canvas (can happen sometimes, when
116  // launching a editor from a double click made in another frame)
117  m_ignoreNextLeftButtonRelease = true;
118 
119  m_mouseCaptureCallback = NULL;
120  m_endMouseCaptureCallback = NULL;
121 
122  m_requestAutoPan = false;
123  m_enableBlockCommands = false;
124  m_minDragEventCount = 0;
125 
126  m_cursorLevel = 0;
127  m_PrintIsMirrored = false;
128 
129  m_doubleClickInterval = 250;
130 
131  m_viewControls->SetSnapping( true );
132 
133  SetEvtHandlerEnabled( true );
134  SetFocus();
135  Show( true );
136  Raise();
137  StartDrawing();
138 }
139 
140 
142 {
143 }
144 
145 
147 {
148  view()->Clear();
149  view()->DisplayComponent( const_cast<LIB_PART*>(aComponent) );
150 
151 }
152 
154 {
155  view()->Clear();
156  view()->DisplaySheet( const_cast<SCH_SHEET*>(aSheet) );
157 }
158 
160 {
161  view()->Clear();
162 
163  if( aScreen )
164  view()->DisplaySheet( const_cast<SCH_SCREEN*>( aScreen ) );
165 }
166 
168 {
169  //m_view->RecacheAllItems();
170 }
171 
172 
174 {
175  for( LAYER_NUM i = 0; (unsigned) i < sizeof( SCH_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
176  {
177  LAYER_NUM layer = SCH_LAYER_ORDER[i];
178  wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
179 
180  m_view->SetLayerOrder( layer, i );
181  }
182 }
183 
184 
186 {
187  VECTOR2D grid_size = m_gal->GetGridSize();
188  bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
189  setDefaultLayerDeps();
190  m_gal->SetWorldUnitLength( SCH_WORLD_UNIT );
191 
192  // Keep grid size and grid visibility:
193  m_gal->SetGridSize( grid_size );
194  SCH_BASE_FRAME* frame = dynamic_cast<SCH_BASE_FRAME*>( GetParent() );
195 
196  if( frame )
197  m_gal->SetGridVisibility( frame->IsGridVisible() );
198 
199  Refresh();
200 
201  return rv;
202 }
203 
204 
206 {
207  m_enableMousewheelPan = aEnable;
208 
209  if( GetParent()->IsGalCanvasActive() )
210  GetParent()->GetGalCanvas()->GetViewControls()->EnableMousewheelPan( aEnable );
211 }
212 
213 
215 {
216  m_enableAutoPan = aEnable;
217 
218  if( GetParent()->IsGalCanvasActive() )
219  GetParent()->GetGalCanvas()->GetViewControls()->EnableAutoPan( aEnable );
220 }
221 
222 
224 {
225  m_enableZoomNoCenter = aEnable;
226 
227  if( GetParent()->IsGalCanvasActive() )
228  GetParent()->GetGalCanvas()->GetViewControls()->EnableCursorWarping( !aEnable );
229 }
230 
231 
233 {
234  // caching makes no sense for Cairo and other software renderers
235  auto target = m_backend == GAL_TYPE_OPENGL ? KIGFX::TARGET_CACHED : KIGFX::TARGET_NONCACHED;
236 
237  for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ )
238  m_view->SetLayerTarget( i, target );
239 
240  // Bitmaps are draw on a non cached GAL layer:
241  m_view->SetLayerTarget( LAYER_DRAW_BITMAPS , KIGFX::TARGET_NONCACHED );
242 
243  // Some draw layers need specific settings
244  m_view->SetLayerTarget( LAYER_GP_OVERLAY , KIGFX::TARGET_OVERLAY );
245  m_view->SetLayerDisplayOnly( LAYER_GP_OVERLAY ) ;
246 
247  m_view->SetLayerTarget( LAYER_SELECT_OVERLAY , KIGFX::TARGET_OVERLAY );
248  m_view->SetLayerDisplayOnly( LAYER_SELECT_OVERLAY ) ;
249 
250  m_view->SetLayerTarget( LAYER_WORKSHEET , KIGFX::TARGET_NONCACHED );
251  m_view->SetLayerDisplayOnly( LAYER_WORKSHEET ) ;
252 }
253 
254 
256 {
257  return static_cast<KIGFX::SCH_VIEW*>( m_view );
258 }
259 
261 {
262  return GetParent()->GetScreen();
263 }
264 
266 {
267  return static_cast<EDA_DRAW_FRAME*>(m_parent); // static_cast<SCH_EDIT_FRAME*> (m_parent);
268 }
269 
270 
271 void SCH_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event )
272 {
273  int localbutt = 0;
274  BASE_SCREEN* screen = GetScreen();
275  auto controls = GetViewControls();
276  auto vmp = VECTOR2I( controls->GetMousePosition() );
277  wxPoint mousePos ( vmp.x, vmp.y );
278 
279  event.Skip();
280 
281  if( !screen )
282  return;
283 
284  /* Adjust value to filter mouse displacement before consider the drag
285  * mouse is really a drag command, not just a movement while click
286  */
287 #define MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND 5
288 
289  if( event.Leaving() )
290  m_canStartBlock = -1;
291 
292  if( !IsMouseCaptured() ) // No mouse capture in progress.
293  m_requestAutoPan = false;
294 
295  if( GetParent()->IsActive() )
296  SetFocus();
297  else
298  return;
299 
300  if( !event.IsButton() && !event.Moving() && !event.Dragging() )
301  return;
302 
303  if( event.RightUp() )
304  {
305  OnRightClick( event );
306  return;
307  }
308 
309  if( m_ignoreMouseEvents )
310  return;
311 
312  if( event.LeftDown() )
313  localbutt = GR_M_LEFT_DOWN;
314 
315  if( event.ButtonDClick( 1 ) )
316  localbutt = GR_M_LEFT_DOWN | GR_M_DCLICK;
317 
318  if( event.MiddleDown() )
319  localbutt = GR_M_MIDDLE_DOWN;
320 
321  // Compute the cursor position in drawing (logical) units.
322  //GetParent()->SetMousePosition( event.GetLogicalPosition( DC ) );
323 
324  int kbstat = 0;
325 
326  if( event.ShiftDown() )
327  kbstat |= GR_KB_SHIFT;
328 
329  if( event.ControlDown() )
330  kbstat |= GR_KB_CTRL;
331 
332  if( event.AltDown() )
333  kbstat |= GR_KB_ALT;
334 
335  // Calling Double Click and Click functions :
336  if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) )
337  {
338  GetParent()->OnLeftDClick( nullptr, mousePos );
339 
340  // inhibit a response to the mouse left button release,
341  // because we have a double click, and we do not want a new
342  // OnLeftClick command at end of this Double Click
343  m_ignoreNextLeftButtonRelease = true;
344  }
345  else if( event.LeftUp() )
346  {
347  // A block command is in progress: a left up is the end of block
348  // or this is the end of a double click, already seen
349  // Note also m_ignoreNextLeftButtonRelease can be set by
350  // the call to OnLeftClick(), so do not change it after calling OnLeftClick
351  bool ignoreEvt = m_ignoreNextLeftButtonRelease;
352  m_ignoreNextLeftButtonRelease = false;
353 
354  if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK && !ignoreEvt )
355  GetParent()->OnLeftClick( nullptr, mousePos );
356 
357  }
358  else if( !event.LeftIsDown() )
359  {
360  /* be sure there is a response to a left button release command
361  * even when a LeftUp event is not seen. This happens when a
362  * double click opens a dialog box, and the release mouse button
363  * is made when the dialog box is opened.
364  */
365  m_ignoreNextLeftButtonRelease = false;
366  }
367 
368  if( event.ButtonDown( wxMOUSE_BTN_MIDDLE ) )
369  {
370  m_PanStartCenter = GetParent()->GetScrollCenterPosition();
371  m_PanStartEventPosition = event.GetPosition();
372 
373  CrossHairOff( );
374  SetCurrentCursor( wxCURSOR_SIZING );
375  }
376 
377  if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) )
378  {
379  CrossHairOn();
380  SetDefaultCursor();
381  }
382 
383  if( event.MiddleIsDown() )
384  {
385  // already managed by EDA_DRAW_PANEL_GAL mouse event handler.
386  return;
387  }
388 
389  // Calling the general function on mouse changes (and pseudo key commands)
390  GetParent()->GeneralControl( nullptr, mousePos );
391 
392  /*******************************/
393  /* Control of block commands : */
394  /*******************************/
395 
396  // Command block can't start if mouse is dragging a new panel
397  static SCH_DRAW_PANEL* lastPanel;
398  if( lastPanel != this )
399  {
400  m_minDragEventCount = 0;
401  m_canStartBlock = -1;
402  }
403 
404  /* A new command block can start after a release buttons
405  * and if the drag is enough
406  * This is to avoid a false start block when a dialog box is dismissed,
407  * or when changing panels in hierarchy navigation
408  * or when clicking while and moving mouse
409  */
410  if( !event.LeftIsDown() && !event.MiddleIsDown() )
411  {
412  m_minDragEventCount = 0;
413  m_canStartBlock = 0;
414 
415  /* Remember the last cursor position when a drag mouse starts
416  * this is the last position ** before ** clicking a button
417  * this is useful to start a block command from the point where the
418  * mouse was clicked first
419  * (a filter creates a delay for the real block command start, and
420  * we must remember this point)
421  */
422  m_CursorStartPos = GetParent()->GetCrossHairPosition();
423  }
424 
425  if( m_enableBlockCommands && !(localbutt & GR_M_DCLICK) )
426  {
427  if( !screen->IsBlockActive() )
428  {
429  screen->m_BlockLocate.SetOrigin( m_CursorStartPos );
430  }
431 
432  if( event.LeftDown() )
433  {
434  if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
435  {
436  m_requestAutoPan = false;
437  GetParent()->HandleBlockPlace( nullptr );
438  m_ignoreNextLeftButtonRelease = true;
439  }
440  }
441  else if( ( m_canStartBlock >= 0 ) && event.LeftIsDown() && !IsMouseCaptured() )
442  {
443  // Mouse is dragging: if no block in progress, start a block command.
444  if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
445  {
446  // Start a block command
447  int cmd_type = kbstat;
448 
449  // A block command is started if the drag is enough. A small
450  // drag is ignored (it is certainly a little mouse move when
451  // clicking) not really a drag mouse
452  if( m_minDragEventCount < MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND )
453  m_minDragEventCount++;
454  else
455  {
456  auto cmd = (GetParent()->GetToolId() == ID_ZOOM_SELECTION) ? BLOCK_ZOOM : 0;
457 
458  DBG(printf("start block\n");)
459 
460  if( !GetParent()->HandleBlockBegin( nullptr, cmd_type, m_CursorStartPos, cmd ) )
461  {
462  // should not occur: error
463  GetParent()->DisplayToolMsg(
464  wxT( "EDA_DRAW_PANEL::OnMouseEvent() Block Error" ) );
465  }
466  else
467  {
468  m_requestAutoPan = true;
469  SetCursor( wxCURSOR_SIZING );
470  }
471  }
472  }
473  }
474 
475  if( event.ButtonUp( wxMOUSE_BTN_LEFT ) )
476  {
477  /* Release the mouse button: end of block.
478  * The command can finish (DELETE) or have a next command (MOVE,
479  * COPY). However the block command is canceled if the block
480  * size is small because a block command filtering is already
481  * made, this case happens, but only when the on grid cursor has
482  * not moved.
483  */
484  #define BLOCK_MINSIZE_LIMIT 1
485  bool BlockIsSmall =
487  && ( std::abs( screen->m_BlockLocate.GetHeight() ) < BLOCK_MINSIZE_LIMIT );
488 
489  if( (screen->m_BlockLocate.GetState() != STATE_NO_BLOCK) && BlockIsSmall )
490  {
491  if( m_endMouseCaptureCallback )
492  {
493  m_endMouseCaptureCallback( this, nullptr );
494  m_requestAutoPan = false;
495  }
496 
497  //SetCursor( (wxStockCursor) m_currentCursor );
498  }
499  else if( screen->m_BlockLocate.GetState() == STATE_BLOCK_END )
500  {
501  m_requestAutoPan = false;
502  GetParent()->HandleBlockEnd( nullptr );
503  //SetCursor( (wxStockCursor) m_currentCursor );
504  if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
505  {
506  m_requestAutoPan = true;
507  SetCursor( wxCURSOR_HAND );
508  }
509  }
510  }
511  }
512 
513  // End of block command on a double click
514  // To avoid an unwanted block move command if the mouse is moved while double clicking
515  if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) )
516  {
517  if( !screen->IsBlockActive() && IsMouseCaptured() )
518  {
519  m_endMouseCaptureCallback( this, nullptr );
520  }
521  }
522 
523  lastPanel = this;
524 
525 }
526 
527 
528 bool SCH_DRAW_PANEL::OnRightClick( wxMouseEvent& event )
529 {
530  auto controls = GetViewControls();
531  auto vmp = controls->GetMousePosition();
532  wxPoint mouseWorldPos ( (int) vmp.x, (int) vmp.y );
533 
534  wxMenu MasterMenu;
535 
536  if( !GetParent()->OnRightClick( mouseWorldPos, &MasterMenu ) )
537  return false;
538 
539  GetParent()->AddMenuZoomAndGrid( &MasterMenu );
540 
541  m_ignoreMouseEvents = true;
542  PopupMenu( &MasterMenu, event.GetPosition() );
543  m_ignoreMouseEvents = false;
544 
545  return true;
546 }
547 
548 void SCH_DRAW_PANEL::CallMouseCapture( wxDC* aDC, const wxPoint& aPosition, bool aErase )
549 {
550  wxCHECK_RET( m_mouseCaptureCallback != NULL, wxT( "Mouse capture callback not set." ) );
551 
552  m_mouseCaptureCallback( this, aDC, aPosition, aErase );
553 }
554 
555 
557 {
558  // CallEndMouseCapture is sometimes called with m_endMouseCaptureCallback == NULL
559  // for instance after an ABORT in block paste.
560  if( m_endMouseCaptureCallback )
561  m_endMouseCaptureCallback( this, aDC );
562 }
563 
564 
565 void SCH_DRAW_PANEL::EndMouseCapture( int id, int cursor, const wxString& title,
566  bool aCallEndFunc )
567 {
568  if( m_mouseCaptureCallback && m_endMouseCaptureCallback && aCallEndFunc )
569  {
570  m_endMouseCaptureCallback( this, nullptr );
571  }
572 
573  m_mouseCaptureCallback = NULL;
574  m_endMouseCaptureCallback = NULL;
575  m_requestAutoPan = false;
576 
577  if( id != -1 && cursor != -1 )
578  {
579  //wxASSERT( cursor > wxCURSOR_NONE && cursor < wxCURSOR_MAX );
580  GetParent()->SetToolID( id, cursor, title );
581  }
582 }
583 
585 {
586  m_viewControls->ShowCursor( false );
587 }
588 
589 
591 {
592  m_viewControls->ShowCursor( true );
593 }
594 
595 
597 {
598  GetViewControls()->WarpCursor( GetParent()->GetCrossHairPosition(), true );
599 }
600 
601 
602 void SCH_DRAW_PANEL::Refresh( bool aEraseBackground, const wxRect* aRect )
603 {
604  EDA_DRAW_PANEL_GAL::Refresh( aEraseBackground, aRect );
605 }
606 
607 
608 void SCH_DRAW_PANEL::OnCharHook( wxKeyEvent& event )
609 {
610  event.Skip();
611 }
612 
613 
614 void SCH_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event )
615 {
616  int localkey;
617 
618  localkey = event.GetKeyCode();
619 
620  switch( localkey )
621  {
622  default:
623  break;
624 
625  case WXK_ESCAPE:
626  m_abortRequest = true;
627 
628  if( IsMouseCaptured() )
629  EndMouseCapture();
630  else
631  EndMouseCapture( ID_NO_TOOL_SELECTED, 0 /*m_defaultCursor*/, wxEmptyString );
632  break;
633  }
634 
635  /* Normalize keys code to easily handle keys from Ctrl+A to Ctrl+Z
636  * They have an ascii code from 1 to 27 remapped
637  * to GR_KB_CTRL + 'A' to GR_KB_CTRL + 'Z'
638  */
639  if( event.ControlDown() && localkey >= WXK_CONTROL_A && localkey <= WXK_CONTROL_Z )
640  localkey += 'A' - 1;
641 
642  /* Disallow shift for keys that have two keycodes on them (e.g. number and
643  * punctuation keys) leaving only the "letter keys" of A-Z.
644  * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout)
645  * and Ctrl-( and Ctrl-5 (FR layout).
646  * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout
647  */
648  bool keyIsLetter = ( localkey >= 'A' && localkey <= 'Z' ) ||
649  ( localkey >= 'a' && localkey <= 'z' );
650 
651  if( event.ShiftDown() && ( keyIsLetter || localkey > 256 ) )
652  localkey |= GR_KB_SHIFT;
653 
654  if( event.ControlDown() )
655  localkey |= GR_KB_CTRL;
656 
657  if( event.AltDown() )
658  localkey |= GR_KB_ALT;
659 
660 
661  // Some key commands use the current mouse position: refresh it.
662  //pos = wxGetMousePosition() - GetScreenPosition();
663 
664  // Compute the cursor position in drawing units. Also known as logical units to wxDC.
665  //pos = wxPoint( DC.DeviceToLogicalX( pos.x ), DC.DeviceToLogicalY( pos.y ) );
666 
667  auto p = GetViewControls()->GetCursorPosition( false );
668 
669  wxPoint pos ((int)p.x, (int)p.y);
670 
671  GetParent()->SetMousePosition( pos );
672 
673  if( !GetParent()->GeneralControl( nullptr, pos, localkey ) )
674  event.Skip();
675 }
676 
677 
678 void SCH_DRAW_PANEL::onPaint( wxPaintEvent& aEvent )
679 {
680  if( !m_gal->IsInitialized() )
681  // The first wxPaintEvent can be fired at startup before the GAL engine is fully initialized
682  // (depending on platforms). Do nothing in this case
683  return;
684 
685  SCH_SCREEN* screen = static_cast<SCH_SCREEN*>( GetScreen() );
686 
687  // The screen might be null if the wxPaintEvent is fired after the parent frame deletion
688  if( !screen )
689  return;
690 
691  // Ensure links are up to date, even if a library was reloaded for some reason:
692  screen->UpdateSymbolLinks();
693 
694  if( m_painter )
695  static_cast<KIGFX::SCH_PAINTER*>(m_painter.get())->GetSettings()->ImportLegacyColors( nullptr );
696 
697  EDA_DRAW_PANEL_GAL::onPaint( aEvent );
698 }
Definition of the SCH_SHEET class for Eeschema.
bool OnRightClick(wxMouseEvent &event)
#define GR_KB_ALT
#define GR_M_DCLICK
Definition: gr_basic.h:77
KIGFX::SCH_VIEW * view() const
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
Definition: base_screen.h:214
#define GR_M_MIDDLE_DOWN
Definition: gr_basic.h:76
#define MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:58
virtual EDA_DRAW_FRAME * GetParent() const override
#define BLOCK_MINSIZE_LIMIT
void OnShow() override
>
to handle and draw images bitmaps
Class WX_VIEW_CONTROLS is a specific implementation of class VIEW_CONTROLS for wxWidgets library...
constexpr double SCH_WORLD_UNIT
Definition: sch_view.h:40
virtual bool SwitchBackend(GAL_TYPE aGalType)
Function SwitchBackend Switches method of rendering graphics.
virtual void MoveCursorToCrossHair() override
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
void UpdateSymbolLinks(bool aForce=false)
Initialize or reinitialize the weak reference to the LIB_PART for each SCH_COMPONENT found in m_drawL...
Definition: sch_screen.cpp:476
int GetHeight() const
Definition: eda_rect.h:118
#define GR_KB_CTRL
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:124
virtual void EndMouseCapture(int aId=-1, int aCursorId=-1, const wxString &aTitle=wxEmptyString, bool aCallEndFunc=true) override
Function EndMouseCapture ends mouse a capture.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:66
void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
The base class for create windows for drawing purpose.
Definition: draw_frame.h:78
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
#define abs(a)
Definition: auxiliary.h:84
WX_VIEW_CONTROLS class definition.
virtual bool IsGridVisible() const
Definition: draw_frame.h:528
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:699
virtual void CallEndMouseCapture(wxDC *aDC) override
Function CallEndMouseCapture calls the end mouse capture callback.
#define ENBL_ZOOM_NO_CENTER_KEY
Definition: pgm_base.h:47
Auxiliary rendering target (noncached)
Definition: definitions.h:42
static const LAYER_NUM SCH_LAYER_ORDER[]
Definition: sch_view.h:42
void OnMouseEvent(wxMouseEvent &event)
Class that handles properties and drawing of worksheet layout.
bool IsBlockActive() const
Definition: base_screen.h:499
#define ENBL_AUTO_PAN_KEY
Definition: pgm_base.h:50
virtual void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase) override
Function CallMouseCapture calls the mouse capture callback.
virtual void onPaint(wxPaintEvent &WXUNUSED(aEvent))
virtual void CrossHairOff(wxDC *DC=nullptr) override
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
void OnKeyEvent(wxKeyEvent &event)
Class BASE_SCREEN handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:76
Class SCH_PAINTER Contains methods for drawing schematic-specific items.
Definition: sch_painter.h:112
void SetEnableAutoPan(bool aEnable) override
virtual void onPaint(wxPaintEvent &WXUNUSED(aEvent)) override
Define a library symbol object.
#define ENBL_MOUSEWHEEL_PAN_KEY
Definition: pgm_base.h:48
Items that may change while the view stays the same (noncached)
Definition: definitions.h:43
virtual void CrossHairOn(wxDC *DC=nullptr) override
general purpose overlay
void setDefaultLayerDeps()
Sets rendering targets & dependencies for layers.
#define GR_KB_SHIFT
bool SwitchBackend(GAL_TYPE aGalType) override
Function SwitchBackend Switches method of rendering graphics.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
#define GR_M_LEFT_DOWN
Definition: gr_basic.h:74
void SetEnableZoomNoCenter(bool aEnable) override
see class PGM_BASE
Main rendering target (cached)
Definition: definitions.h:41
BLOCK_STATE_T GetState() const
VTBL_ENTRY wxConfigBase * CommonSettings() const
Definition: pgm_base.h:187
size_t i
Definition: json11.cpp:597
void DisplaySheet(const SCH_SHEET *aSheet)
currently selected items overlay
int GetWidth() const
Definition: eda_rect.h:117
void OnCharHook(wxKeyEvent &event)
BASE_SCREEN * GetScreen() override
virtual void SetGridVisibility(bool aVisible)
It may be overloaded by derived classes.
Definition: draw_frame.h:537
#define DBG(x)
Definition: fctsys.h:33
A shim class between EDA_DRAW_FRAME and several derived classes: LIB_EDIT_FRAME, LIB_VIEW_FRAME, and SCH_EDIT_FRAME, and it brings in a common way of handling the provided virtual functions for the derived classes.
void DisplayComponent(const LIB_PART *aComponent)
Function DisplayBoard FIXME adds all items from the current board to the VIEW, so they can be display...
void setDefaultLayerOrder()
Reassigns layer order to the initial settings.
void SetEnableMousewheelPan(bool aEnable) override