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-2019 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, dynamic_cast<SCH_BASE_FRAME*>( aParentWindow ) );
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  // Early initialization of the canvas background color,
83  // before any OnPaint event is fired for the canvas using a wrong bg color
84  auto settings = m_painter->GetSettings();
85  m_gal->SetClearColor( settings->GetBackgroundColor() );
86 
87  setDefaultLayerOrder();
88  setDefaultLayerDeps();
89 
90  view()->UpdateAllLayersOrder();
91 
92  // View controls is the first in the event handler chain, so the Tool Framework operates
93  // on updated viewport data.
94  m_viewControls = new KIGFX::WX_VIEW_CONTROLS( m_view, this );
95 
96  const wxEventType events[] =
97  {
98  wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK,
99  wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
100  wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
101  wxEVT_MOTION, wxEVT_MOUSEWHEEL,
102  };
103 
104  for( auto e : events )
105  {
106  Connect( e, wxMouseEventHandler( SCH_DRAW_PANEL::OnMouseEvent ), NULL, this );
107  }
108 
109  Connect( wxEVT_CHAR, wxKeyEventHandler( SCH_DRAW_PANEL::OnKeyEvent ), NULL, this );
110  Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( SCH_DRAW_PANEL::OnCharHook ), NULL, this );
111 
112  Pgm().CommonSettings()->Read( ENBL_MOUSEWHEEL_PAN_KEY, &m_enableMousewheelPan, false );
113  Pgm().CommonSettings()->Read( ENBL_ZOOM_NO_CENTER_KEY, &m_enableZoomNoCenter, false );
114  Pgm().CommonSettings()->Read( ENBL_AUTO_PAN_KEY, &m_enableAutoPan, true );
115 
116  m_canStartBlock = -1; // Command block can start if >= 0
117  m_abortRequest = false;
118  m_ignoreMouseEvents = false;
119  // Be sure a mouse release button event will be ignored when creating the canvas
120  // if the mouse click was not made inside the canvas (can happen sometimes, when
121  // launching a editor from a double click made in another frame)
122  m_ignoreNextLeftButtonRelease = true;
123 
124  m_mouseCaptureCallback = NULL;
125  m_endMouseCaptureCallback = NULL;
126 
127  m_enableBlockCommands = false;
128  m_minDragEventCount = 0;
129 
130  m_cursorLevel = 0;
131  m_PrintIsMirrored = false;
132 
133  m_doubleClickInterval = 250;
134 
135  m_viewControls->SetSnapping( true );
136 
137  SetEvtHandlerEnabled( true );
138  SetFocus();
139  Show( true );
140  Raise();
141  StartDrawing();
142 }
143 
144 
146 {
147 }
148 
149 
151 {
152  view()->Clear();
153  view()->DisplayComponent( const_cast<LIB_PART*>(aComponent) );
154 
155 }
156 
157 
159 {
160  view()->Clear();
161  view()->DisplaySheet( const_cast<SCH_SHEET*>(aSheet) );
162 }
163 
164 
166 {
167  view()->Clear();
168 
169  if( aScreen )
170  view()->DisplaySheet( const_cast<SCH_SCREEN*>( aScreen ) );
171 }
172 
173 
175 {
176  //m_view->RecacheAllItems();
177 }
178 
179 
181 {
182  for( LAYER_NUM i = 0; (unsigned) i < sizeof( SCH_LAYER_ORDER ) / sizeof( LAYER_NUM ); ++i )
183  {
184  LAYER_NUM layer = SCH_LAYER_ORDER[i];
185  wxASSERT( layer < KIGFX::VIEW::VIEW_MAX_LAYERS );
186 
187  m_view->SetLayerOrder( layer, i );
188  }
189 }
190 
191 
193 {
194  VECTOR2D grid_size = m_gal->GetGridSize();
195  bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend( aGalType );
196  setDefaultLayerDeps();
197  m_gal->SetWorldUnitLength( SCH_WORLD_UNIT );
198 
199  // Keep grid size and grid visibility:
200  m_gal->SetGridSize( grid_size );
201  SCH_BASE_FRAME* frame = dynamic_cast<SCH_BASE_FRAME*>( GetParent() );
202 
203  if( frame )
204  m_gal->SetGridVisibility( frame->IsGridVisible() );
205 
206  Refresh();
207 
208  return rv;
209 }
210 
211 
213 {
214  m_enableMousewheelPan = aEnable;
215 
216  if( GetParent()->IsGalCanvasActive() )
217  GetParent()->GetGalCanvas()->GetViewControls()->EnableMousewheelPan( aEnable );
218 }
219 
220 
222 {
224 
225  if( GetParent()->IsGalCanvasActive() )
226  GetParent()->GetGalCanvas()->GetViewControls()->EnableAutoPan( aEnable );
227 }
228 
229 
231 {
232  wxCHECK( GetParent()->IsGalCanvasActive(), /*void*/ );
233  GetParent()->GetGalCanvas()->GetViewControls()->SetAutoPan( aEnable );
234 }
235 
236 
238 {
239  m_enableZoomNoCenter = aEnable;
240 
241  if( GetParent()->IsGalCanvasActive() )
242  GetParent()->GetGalCanvas()->GetViewControls()->EnableCursorWarping( !aEnable );
243 }
244 
245 
247 {
248  // caching makes no sense for Cairo and other software renderers
249  auto target = m_backend == GAL_TYPE_OPENGL ? KIGFX::TARGET_CACHED : KIGFX::TARGET_NONCACHED;
250 
251  for( int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++ )
252  m_view->SetLayerTarget( i, target );
253 
254  // Bitmaps are draw on a non cached GAL layer:
255  m_view->SetLayerTarget( LAYER_DRAW_BITMAPS , KIGFX::TARGET_NONCACHED );
256 
257  // Some draw layers need specific settings
258  m_view->SetLayerTarget( LAYER_GP_OVERLAY , KIGFX::TARGET_OVERLAY );
259  m_view->SetLayerDisplayOnly( LAYER_GP_OVERLAY ) ;
260 
261  m_view->SetLayerTarget( LAYER_SELECT_OVERLAY , KIGFX::TARGET_OVERLAY );
262  m_view->SetLayerDisplayOnly( LAYER_SELECT_OVERLAY ) ;
263 
264  m_view->SetLayerTarget( LAYER_WORKSHEET , KIGFX::TARGET_NONCACHED );
265  m_view->SetLayerDisplayOnly( LAYER_WORKSHEET ) ;
266 }
267 
268 
270 {
271  return static_cast<KIGFX::SCH_VIEW*>( m_view );
272 }
273 
275 {
276  return GetParent()->GetScreen();
277 }
278 
280 {
281  return static_cast<EDA_DRAW_FRAME*>(m_parent); // static_cast<SCH_EDIT_FRAME*> (m_parent);
282 }
283 
284 
285 void SCH_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event )
286 {
287  int localbutt = 0;
288  BASE_SCREEN* screen = GetScreen();
289  auto controls = GetViewControls();
290  auto vmp = VECTOR2I( controls->GetMousePosition() );
291  wxPoint mousePos ( vmp.x, vmp.y );
292 
293  event.Skip();
294 
295  if( !screen )
296  return;
297 
298  /* Adjust value to filter mouse displacement before consider the drag
299  * mouse is really a drag command, not just a movement while click
300  */
301 #define MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND 5
302 
303  if( event.Leaving() )
304  m_canStartBlock = -1;
305 
306  if( !IsMouseCaptured() ) // No mouse capture in progress.
307  SetAutoPanRequest( false );
308 
309  if( GetParent()->IsActive() )
310  SetFocus();
311  else
312  return;
313 
314  if( !event.IsButton() && !event.Moving() && !event.Dragging() )
315  return;
316 
317  if( event.RightUp() )
318  {
319  OnRightClick( event );
320  return;
321  }
322 
323  if( m_ignoreMouseEvents )
324  return;
325 
326  if( event.LeftDown() )
327  localbutt = GR_M_LEFT_DOWN;
328 
329  if( event.ButtonDClick( 1 ) )
330  localbutt = GR_M_LEFT_DOWN | GR_M_DCLICK;
331 
332  if( event.MiddleDown() )
333  localbutt = GR_M_MIDDLE_DOWN;
334 
335  // Compute the cursor position in drawing (logical) units.
336  //GetParent()->SetMousePosition( event.GetLogicalPosition( DC ) );
337 
338  int kbstat = 0;
339 
340  if( event.ShiftDown() )
341  kbstat |= GR_KB_SHIFT;
342 
343  if( event.ControlDown() )
344  kbstat |= GR_KB_CTRL;
345 
346  if( event.AltDown() )
347  kbstat |= GR_KB_ALT;
348 
349  // Calling Double Click and Click functions :
350  if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) )
351  {
352  GetParent()->OnLeftDClick( nullptr, mousePos );
353 
354  // inhibit a response to the mouse left button release,
355  // because we have a double click, and we do not want a new
356  // OnLeftClick command at end of this Double Click
357  m_ignoreNextLeftButtonRelease = true;
358  }
359  else if( event.LeftUp() )
360  {
361  // A block command is in progress: a left up is the end of block
362  // or this is the end of a double click, already seen
363  // Note also m_ignoreNextLeftButtonRelease can be set by
364  // the call to OnLeftClick(), so do not change it after calling OnLeftClick
365  bool ignoreEvt = m_ignoreNextLeftButtonRelease;
366  m_ignoreNextLeftButtonRelease = false;
367 
368  if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK && !ignoreEvt )
369  GetParent()->OnLeftClick( nullptr, mousePos );
370 
371  }
372  else if( !event.LeftIsDown() )
373  {
374  /* be sure there is a response to a left button release command
375  * even when a LeftUp event is not seen. This happens when a
376  * double click opens a dialog box, and the release mouse button
377  * is made when the dialog box is opened.
378  */
379  m_ignoreNextLeftButtonRelease = false;
380  }
381 
382  if( event.ButtonDown( wxMOUSE_BTN_MIDDLE ) )
383  {
384  m_PanStartCenter = GetParent()->GetScrollCenterPosition();
385  m_PanStartEventPosition = event.GetPosition();
386 
387  CrossHairOff( );
388  SetCurrentCursor( wxCURSOR_SIZING );
389  }
390 
391  if( event.ButtonUp( wxMOUSE_BTN_MIDDLE ) )
392  {
393  CrossHairOn();
394  SetDefaultCursor();
395  }
396 
397  if( event.MiddleIsDown() )
398  {
399  // already managed by EDA_DRAW_PANEL_GAL mouse event handler.
400  return;
401  }
402 
403  // Calling the general function on mouse changes (and pseudo key commands)
404  GetParent()->GeneralControl( nullptr, mousePos );
405 
406  /*******************************/
407  /* Control of block commands : */
408  /*******************************/
409 
410  // Command block can't start if mouse is dragging a new panel
411  static SCH_DRAW_PANEL* lastPanel;
412  if( lastPanel != this )
413  {
414  m_minDragEventCount = 0;
415  m_canStartBlock = -1;
416  }
417 
418  /* A new command block can start after a release buttons
419  * and if the drag is enough
420  * This is to avoid a false start block when a dialog box is dismissed,
421  * or when changing panels in hierarchy navigation
422  * or when clicking while and moving mouse
423  */
424  if( !event.LeftIsDown() && !event.MiddleIsDown() )
425  {
426  m_minDragEventCount = 0;
427  m_canStartBlock = 0;
428 
429  /* Remember the last cursor position when a drag mouse starts
430  * this is the last position ** before ** clicking a button
431  * this is useful to start a block command from the point where the
432  * mouse was clicked first
433  * (a filter creates a delay for the real block command start, and
434  * we must remember this point)
435  */
436  m_CursorStartPos = GetParent()->GetCrossHairPosition();
437  }
438 
439  if( m_enableBlockCommands && !(localbutt & GR_M_DCLICK) )
440  {
441  if( !screen->IsBlockActive() )
442  {
443  screen->m_BlockLocate.SetOrigin( m_CursorStartPos );
444  }
445 
446  if( event.LeftDown() )
447  {
448  if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
449  {
450  SetAutoPanRequest( false );
451  GetParent()->HandleBlockPlace( nullptr );
452  m_ignoreNextLeftButtonRelease = true;
453  }
454  }
455  else if( ( m_canStartBlock >= 0 ) && event.LeftIsDown() && !IsMouseCaptured() )
456  {
457  // Mouse is dragging: if no block in progress, start a block command.
458  if( screen->m_BlockLocate.GetState() == STATE_NO_BLOCK )
459  {
460  // Start a block command
461  int cmd_type = kbstat;
462 
463  // A block command is started if the drag is enough. A small
464  // drag is ignored (it is certainly a little mouse move when
465  // clicking) not really a drag mouse
466  if( m_minDragEventCount < MIN_DRAG_COUNT_FOR_START_BLOCK_COMMAND )
467  m_minDragEventCount++;
468  else
469  {
470  auto cmd = (GetParent()->GetToolId() == ID_ZOOM_SELECTION) ? BLOCK_ZOOM : 0;
471 
472  DBG(printf("start block\n");)
473 
474  if( !GetParent()->HandleBlockBegin( nullptr, cmd_type, m_CursorStartPos, cmd ) )
475  {
476  // should not occur: error
477  GetParent()->DisplayToolMsg(
478  wxT( "EDA_DRAW_PANEL::OnMouseEvent() Block Error" ) );
479  }
480  else
481  {
482  SetAutoPanRequest( true );
483  SetCursor( wxCURSOR_SIZING );
484  }
485  }
486  }
487  }
488 
489  if( event.ButtonUp( wxMOUSE_BTN_LEFT ) )
490  {
491  /* Release the mouse button: end of block.
492  * The command can finish (DELETE) or have a next command (MOVE,
493  * COPY). However the block command is canceled if the block
494  * size is small because a block command filtering is already
495  * made, this case happens, but only when the on grid cursor has
496  * not moved.
497  */
498  #define BLOCK_MINSIZE_LIMIT 1
499  bool BlockIsSmall =
501  && ( std::abs( screen->m_BlockLocate.GetHeight() ) < BLOCK_MINSIZE_LIMIT );
502 
503  if( (screen->m_BlockLocate.GetState() != STATE_NO_BLOCK) && BlockIsSmall )
504  {
505  if( m_endMouseCaptureCallback )
506  {
507  m_endMouseCaptureCallback( this, nullptr );
508  SetAutoPanRequest( false );
509  }
510 
511  //SetCursor( (wxStockCursor) m_currentCursor );
512  }
513  else if( screen->m_BlockLocate.GetState() == STATE_BLOCK_END )
514  {
515  SetAutoPanRequest( false );
516  GetParent()->HandleBlockEnd( nullptr );
517  //SetCursor( (wxStockCursor) m_currentCursor );
518  if( screen->m_BlockLocate.GetState() == STATE_BLOCK_MOVE )
519  {
520  SetAutoPanRequest( true );
521  SetCursor( wxCURSOR_HAND );
522  }
523  }
524  }
525  }
526 
527  // End of block command on a double click
528  // To avoid an unwanted block move command if the mouse is moved while double clicking
529  if( localbutt == (int) ( GR_M_LEFT_DOWN | GR_M_DCLICK ) )
530  {
531  if( !screen->IsBlockActive() && IsMouseCaptured() )
532  {
533  m_endMouseCaptureCallback( this, nullptr );
534  }
535  }
536 
537  lastPanel = this;
538 }
539 
540 
541 bool SCH_DRAW_PANEL::OnRightClick( wxMouseEvent& event )
542 {
543  auto controls = GetViewControls();
544  auto vmp = controls->GetMousePosition();
545  wxPoint mouseWorldPos ( (int) vmp.x, (int) vmp.y );
546 
547  wxMenu MasterMenu;
548 
549  if( !GetParent()->OnRightClick( mouseWorldPos, &MasterMenu ) )
550  return false;
551 
552  GetParent()->AddMenuZoomAndGrid( &MasterMenu );
553 
554  m_ignoreMouseEvents = true;
555  PopupMenu( &MasterMenu, event.GetPosition() );
556  m_ignoreMouseEvents = false;
557 
558  return true;
559 }
560 
561 void SCH_DRAW_PANEL::CallMouseCapture( wxDC* aDC, const wxPoint& aPosition, bool aErase )
562 {
563  wxCHECK_RET( m_mouseCaptureCallback != NULL, wxT( "Mouse capture callback not set." ) );
564 
565  m_mouseCaptureCallback( this, aDC, aPosition, aErase );
566 }
567 
568 
570 {
571  // CallEndMouseCapture is sometimes called with m_endMouseCaptureCallback == NULL
572  // for instance after an ABORT in block paste.
573  if( m_endMouseCaptureCallback )
574  m_endMouseCaptureCallback( this, aDC );
575 }
576 
577 
578 void SCH_DRAW_PANEL::EndMouseCapture( int id, int cursor, const wxString& title,
579  bool aCallEndFunc )
580 {
581  if( m_mouseCaptureCallback && m_endMouseCaptureCallback && aCallEndFunc )
582  {
583  m_endMouseCaptureCallback( this, nullptr );
584  }
585 
586  m_mouseCaptureCallback = NULL;
587  m_endMouseCaptureCallback = NULL;
588  SetAutoPanRequest( false );
589 
590  if( id != -1 && cursor != -1 )
591  {
592  //wxASSERT( cursor > wxCURSOR_NONE && cursor < wxCURSOR_MAX );
593  GetParent()->SetToolID( id, cursor, title );
594  }
595 }
596 
598 {
599  m_viewControls->ShowCursor( false );
600 }
601 
602 
604 {
605  m_viewControls->ShowCursor( true );
606 }
607 
608 
610 {
611  GetViewControls()->WarpCursor( GetParent()->GetCrossHairPosition(), true );
612 }
613 
614 
615 void SCH_DRAW_PANEL::Refresh( bool aEraseBackground, const wxRect* aRect )
616 {
617  EDA_DRAW_PANEL_GAL::Refresh( aEraseBackground, aRect );
618 }
619 
620 
621 void SCH_DRAW_PANEL::OnCharHook( wxKeyEvent& event )
622 {
623  event.Skip();
624 }
625 
626 
627 void SCH_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event )
628 {
629  int localkey;
630 
631  localkey = event.GetKeyCode();
632 
633  switch( localkey )
634  {
635  default:
636  break;
637 
638  case WXK_ESCAPE:
639  m_abortRequest = true;
640 
641  if( IsMouseCaptured() )
642  EndMouseCapture();
643  else
644  EndMouseCapture( ID_NO_TOOL_SELECTED, 0 /*m_defaultCursor*/, wxEmptyString );
645  break;
646  }
647 
648  /* Normalize keys code to easily handle keys from Ctrl+A to Ctrl+Z
649  * They have an ascii code from 1 to 27 remapped
650  * to GR_KB_CTRL + 'A' to GR_KB_CTRL + 'Z'
651  */
652  if( event.ControlDown() && localkey >= WXK_CONTROL_A && localkey <= WXK_CONTROL_Z )
653  localkey += 'A' - 1;
654 
655  /* Disallow shift for keys that have two keycodes on them (e.g. number and
656  * punctuation keys) leaving only the "letter keys" of A-Z.
657  * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout)
658  * and Ctrl-( and Ctrl-5 (FR layout).
659  * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout
660  */
661  bool keyIsLetter = ( localkey >= 'A' && localkey <= 'Z' ) ||
662  ( localkey >= 'a' && localkey <= 'z' );
663 
664  if( event.ShiftDown() && ( keyIsLetter || localkey > 256 ) )
665  localkey |= GR_KB_SHIFT;
666 
667  if( event.ControlDown() )
668  localkey |= GR_KB_CTRL;
669 
670  if( event.AltDown() )
671  localkey |= GR_KB_ALT;
672 
673 
674  // Some key commands use the current mouse position: refresh it.
675  //pos = wxGetMousePosition() - GetScreenPosition();
676 
677  // Compute the cursor position in drawing units. Also known as logical units to wxDC.
678  //pos = wxPoint( DC.DeviceToLogicalX( pos.x ), DC.DeviceToLogicalY( pos.y ) );
679 
680  auto p = GetViewControls()->GetCursorPosition( false );
681 
682  wxPoint pos ((int)p.x, (int)p.y);
683 
684  GetParent()->SetMousePosition( pos );
685 
686  if( !GetParent()->GeneralControl( nullptr, pos, localkey ) )
687  event.Skip();
688 }
689 
690 
691 void SCH_DRAW_PANEL::onPaint( wxPaintEvent& aEvent )
692 {
693  if( !m_gal->IsInitialized() || !m_gal->IsVisible() )
694  // The first wxPaintEvent can be fired at startup before the GAL engine is fully initialized
695  // (depending on platforms). Do nothing in this case
696  return;
697 
698  if( m_painter )
699  static_cast<KIGFX::SCH_PAINTER*>(m_painter.get())->GetSettings()->ImportLegacyColors( nullptr );
700 
701  EDA_DRAW_PANEL_GAL::onPaint( aEvent );
702 }
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
BLOCK_STATE_T GetState() 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
bool IsBlockActive() const
Definition: base_screen.h:499
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:57
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:42
virtual bool SwitchBackend(GAL_TYPE aGalType)
Function SwitchBackend Switches method of rendering graphics.
virtual bool IsGridVisible() const
Definition: draw_frame.h:535
virtual void MoveCursorToCrossHair() override
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
int GetWidth() const
Definition: eda_rect.h:117
#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:81
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
#define abs(a)
Definition: auxiliary.h:84
WX_VIEW_CONTROLS class definition.
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:712
virtual void CallEndMouseCapture(wxDC *aDC) override
Function CallEndMouseCapture calls the end mouse capture callback.
#define ENBL_ZOOM_NO_CENTER_KEY
Definition: pgm_base.h:48
Auxiliary rendering target (noncached)
Definition: definitions.h:49
static const LAYER_NUM SCH_LAYER_ORDER[]
Definition: sch_view.h:44
void OnMouseEvent(wxMouseEvent &event)
Class that handles properties and drawing of worksheet layout.
#define ENBL_AUTO_PAN_KEY
Definition: pgm_base.h:51
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:113
void SetEnableAutoPan(bool aEnable) override
KIGFX::SCH_VIEW * view() const
virtual void onPaint(wxPaintEvent &WXUNUSED(aEvent)) override
Define a library symbol object.
#define ENBL_MOUSEWHEEL_PAN_KEY
Definition: pgm_base.h:49
Items that may change while the view stays the same (noncached)
Definition: definitions.h:50
virtual void CrossHairOn(wxDC *DC=nullptr) override
void setDefaultLayerDeps()
Sets rendering targets & dependencies for layers.
#define GR_KB_SHIFT
VTBL_ENTRY wxConfigBase * CommonSettings() const
Definition: pgm_base.h:189
int GetHeight() const
Definition: eda_rect.h:118
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...
void SetAutoPanRequest(bool aEnable) override
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:48
size_t i
Definition: json11.cpp:597
void DisplaySheet(const SCH_SHEET *aSheet)
currently selected items overlay
void OnCharHook(wxKeyEvent &event)
BASE_SCREEN * GetScreen() override
#define DBG(x)
Definition: fctsys.h:33
A shim class between EDA_DRAW_FRAME and several derived classes: LIB_EDIT_FRAME, LIB_VIEW_FRAME,...
virtual void SetEnableAutoPan(bool aEnable)
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