You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

496 lines
16 KiB

14 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
  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. #ifndef LAYERWIDGET_H_
  25. #define LAYERWIDGET_H_
  26. #include <wx/intl.h>
  27. #include <wx/wx.h>
  28. #include <wx/statbmp.h>
  29. #include <wx/string.h>
  30. #include <wx/aui/auibook.h>
  31. #include <wx/notebook.h>
  32. #include <wx/sizer.h>
  33. #include <wx/gdicmn.h>
  34. #include <wx/scrolwin.h>
  35. #include <wx/font.h>
  36. #include <wx/colour.h>
  37. #include <wx/settings.h>
  38. #include <wx/panel.h>
  39. #include <wx/bitmap.h>
  40. #include <wx/image.h>
  41. #include <wx/icon.h>
  42. #include <layers_id_colors_and_visibility.h>
  43. #include <gal/color4d.h>
  44. #include <widgets/color_swatch.h>
  45. #include <widgets/indicator_icon.h>
  46. #define LYR_COLUMN_COUNT 5 ///< Layer tab column count
  47. #define RND_COLUMN_COUNT 2 ///< Rendering tab column count
  48. #define COLUMN_ICON_ACTIVE 0
  49. #define COLUMN_COLORBM 1
  50. #define COLUMN_COLOR_LYR_CB 2
  51. #define COLUMN_COLOR_LYRNAME 3
  52. #define COLUMN_ALPHA_INDICATOR 4
  53. using KIGFX::COLOR4D;
  54. /**
  55. * LAYER_WIDGET
  56. * is abstract and is used to manage a list of layers, with the notion of
  57. * a "current" layer, and layer specific visibility control. You must derive from
  58. * it to use it so you can implement the abstract functions which recieve the
  59. * events. Each layer is given its own color, and that color can be changed
  60. * within the UI provided here. This widget knows nothing of the client code, meaning
  61. * it has no knowledge of a BOARD or anything. To use it you must derive from
  62. * this class and implement the abstract functions:
  63. * <p> void OnLayerColorChange( int aLayer, int aColor );
  64. * <p> bool OnLayerSelect( int aLayer );
  65. * <p> void OnLayerVisible( int aLayer, bool isVisible );
  66. * <p> void OnRenderColorChange( int id, int aColor );
  67. * <p> void OnRenderEnable( int id, bool isEnabled );
  68. *
  69. * Please note that even if designed toward layers, it is used to
  70. * contain other stuff, too (the second page in pcbnew contains render
  71. * items, for example)
  72. */
  73. class LAYER_WIDGET : public wxPanel
  74. {
  75. public:
  76. /**
  77. * Struct ROW
  78. * provides all the data needed to add a row to a LAYER_WIDGET. This is
  79. * part of the public API for a LAYER_WIDGET.
  80. */
  81. struct ROW
  82. {
  83. wxString rowName; ///< the prompt or layername
  84. int id; ///< either a layer or "visible element" id
  85. COLOR4D color; ///< COLOR4D::UNSPECIFIED if none.
  86. bool state; ///< initial wxCheckBox state
  87. wxString tooltip; ///< if not empty, use this tooltip on row
  88. bool changeable; ///< if true, the state can be changed
  89. bool spacer; ///< if true, this row is a spacer
  90. COLOR4D defaultColor; ///< The default color for the row
  91. ROW( const wxString& aRowName, int aId, COLOR4D aColor = COLOR4D::UNSPECIFIED,
  92. const wxString& aTooltip = wxEmptyString, bool aState = true,
  93. bool aChangeable = true, COLOR4D aDefaultColor = COLOR4D::UNSPECIFIED )
  94. {
  95. rowName = aRowName;
  96. id = aId;
  97. color = aColor;
  98. state = aState;
  99. tooltip = aTooltip;
  100. changeable = aChangeable;
  101. spacer = false;
  102. defaultColor = aDefaultColor;
  103. }
  104. ROW()
  105. {
  106. id = 0;
  107. color = COLOR4D::UNSPECIFIED;
  108. state = true;
  109. changeable = true;
  110. spacer = true;
  111. defaultColor = COLOR4D::UNSPECIFIED;
  112. }
  113. };
  114. static const wxEventType EVT_LAYER_COLOR_CHANGE;
  115. protected:
  116. wxAuiNotebook* m_notebook;
  117. wxPanel* m_LayerPanel;
  118. wxScrolledWindow* m_LayerScrolledWindow;
  119. wxFlexGridSizer* m_LayersFlexGridSizer;
  120. wxPanel* m_RenderingPanel;
  121. wxScrolledWindow* m_RenderScrolledWindow;
  122. wxFlexGridSizer* m_RenderFlexGridSizer;
  123. wxWindow* m_FocusOwner;
  124. int m_CurrentRow; ///< selected row of layer list
  125. int m_PointSize;
  126. ROW_ICON_PROVIDER* m_IconProvider;
  127. /**
  128. * Virtual Function useAlternateBitmap
  129. * @return true if bitmaps shown in Render layer list
  130. * are alternate bitmaps, or false if they are "normal" bitmaps
  131. * This is a virtual function because Pcbnew uses normal bitmaps
  132. * but GerbView uses both bitmaps
  133. * (alternate bitmaps to show layers in use, normal fo others)
  134. */
  135. virtual bool useAlternateBitmap(int aRow) { return false; }
  136. /**
  137. * Subclasses can override this to provide accurate representation
  138. * of transparent colour swatches.
  139. */
  140. virtual COLOR4D getBackgroundLayerColor() { return COLOR4D::BLACK; }
  141. /**
  142. * Function encodeId
  143. * is here to allow saving a layer index within a control as its wxControl id,
  144. * but to do so in a way that all child wxControl ids within a wxWindow are unique,
  145. * since this is required by Windows.
  146. * @see getDecodedId()
  147. */
  148. static int encodeId( int aColumn, int aId );
  149. /**
  150. * Function getDecodedId
  151. * decodes \a aControlId to original un-encoded value. This of
  152. * course holds iff encodedId was called with a LAYER_NUM (this box
  153. * is used for other things than layers, too)
  154. */
  155. static LAYER_NUM getDecodedId( int aControlId );
  156. void OnLeftDownLayers( wxMouseEvent& event );
  157. /**
  158. * Function OnRightDownLayer
  159. * Called when user right-clicks a layer
  160. */
  161. void OnRightDownLayer( wxMouseEvent& event, COLOR_SWATCH* aColorSwatch, const wxString& aLayerName );
  162. /**
  163. * Function OnSwatchChanged()
  164. * is called when a user changes a swatch color
  165. */
  166. void OnLayerSwatchChanged( wxCommandEvent& aEvent );
  167. /**
  168. * Function OnLayerCheckBox
  169. * handles the "is layer visible" checkbox and propogates the
  170. * event to the client's notification function.
  171. */
  172. void OnLayerCheckBox( wxCommandEvent& event );
  173. /**
  174. * Function OnRightDownRender
  175. * Called when user right-clicks a render option
  176. */
  177. void OnRightDownRender( wxMouseEvent& aEvent, COLOR_SWATCH* aColorSwatch, const wxString& aRenderName );
  178. /**
  179. * Function OnRenderSwatchChanged
  180. * Called when user has changed the swatch color of a render entry
  181. */
  182. void OnRenderSwatchChanged( wxCommandEvent& aEvent );
  183. void OnRenderCheckBox( wxCommandEvent& event );
  184. void OnTabChange( wxNotebookEvent& event );
  185. /**
  186. * Function getLayerComp
  187. * returns the component within the m_LayersFlexGridSizer at @a aRow and @a aCol
  188. * or NULL if these parameters are out of range.
  189. *
  190. * @param aRow is the row index
  191. * @param aColumn is the column
  192. * @return wxWindow - the component installed within the sizer at given grid coordinate.
  193. */
  194. wxWindow* getLayerComp( int aRow, int aColumn ) const;
  195. wxWindow* getRenderComp( int aRow, int aColumn ) const;
  196. /**
  197. * Function findLayerRow
  198. * returns the row index that \a aLayer resides in, or -1 if not found.
  199. */
  200. int findLayerRow( LAYER_NUM aLayer ) const;
  201. int findRenderRow( int aId ) const;
  202. /**
  203. * Function insertLayerRow
  204. * appends or inserts a new row in the layer portion of the widget.
  205. */
  206. void insertLayerRow( int aRow, const ROW& aSpec );
  207. void insertRenderRow( int aRow, const ROW& aSpec );
  208. void setLayerCheckbox( LAYER_NUM aLayer, bool isVisible );
  209. void updateLayerRow( int aRow, const wxString& aName );
  210. /**
  211. * Function passOnFocus
  212. * gives away the keyboard focus up to the main parent window.
  213. */
  214. void passOnFocus();
  215. // popup menu ids.
  216. enum POPUP_ID
  217. {
  218. ID_CHANGE_LAYER_COLOR = wxID_HIGHEST,
  219. ID_CHANGE_RENDER_COLOR,
  220. ID_LAST_VALUE
  221. };
  222. public:
  223. /** Constructor
  224. * @param aParent is the parent window
  225. * @param aFocusOwner is the window that should be sent the focus after
  226. * @param id is the wxWindow id ( default = wxID_ANY)
  227. * @param pos is the window position
  228. * @param size is the window size
  229. * @param style is the window style
  230. * every operation.
  231. */
  232. LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, wxWindowID id = wxID_ANY,
  233. const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
  234. long style = wxTAB_TRAVERSAL );
  235. virtual ~LAYER_WIDGET();
  236. /**
  237. * Function GetBestSize
  238. * returns the preferred minimum size, taking into consideration the
  239. * dynamic content. Nothing in wxWidgets was reliable enough so this
  240. * overrides one of their functions.
  241. */
  242. wxSize GetBestSize() const;
  243. /**
  244. * Function GetLayerRowCount
  245. * returns the number of rows in the layer tab.
  246. */
  247. int GetLayerRowCount() const;
  248. /**
  249. * Function GetRenderRowCount
  250. * returns the number of rows in the render tab.
  251. */
  252. int GetRenderRowCount() const;
  253. /**
  254. * Function AppendLayerRow
  255. * appends a new row in the layer portion of the widget. The user must
  256. * ensure that ROW::id is unique for all existing rows on Windows.
  257. */
  258. void AppendLayerRow( const ROW& aRow );
  259. /**
  260. * Function AppendLayerRows
  261. * appends new rows in the layer portion of the widget. The user must
  262. * ensure that ROW::id is unique for all existing rows on Windows.
  263. */
  264. void AppendLayerRows( const ROW* aRowsArray, int aRowCount )
  265. {
  266. for( int row=0; row<aRowCount; ++row )
  267. AppendLayerRow( aRowsArray[row] );
  268. UpdateLayouts();
  269. }
  270. /**
  271. * Function ClearLayerRows
  272. * empties out the layer rows.
  273. */
  274. void ClearLayerRows();
  275. /**
  276. * Function AppendRenderRow
  277. * appends a new row in the render portion of the widget. The user must
  278. * ensure that ROW::id is unique for all existing rows on Windows.
  279. */
  280. void AppendRenderRow( const ROW& aRow );
  281. /**
  282. * Function AppendRenderRows
  283. * appends new rows in the render portion of the widget. The user must
  284. * ensure that ROW::id is unique for all existing rows on Windows.
  285. */
  286. void AppendRenderRows( const ROW* aRowsArray, int aRowCount )
  287. {
  288. for( int row=0; row<aRowCount; ++row )
  289. AppendRenderRow( aRowsArray[row] );
  290. UpdateLayouts();
  291. }
  292. /**
  293. * Function ClearRenderRows
  294. * empties out the render rows.
  295. */
  296. void ClearRenderRows();
  297. /**
  298. * Function SelectLayerRow
  299. * changes the row selection in the layer list to the given row.
  300. */
  301. void SelectLayerRow( int aRow );
  302. /**
  303. * Function SelectLayer
  304. * changes the row selection in the layer list to \a aLayer provided.
  305. */
  306. void SelectLayer( LAYER_NUM aLayer );
  307. /**
  308. * Function GetSelectedLayer
  309. * returns the selected layer or -1 if none.
  310. */
  311. LAYER_NUM GetSelectedLayer();
  312. /**
  313. * Function SetLayerVisible
  314. * sets \a aLayer visible or not. This does not invoke OnLayerVisible().
  315. */
  316. void SetLayerVisible( LAYER_NUM aLayer, bool isVisible );
  317. /**
  318. * Function IsLayerVisible
  319. * returns the visible state of the layer ROW associated with \a aLayer id.
  320. */
  321. bool IsLayerVisible( LAYER_NUM aLayer );
  322. /**
  323. * Function SetLayerColor
  324. * changes the color of \a aLayer
  325. */
  326. void SetLayerColor( LAYER_NUM aLayer, COLOR4D aColor );
  327. /**
  328. * Function GetLayerColor
  329. * returns the color of the layer ROW associated with \a aLayer id.
  330. */
  331. COLOR4D GetLayerColor( LAYER_NUM aLayer ) const;
  332. /**
  333. * Function SetRenderState
  334. * sets the state of the checkbox associated with \a aId within the
  335. * Render tab group of the widget. Does not fire an event, i.e. does
  336. * not invoke OnRenderEnable().
  337. * @param aId is the same unique id used when adding a ROW to the
  338. * Render tab.
  339. * @param isSet = the new checkbox state
  340. */
  341. void SetRenderState( int aId, bool isSet );
  342. /**
  343. * Function GetRenderState
  344. * returns the state of the checkbox associated with \a aId.
  345. * @return bool - true if checked, else false.
  346. */
  347. bool GetRenderState( int aId );
  348. void UpdateLayouts();
  349. /**
  350. * Function UpdateLayerIcons
  351. * Update all layer manager icons (layers only)
  352. * Useful when loading a file or clearing a layer because they change,
  353. * and the indicator arrow icon needs to be updated
  354. */
  355. void UpdateLayerIcons();
  356. /* did not help:
  357. void Freeze()
  358. {
  359. LAYER_PANEL_BASE::Freeze();
  360. m_LayerScrolledWindow->Freeze();
  361. m_RenderScrolledWindow->Freeze();
  362. }
  363. void Thaw()
  364. {
  365. m_RenderScrolledWindow->Thaw();
  366. m_LayerScrolledWindow->Thaw();
  367. LAYER_PANEL_BASE::Thaw();
  368. }
  369. */
  370. //-----<abstract functions>-------------------------------------------
  371. /**
  372. * Function OnLayerColorChange
  373. * is called to notify client code about a layer color change. Derived
  374. *es will handle this accordingly.
  375. * @param aLayer is the board layer to change
  376. * @param aColor is the new color
  377. */
  378. virtual void OnLayerColorChange( int aLayer, COLOR4D aColor ) = 0;
  379. /**
  380. * Function OnLayerSelect
  381. * is called to notify client code whenever the user selects a different
  382. * layer. Derived classes will handle this accordingly, and can deny
  383. * the change by returning false.
  384. * @param aLayer is the board layer to select
  385. */
  386. virtual bool OnLayerSelect( int aLayer ) = 0;
  387. /**
  388. * Function OnLayerVisible
  389. * is called to notify client code about a layer visibility change.
  390. *
  391. * @param aLayer is the board layer to select
  392. * @param isVisible is the new visible state
  393. * @param isFinal is true when this is the last of potentially several
  394. * such calls, and can be used to decide when to update the screen only
  395. * one time instead of several times in the midst of a multiple layer change.
  396. */
  397. virtual void OnLayerVisible( LAYER_NUM aLayer, bool isVisible, bool isFinal = true ) = 0;
  398. /**
  399. * Function OnLayerRightClick
  400. * is called to notify client code about a layer being right-clicked.
  401. *
  402. * @param aMenu is the right-click menu containing layer-scoped options.
  403. * It can be used to add extra, wider scoped menu items.
  404. */
  405. virtual void OnLayerRightClick( wxMenu& aMenu ) = 0;
  406. /**
  407. * Function OnRenderColorChange
  408. * is called to notify client code whenever the user changes a rendering
  409. * color.
  410. * @param aId is the same id that was established in a Rendering row
  411. * via the AddRenderRow() function.
  412. * @param aColor is the new color
  413. */
  414. virtual void OnRenderColorChange( int aId, COLOR4D aColor ) = 0;
  415. /**
  416. * Function OnRenderEnable
  417. * is called to notify client code whenever the user changes an rendering
  418. * enable in one of the rendering checkboxes.
  419. * @param aId is the same id that was established in a Rendering row
  420. * via the AddRenderRow() function.
  421. * @param isEnabled is the state of the checkbox, true if checked.
  422. */
  423. virtual void OnRenderEnable( int aId, bool isEnabled ) = 0;
  424. //-----</abstract functions>------------------------------------------
  425. };
  426. #endif // LAYERWIDGET_H_