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.

434 lines
14 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 <colors.h>
  44. #define LYR_COLUMN_COUNT 4 ///< Layer tab column count
  45. #define RND_COLUMN_COUNT 2 ///< Rendering tab column count
  46. #define COLUMN_ICON_ACTIVE 0
  47. #define COLUMN_COLORBM 1
  48. #define COLUMN_COLOR_LYR_CB 2
  49. #define COLUMN_COLOR_LYRNAME 3
  50. /**
  51. * Class LAYER_WIDGET
  52. * is abstract and is used to manage a list of layers, with the notion of
  53. * a "current" layer, and layer specific visibility control. You must derive from
  54. * it to use it so you can implement the abstract functions which recieve the
  55. * events. Each layer is given its own color, and that color can be changed
  56. * within the UI provided here. This widget knows nothing of the client code, meaning
  57. * it has no knowledge of a BOARD or anything. To use it you must derive from
  58. * this class and implement the abstract functions:
  59. * <p> void OnLayerColorChange( int aLayer, int aColor );
  60. * <p> bool OnLayerSelect( int aLayer );
  61. * <p> void OnLayerVisible( int aLayer, bool isVisible );
  62. * <p> void OnRenderColorChange( int id, int aColor );
  63. * <p> void OnRenderEnable( int id, bool isEnabled );
  64. *
  65. * Please note that even if designed toward layers, it is used to
  66. * contain other stuff, too (the second page in pcbnew contains render
  67. * items, for example)
  68. */
  69. class LAYER_WIDGET : public wxPanel
  70. {
  71. public:
  72. /**
  73. * Struct ROW
  74. * provides all the data needed to add a row to a LAYER_WIDGET. This is
  75. * part of the public API for a LAYER_WIDGET.
  76. */
  77. struct ROW
  78. {
  79. wxString rowName; ///< the prompt or layername
  80. int id; ///< either a layer or "visible element" id
  81. EDA_COLOR_T color; ///< -1 if none.
  82. bool state; ///< initial wxCheckBox state
  83. wxString tooltip; ///< if not empty, use this tooltip on row
  84. ROW( const wxString& aRowName, int aId, EDA_COLOR_T aColor = UNSPECIFIED_COLOR,
  85. const wxString& aTooltip = wxEmptyString, bool aState = true )
  86. {
  87. rowName = aRowName;
  88. id = aId;
  89. color = aColor;
  90. state = aState;
  91. tooltip = aTooltip;
  92. }
  93. };
  94. static const wxEventType EVT_LAYER_COLOR_CHANGE;
  95. protected:
  96. wxAuiNotebook* m_notebook;
  97. wxPanel* m_LayerPanel;
  98. wxScrolledWindow* m_LayerScrolledWindow;
  99. wxFlexGridSizer* m_LayersFlexGridSizer;
  100. wxPanel* m_RenderingPanel;
  101. wxScrolledWindow* m_RenderScrolledWindow;
  102. wxFlexGridSizer* m_RenderFlexGridSizer;
  103. wxWindow* m_FocusOwner;
  104. wxBitmap* m_BlankBitmap;
  105. wxBitmap* m_BlankAlternateBitmap;
  106. wxBitmap* m_RightArrowBitmap;
  107. wxBitmap* m_RightArrowAlternateBitmap;
  108. wxSize m_BitmapSize;
  109. int m_CurrentRow; ///< selected row of layer list
  110. int m_PointSize;
  111. static wxBitmap makeBitmap( EDA_COLOR_T aColor );
  112. /**
  113. * Virtual Function useAlternateBitmap
  114. * @return true if bitmaps shown in Render layer list
  115. * are alternate bitmaps, or false if they are "normal" bitmaps
  116. * This is a virtual function because Pcbnew uses normal bitmaps
  117. * but GerbView uses both bitmaps
  118. * (alternate bitmaps to show layers in use, normal fo others)
  119. */
  120. virtual bool useAlternateBitmap(int aRow) { return false; }
  121. /**
  122. * Function encodeId
  123. * is here to allow saving a layer index within a control as its wxControl id,
  124. * but to do so in a way that all child wxControl ids within a wxWindow are unique,
  125. * since this is required by Windows.
  126. * @see getDecodedId()
  127. */
  128. static int encodeId( int aColumn, int aId );
  129. /**
  130. * Function getDecodedId
  131. * decodes \a aControlId to original un-encoded value. This of
  132. * course holds iff encodedId was called with a LAYER_NUM (this box
  133. * is used for other things than layers, too)
  134. */
  135. static LAYER_NUM getDecodedId( int aControlId );
  136. /**
  137. * Function makeColorButton
  138. * creates a wxBitmapButton and assigns it a solid color and a control ID
  139. */
  140. wxBitmapButton* makeColorButton( wxWindow* aParent, EDA_COLOR_T aColor, int aID );
  141. void OnLeftDownLayers( wxMouseEvent& event );
  142. /**
  143. * Function OnMiddleDownLayerColor
  144. * is called only from a color button when user right clicks.
  145. */
  146. void OnMiddleDownLayerColor( wxMouseEvent& event );
  147. /**
  148. * Function OnLayerCheckBox
  149. * handles the "is layer visible" checkbox and propogates the
  150. * event to the client's notification function.
  151. */
  152. void OnLayerCheckBox( wxCommandEvent& event );
  153. void OnMiddleDownRenderColor( wxMouseEvent& event );
  154. void OnRenderCheckBox( wxCommandEvent& event );
  155. void OnTabChange( wxNotebookEvent& event );
  156. /**
  157. * Function getLayerComp
  158. * returns the component within the m_LayersFlexGridSizer at @a aRow and @a aCol
  159. * or NULL if these parameters are out of range.
  160. *
  161. * @param aRow is the row index
  162. * @param aColumn is the column
  163. * @return wxWindow - the component installed within the sizer at given grid coordinate.
  164. */
  165. wxWindow* getLayerComp( int aRow, int aColumn ) const;
  166. wxWindow* getRenderComp( int aRow, int aColumn ) const;
  167. /**
  168. * Function findLayerRow
  169. * returns the row index that \a aLayer resides in, or -1 if not found.
  170. */
  171. int findLayerRow( LAYER_NUM aLayer ) const;
  172. int findRenderRow( int aId ) const;
  173. /**
  174. * Function insertLayerRow
  175. * appends or inserts a new row in the layer portion of the widget.
  176. */
  177. void insertLayerRow( int aRow, const ROW& aSpec );
  178. void insertRenderRow( int aRow, const ROW& aSpec );
  179. /**
  180. * Function passOnFocus
  181. * gives away the keyboard focus up to the main parent window.
  182. */
  183. void passOnFocus();
  184. public:
  185. /** Constructor
  186. * @param aParent is the parent window
  187. * @param aFocusOwner is the window that should be sent the focus after
  188. * @param aPointSize is the font point size to use within the widget. This
  189. * effectively sets the overal size of the widget via the row height and bitmap
  190. * button sizes.
  191. * @param id is the wxWindow id ( default = wxID_ANY)
  192. * @param pos is the window position
  193. * @param size is the window size
  194. * @param style is the window style
  195. * every operation.
  196. */
  197. LAYER_WIDGET( wxWindow* aParent, wxWindow* aFocusOwner, int aPointSize = -1,
  198. wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
  199. const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL );
  200. virtual ~LAYER_WIDGET();
  201. /**
  202. * Function GetBestSize
  203. * returns the preferred minimum size, taking into consideration the
  204. * dynamic content. Nothing in wxWidgets was reliable enough so this
  205. * overrides one of their functions.
  206. */
  207. wxSize GetBestSize() const;
  208. /**
  209. * Function GetLayerRowCount
  210. * returns the number of rows in the layer tab.
  211. */
  212. int GetLayerRowCount() const;
  213. /**
  214. * Function GetRenderRowCount
  215. * returns the number of rows in the render tab.
  216. */
  217. int GetRenderRowCount() const;
  218. /**
  219. * Function AppendLayerRow
  220. * appends a new row in the layer portion of the widget. The user must
  221. * ensure that ROW::id is unique for all existing rows on Windows.
  222. */
  223. void AppendLayerRow( const ROW& aRow );
  224. /**
  225. * Function AppendLayerRows
  226. * appends new rows in the layer portion of the widget. The user must
  227. * ensure that ROW::id is unique for all existing rows on Windows.
  228. */
  229. void AppendLayerRows( const ROW* aRowsArray, int aRowCount )
  230. {
  231. for( int row=0; row<aRowCount; ++row )
  232. AppendLayerRow( aRowsArray[row] );
  233. }
  234. /**
  235. * Function ClearLayerRows
  236. * empties out the layer rows.
  237. */
  238. void ClearLayerRows();
  239. /**
  240. * Function AppendRenderRow
  241. * appends a new row in the render portion of the widget. The user must
  242. * ensure that ROW::id is unique for all existing rows on Windows.
  243. */
  244. void AppendRenderRow( const ROW& aRow );
  245. /**
  246. * Function AppendRenderRows
  247. * appends new rows in the render portion of the widget. The user must
  248. * ensure that ROW::id is unique for all existing rows on Windows.
  249. */
  250. void AppendRenderRows( const ROW* aRowsArray, int aRowCount )
  251. {
  252. for( int row=0; row<aRowCount; ++row )
  253. AppendRenderRow( aRowsArray[row] );
  254. }
  255. /**
  256. * Function ClearRenderRows
  257. * empties out the render rows.
  258. */
  259. void ClearRenderRows();
  260. /**
  261. * Function SelectLayerRow
  262. * changes the row selection in the layer list to the given row.
  263. */
  264. void SelectLayerRow( int aRow );
  265. /**
  266. * Function SelectLayer
  267. * changes the row selection in the layer list to \a aLayer provided.
  268. */
  269. void SelectLayer( LAYER_NUM aLayer );
  270. /**
  271. * Function GetSelectedLayer
  272. * returns the selected layer or -1 if none.
  273. */
  274. LAYER_NUM GetSelectedLayer();
  275. /**
  276. * Function SetLayerVisible
  277. * sets \a aLayer visible or not. This does not invoke OnLayerVisible().
  278. */
  279. void SetLayerVisible( LAYER_NUM aLayer, bool isVisible );
  280. /**
  281. * Function IsLayerVisible
  282. * returns the visible state of the layer ROW associated with \a aLayer id.
  283. */
  284. bool IsLayerVisible( LAYER_NUM aLayer );
  285. /**
  286. * Function SetLayerColor
  287. * changes the color of \a aLayer
  288. */
  289. void SetLayerColor( LAYER_NUM aLayer, EDA_COLOR_T aColor );
  290. /**
  291. * Function GetLayerColor
  292. * returns the color of the layer ROW associated with \a aLayer id.
  293. */
  294. EDA_COLOR_T GetLayerColor( LAYER_NUM aLayer ) const;
  295. /**
  296. * Function SetRenderState
  297. * sets the state of the checkbox associated with \a aId within the
  298. * Render tab group of the widget. Does not fire an event, i.e. does
  299. * not invoke OnRenderEnable().
  300. * @param aId is the same unique id used when adding a ROW to the
  301. * Render tab.
  302. * @param isSet = the new checkbox state
  303. */
  304. void SetRenderState( int aId, bool isSet );
  305. /**
  306. * Function GetRenderState
  307. * returns the state of the checkbox associated with \a aId.
  308. * @return bool - true if checked, else false.
  309. */
  310. bool GetRenderState( int aId );
  311. void UpdateLayouts();
  312. /* did not help:
  313. void Freeze()
  314. {
  315. LAYER_PANEL_BASE::Freeze();
  316. m_LayerScrolledWindow->Freeze();
  317. m_RenderScrolledWindow->Freeze();
  318. }
  319. void Thaw()
  320. {
  321. m_RenderScrolledWindow->Thaw();
  322. m_LayerScrolledWindow->Thaw();
  323. LAYER_PANEL_BASE::Thaw();
  324. }
  325. */
  326. //-----<abstract functions>-------------------------------------------
  327. /**
  328. * Function OnLayerColorChange
  329. * is called to notify client code about a layer color change. Derived
  330. * classes will handle this accordingly.
  331. * @param aLayer is the board layer to change
  332. * @param aColor is the new color
  333. */
  334. virtual void OnLayerColorChange( int aLayer, EDA_COLOR_T aColor ) = 0;
  335. /**
  336. * Function OnLayerSelect
  337. * is called to notify client code whenever the user selects a different
  338. * layer. Derived classes will handle this accordingly, and can deny
  339. * the change by returning false.
  340. * @param aLayer is the board layer to select
  341. */
  342. virtual bool OnLayerSelect( int aLayer ) = 0;
  343. /**
  344. * Function OnLayerVisible
  345. * is called to notify client code about a layer visibility change.
  346. *
  347. * @param aLayer is the board layer to select
  348. * @param isVisible is the new visible state
  349. * @param isFinal is true when this is the last of potentially several
  350. * such calls, and can be used to decide when to update the screen only
  351. * one time instead of several times in the midst of a multiple layer change.
  352. */
  353. virtual void OnLayerVisible( LAYER_NUM aLayer, bool isVisible, bool isFinal = true ) = 0;
  354. /**
  355. * Function OnRenderColorChange
  356. * is called to notify client code whenever the user changes a rendering
  357. * color.
  358. * @param aId is the same id that was established in a Rendering row
  359. * via the AddRenderRow() function.
  360. * @param aColor is the new color
  361. */
  362. virtual void OnRenderColorChange( int aId, EDA_COLOR_T aColor ) = 0;
  363. /**
  364. * Function OnRenderEnable
  365. * is called to notify client code whenever the user changes an rendering
  366. * enable in one of the rendering checkboxes.
  367. * @param aId is the same id that was established in a Rendering row
  368. * via the AddRenderRow() function.
  369. * @param isEnabled is the state of the checkbox, true if checked.
  370. */
  371. virtual void OnRenderEnable( int aId, bool isEnabled ) = 0;
  372. //-----</abstract functions>------------------------------------------
  373. };
  374. #endif // LAYERWIDGET_H_