1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25 
26 #ifndef DRAW_FRAME_H_
27 #define DRAW_FRAME_H_
28 
29 #include <eda_base_frame.h>
30 #include <kiway_player.h>
31 #include <gal/gal_display_options.h>
32 #include <gal/color4d.h>
33 #include <class_draw_panel_gal.h>
34 #include <origin_transforms.h>
35 #include <kiid.h>
36 #include "hotkeys_basic.h"
37 
38 class EDA_ITEM;
39 class wxSingleInstanceChecker;
40 class ACTION_TOOLBAR;
41 class COLOR_SETTINGS;
42 class TOOL_MENU;
43 class APP_SETTINGS_BASE;
44 class wxFindReplaceData;
45 
46 namespace KIGFX
47 {
48     class GAL_DISPLAY_OPTIONS;
49     class RENDER_SETTINGS;
50 }
51 
52 using KIGFX::COLOR4D;
53 using KIGFX::RENDER_SETTINGS;
54 
55 #define LIB_EDIT_FRAME_NAME                 wxT( "LibeditFrame" )
56 #define SCH_EDIT_FRAME_NAME                 wxT( "SchematicFrame" )
57 #define PL_EDITOR_FRAME_NAME                wxT( "PlEditorFrame" )
58 #define FOOTPRINT_WIZARD_FRAME_NAME         wxT( "FootprintWizard" )
59 #define FOOTPRINT_EDIT_FRAME_NAME           wxT( "ModEditFrame" )
60 #define FOOTPRINT_VIEWER_FRAME_NAME         wxT( "ModViewFrame" )
61 #define FOOTPRINT_VIEWER_FRAME_NAME_MODAL   wxT( "ModViewFrameModal" )
62 #define PCB_EDIT_FRAME_NAME                 wxT( "PcbFrame" )
63 
64 
65 /**
66  * The base class for create windows for drawing purpose.
67  *
68  * The Eeschema, Pcbnew and GerbView main windows are just a few examples of classes
69  * derived from EDA_DRAW_FRAME.
70  */
71 class EDA_DRAW_FRAME : public KIWAY_PLAYER
72 {
73 public:
74     EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle,
75                     const wxPoint& aPos, const wxSize& aSize, long aStyle,
76                     const wxString& aFrameName );
77 
78     ~EDA_DRAW_FRAME();
79 
80     /**
81      * Mark a schematic file as being in use.
82      *
83      * Use #ReleaseFile() to undo this.
84      *
85      * @param aFileName full path to the file.
86      * @return false if the file was already locked, true otherwise.
87      */
88     bool LockFile( const wxString& aFileName );
89 
90     /**
91      * Release the current file marked in use.  See m_file_checker.
92      */
93     void ReleaseFile();
94 
95     /**
96      * Toggles the scripting console visibility
97      */
98     void ScriptingConsoleEnableDisable();
99 
100     /**
101      * Gets the current visibility of the scripting console window
102      */
103     bool IsScriptingConsoleVisible();
104 
GetFindReplaceData()105     wxFindReplaceData& GetFindReplaceData() { return *m_findReplaceData; }
GetFindHistoryList()106     wxArrayString& GetFindHistoryList() { return m_findStringHistoryList; }
107 
108     virtual void SetPageSettings( const PAGE_INFO& aPageSettings ) = 0;
109     virtual const PAGE_INFO& GetPageSettings() const = 0;
110 
111     /**
112      * Works off of GetPageSettings() to return the size of the paper page in
113      * the internal units of this particular view.
114      */
115     virtual const wxSize GetPageSizeIU() const = 0;
116 
117     /**
118      * For those frames that support polar coordinates.
119      */
GetShowPolarCoords()120     bool GetShowPolarCoords() const { return m_polarCoords; }
SetShowPolarCoords(bool aShow)121     void SetShowPolarCoords( bool aShow ) { m_polarCoords = aShow; }
122 
123     void ToggleUserUnits() override;
124 
125     /**
126      * Get the pair or units in current use.
127      *
128      * The primary unit is the main unit of the frame, and the secondary unit is the unit
129      * of the other system that was used most recently.
130      */
131     void GetUnitPair( EDA_UNITS& aPrimaryUnit, EDA_UNITS& aSecondaryUnits );
132 
133     /**
134      * Return the absolute coordinates of the origin of the snap grid.
135      *
136      * This is treated as a relative offset and snapping will occur at multiples of the grid
137      * size relative to this point.
138      */
139     virtual const wxPoint& GetGridOrigin() const = 0;
140     virtual void SetGridOrigin( const wxPoint& aPosition ) = 0;
141 
142     /**
143      * Return the nearest \a aGridSize location to \a aPosition.
144      *
145      * @param aPosition The position to check.
146      * @return The nearest grid position.
147      */
148     wxPoint GetNearestGridPosition( const wxPoint& aPosition ) const;
149 
150     /**
151      * Return the nearest \a aGridSize / 2 location to \a aPosition.
152      *
153      * This is useful when attempting for keep outer points on grid but
154      * not the middle point.
155      *
156      * @param aPosition The position to check.
157      * @return The nearest half-grid position.
158      */
159     wxPoint GetNearestHalfGridPosition( const wxPoint& aPosition ) const;
160 
161     /**
162      * Return a reference to the default ORIGIN_TRANSFORMS object
163      */
GetOriginTransforms()164     virtual ORIGIN_TRANSFORMS& GetOriginTransforms()
165     { return m_originTransforms; }
166 
167 
168     virtual const TITLE_BLOCK& GetTitleBlock() const = 0;
169     virtual void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) = 0;
170 
171     // the background color of the draw canvas:
172     // Virtual because some frames can have a specific way to get/set the bg color
GetDrawBgColor()173     virtual COLOR4D GetDrawBgColor() const { return m_drawBgColor; }
SetDrawBgColor(const COLOR4D & aColor)174     virtual void SetDrawBgColor( const COLOR4D& aColor) { m_drawBgColor= aColor ; }
175 
176     /// Returns a pointer to the active color theme settings
177     virtual COLOR_SETTINGS* GetColorSettings() const;
178 
ShowPageLimits()179     bool ShowPageLimits() const { return m_showPageLimits; }
SetShowPageLimits(bool aShow)180     void SetShowPageLimits( bool aShow ) { m_showPageLimits = aShow; }
181 
182     /**
183      * @param doOpen if true runs an Open Library browser, otherwise New Library
184      * @param aFilename for New may contain a default name; in both cases return the chosen
185      *                  filename.
186      * @param wildcard a wildcard to filter the displayed files
187      * @param ext the library file extension
188      * @param isDirectory indicates the library files are directories
189      * @return true for OK; false for Cancel.
190      */
191     bool LibraryFileBrowser( bool doOpen, wxFileName& aFilename, const wxString& wildcard,
192                              const wxString& ext, bool isDirectory = false, bool aIsGlobal = false,
193                              const wxString& aGlobalPath = wxEmptyString );
194 
195     void CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) override;
196 
197     virtual wxString GetScreenDesc() const;
198 
199     /**
200      * Return a pointer to a BASE_SCREEN or one of its derivatives.
201      *
202      * It is overloaded by derived classes to return #SCH_SCREEN or #PCB_SCREEN.
203      */
GetScreen()204     virtual BASE_SCREEN* GetScreen() const  { return m_currentScreen; }
205 
206     void EraseMsgBox();
207 
ReCreateMenuBar()208     void ReCreateMenuBar() override { }
209     virtual void ReCreateHToolbar() = 0;
210     virtual void ReCreateVToolbar() = 0;
211     virtual void ReCreateOptToolbar() = 0;
ReCreateAuxiliaryToolbar()212     virtual void ReCreateAuxiliaryToolbar() { }
213 
214     /**
215      * Update the sizes of any controls in the toolbars of the frame.
216      */
UpdateToolbarControlSizes()217     virtual void UpdateToolbarControlSizes() { }
218 
219     /*
220      * These 4 functions provide a basic way to show/hide grid and /get/set grid color.
221      *
222      * These parameters are saved in KiCad config for each main frame.
223      */
224     bool IsGridVisible() const;
225     virtual void SetGridVisibility( bool aVisible );
226 
GetGridColor()227     virtual COLOR4D GetGridColor() { return m_gridColor; }
SetGridColor(const COLOR4D & aColor)228     virtual void SetGridColor( const COLOR4D& aColor ) { m_gridColor = aColor; }
229 
230     /**
231      * Command event handler for selecting grid sizes.
232      *
233      * All commands that set the grid size should eventually end up here. This is where the
234      * application setting is saved.  If you override this method, make sure you call down
235      * to the base class.
236      *
237      * @param event Command event from the grid size combobox on the toolbar.
238      */
239     void OnSelectGrid( wxCommandEvent& event );
240 
241     void OnGridSettings( wxCommandEvent& event );
242 
243     /**
244      * Rebuild the grid combobox to respond to any changes in the GUI (units, user
245      * grid changes, etc.).
246      */
247     void UpdateGridSelectBox();
248 
249     /**
250      * Update the checked item in the grid combobox.
251      */
252     void OnUpdateSelectGrid( wxUpdateUIEvent& aEvent );
253 
254     /**
255      * Rebuild the grid combobox to respond to any changes in the GUI (units, user
256      * grid changes, etc.)
257      */
258     void UpdateZoomSelectBox();
259 
260     /**
261      * Update the checked item in the zoom combobox.
262      */
263     void OnUpdateSelectZoom( wxUpdateUIEvent& aEvent );
264 
265     /**
266      * Return a human readable value for display in dialogs.
267      */
268     const wxString GetZoomLevelIndicator() const;
269 
270     /**
271      * Set the zoom factor when selected by the zoom list box in the main tool bar.
272      *
273      * @note List position 0 is fit to page.
274      *       List position >= 1 = zoom (1 to zoom max).
275      *       Last list position is custom zoom not in zoom list.
276      */
277     virtual void OnSelectZoom( wxCommandEvent& event );
278 
279     /**
280      * Recalculate the size of toolbars and display panel when the frame size changes.
281      */
282     virtual void OnSize( wxSizeEvent& event ) override;
283 
284     void OnMove( wxMoveEvent& aEvent ) override;
285 
286     /**
287      * Rebuild the GAL and redraws the screen.  Call when something went wrong.
288      */
289     virtual void HardRedraw();
290 
291     /**
292      * Redraw the screen with best zoom level and the best centering that shows all the
293      * page or the board.
294      */
295     virtual void Zoom_Automatique( bool aWarpPointer );
296 
297     /**
298      * Useful to focus on a particular location, in find functions.
299      *
300      * Move the graphic cursor (crosshair cursor) at a given coordinate and reframes the
301      * drawing if the requested point is out of view or if center on location is requested.
302      *
303      * @param aPos is the point to go to.
304      */
305     void FocusOnLocation( const wxPoint& aPos );
306 
307     /**
308      * Construct a "basic" menu for a tool, containing only items that apply to all tools
309      * (e.g. zoom and grid).
310      */
311     void AddStandardSubMenus( TOOL_MENU& aMenu );
312 
313     /**
314      * Prints the drawing-sheet (frame and title block).
315      *
316      * @param aScreen screen to draw.
317      * @param aMils2Iu The mils to Iu conversion factor.
318      * @param aFilename The filename to display in basic inscriptions.
319      * @param aSheetLayer The layer displayed from PcbNew.
320      */
321     void PrintDrawingSheet( const RENDER_SETTINGS* aSettings, BASE_SCREEN* aScreen,
322                             double aMils2Iu, const wxString& aFilename,
323                             const wxString& aSheetLayer = wxEmptyString );
324 
325     void DisplayToolMsg( const wxString& msg ) override;
326 
327     void DisplayConstraintsMsg( const wxString& msg );
328 
329     /**
330      * Called when modifying the page settings.
331      * In derived classes it can be used to modify parameters like draw area size,
332      * and any other local parameter related to the page settings.
333      */
OnPageSettingsChange()334     virtual void OnPageSettingsChange() {}
335 
336     /**
337      * Update the status bar information.
338      *
339      * The EDA_DRAW_FRAME level updates the absolute and relative coordinates and the
340      * zoom information.  If you override this virtual method, make sure to call this
341      * subclassed method.
342      */
343     void UpdateStatusBar() override;
344 
345     /**
346      * Display current unit pane in the status bar.
347      */
348     void DisplayUnitsMsg();
349 
350     /**
351      * Display current grid size in the status bar.
352      */
353     virtual void DisplayGridMsg();
354 
355     void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
356     void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
357 
358     /**
359      * Append a message to the message panel.
360      *
361      * This helper method checks to make sure the message panel exists in the frame and
362      * appends a message to it using the message panel AppendMessage() method.
363      *
364      * @param aTextUpper The message upper text.
365      * @param aTextLower The message lower text.
366      * @param aPadding Number of spaces to pad between messages.
367      */
368     void AppendMsgPanel( const wxString& aTextUpper, const wxString& aTextLower, int aPadding = 6 );
369 
370     /**
371      * Clear all messages from the message panel.
372      */
373     virtual void ClearMsgPanel();
374 
375     /**
376      * Clear the message panel and populates it with the contents of \a aList.
377      *
378      * @param aList is the list of #MSG_PANEL_ITEM objects to fill the message panel.
379      */
380     void SetMsgPanel( const std::vector< MSG_PANEL_ITEM >& aList );
381     void SetMsgPanel( EDA_ITEM* aItem );
382 
383     /**
384      * Helper function that erases the msg panel and then appends a single message
385      *
386      * @param aTextUpper The message upper text.
387      * @param aTextLower The message lower text.
388      * @param aPadding Number of spaces to pad between messages.
389      */
390     void SetMsgPanel( const wxString& aTextUpper, const wxString& aTextLower, int aPadding = 6 );
391 
392     /**
393      * Redraw the message panel.
394      */
395     virtual void UpdateMsgPanel();
396 
397     /**
398      * Fetch an item by KIID.  Frame-type-specific implementation.
399      */
GetItem(const KIID & aId)400     virtual EDA_ITEM* GetItem( const KIID& aId ) const { return nullptr; }
401 
402     /**
403      * Print the page pointed by current screen, set by the calling print function.
404      *
405      * @param aDC wxDC given by the calling print function
406      */
407     virtual void PrintPage( const RENDER_SETTINGS* aSettings );
408 
409     /**
410      * Use to start up the GAL drawing canvas.
411      */
412     virtual void ActivateGalCanvas();
413 
414     /**
415      * Changes the current rendering backend.
416      */
417     virtual void SwitchCanvas( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType );
418 
419     /**
420      * Return a pointer to GAL-based canvas of given EDA draw frame.
421      *
422      * @return Pointer to GAL-based canvas.
423      */
GetCanvas()424     virtual EDA_DRAW_PANEL_GAL* GetCanvas() const { return m_canvas; }
SetCanvas(EDA_DRAW_PANEL_GAL * aPanel)425     void SetCanvas( EDA_DRAW_PANEL_GAL* aPanel ) { m_canvas = aPanel; }
426 
GetToolCanvas()427     wxWindow* GetToolCanvas() const override { return GetCanvas(); }
428 
429     /**
430      * Return a reference to the gal rendering options used by GAL for rendering.
431      */
GetGalDisplayOptions()432     KIGFX::GAL_DISPLAY_OPTIONS& GetGalDisplayOptions() { return m_galDisplayOptions; }
433 
RefreshCanvas()434     void RefreshCanvas() override
435     {
436         GetCanvas()->Refresh();
437     }
438 
439     /**
440      * Returns bbox of document with option to not include some items.
441      *
442      * Used most commonly by "Zoom to Fit" and "Zoom to Objects".  In Eeschema for "Zoom to Fit"
443      * it's passed "true" to include drawing sheet border, and "false" by "Zoom To Objects" to
444      * ignore drawing sheet border.  In Pcbnew, false makes it ignore any items outside the PCB
445      * edge such as fabrication notes.
446      *
447      * @param aIncludeAllVisible True to include everything visible in bbox calculations,
448      *                           false to ignore some visible items (program dependent).
449      * @return Bounding box of the document (ignoring some items as requested).
450      */
451     virtual const BOX2I GetDocumentExtents( bool aIncludeAllVisible = true ) const;
452 
453     /**
454      * Rebuild all toolbars, and update the checked state of check tools
455      */
456     void RecreateToolbars();
457 
DECLARE_EVENT_TABLE()458     DECLARE_EVENT_TABLE()
459 
460 protected:
461     virtual void SetScreen( BASE_SCREEN* aScreen )  { m_currentScreen = aScreen; }
462 
463     void unitsChangeRefresh() override;
464 
465     void setupUnits( APP_SETTINGS_BASE* aCfg );
466 
467     std::vector<wxWindow*> findDialogs();
468 
469     /**
470      * Determines the Canvas type to load (with prompt if required) and initializes m_canvasType
471      */
472     void resolveCanvasType();
473 
474     /**
475      * Returns the canvas type stored in the application settings.
476      */
477     EDA_DRAW_PANEL_GAL::GAL_TYPE loadCanvasTypeSetting();
478 
479     /**
480      * Stores the canvas type in the application settings.
481      */
482     bool saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvasType );
483 
484     /**
485      * Handle a window activation event.
486      */
487     virtual void handleActivateEvent( wxActivateEvent& aEvent );
488     void onActivate( wxActivateEvent& aEvent );
489 
490 
491     wxSocketServer*             m_socketServer;
492     std::vector<wxSocketBase*>  m_sockets;         ///< interprocess communication
493 
494     ///< Prevents opening same file multiple times.
495     std::unique_ptr<wxSingleInstanceChecker> m_file_checker;
496 
497     bool               m_showPageLimits;    // True to display the page limits
498     COLOR4D            m_gridColor;         // Grid color
499     COLOR4D            m_drawBgColor;       // The background color of the draw canvas; BLACK for
500                                             // Pcbnew, BLACK or WHITE for Eeschema
501     int                m_undoRedoCountMax;  // Default Undo/Redo command Max depth, to be handed
502                                             // to screens
503     bool               m_polarCoords;       // For those frames that support polar coordinates
504 
505     bool               m_showBorderAndTitleBlock;  // Show the drawing sheet (border & title block).
506     long               m_firstRunDialogSetting;    // Show first run dialog on startup
507 
508     wxChoice*          m_gridSelectBox;
509     wxChoice*          m_zoomSelectBox;
510 
511     ACTION_TOOLBAR*    m_mainToolBar;
512     ACTION_TOOLBAR*    m_auxiliaryToolBar;  // Additional tools under main toolbar
513     ACTION_TOOLBAR*    m_drawToolBar;       // Drawing tools (typically on right edge of window)
514     ACTION_TOOLBAR*    m_optionsToolBar;    // Options (typically on left edge of window)
515 
516     wxFindReplaceData* m_findReplaceData;
517     wxArrayString      m_findStringHistoryList;
518     wxArrayString      m_replaceStringHistoryList;
519 
520     EDA_MSG_PANEL*     m_messagePanel;
521     int                m_msgFrameHeight;
522 
523     COLOR_SETTINGS*    m_colorSettings;
524 
525     ///< The current canvas type.
526     EDA_DRAW_PANEL_GAL::GAL_TYPE    m_canvasType;
527 
528 private:
529     BASE_SCREEN*                m_currentScreen;      ///< current used SCREEN
530     EDA_DRAW_PANEL_GAL*         m_canvas;
531 
532     ///< This the frame's interface to setting GAL display options.
533     KIGFX::GAL_DISPLAY_OPTIONS  m_galDisplayOptions;
534 
535     ///< Default display origin transforms object.
536     ORIGIN_TRANSFORMS           m_originTransforms;
537 };
538 
539 #endif  // DRAW_FRAME_H_
540