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.

369 lines
9.6 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2019 jp.charras at wanadoo.fr
  5. * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * @file design_inspector.cpp
  22. */
  23. #include <wx/imaglist.h>
  24. #include <wx/wupdlock.h>
  25. #include <fctsys.h>
  26. #include <ws_draw_item.h>
  27. #include <ws_data_model.h>
  28. #include <pl_editor_id.h>
  29. #include <design_inspector.h>
  30. #include <tool/tool_manager.h>
  31. #include <tools/pl_actions.h>
  32. #include <tools/pl_selection_tool.h>
  33. #include <properties_frame.h>
  34. /* XPM
  35. * This bitmap is used to show item types
  36. */
  37. static const char* root_xpm[] =
  38. {
  39. "12 12 2 1",
  40. " c None",
  41. "x c #008080",
  42. " xxxx ",
  43. " xxx ",
  44. " xxx ",
  45. " xxx ",
  46. "xxxxxxxxxxx ",
  47. "xxxxxxxxxxxx",
  48. "xxxxxxxxxxx ",
  49. " xxx ",
  50. " xxx ",
  51. " xxx ",
  52. " xxxx ",
  53. " "
  54. };
  55. static const char* line_xpm[] =
  56. {
  57. "12 12 2 1",
  58. " c None",
  59. "x c #008080",
  60. "xx ",
  61. "xx ",
  62. "xx ",
  63. "xx ",
  64. "xx ",
  65. "xx ",
  66. "xx ",
  67. "xx ",
  68. "xx ",
  69. "xx ",
  70. "xxxxxxxxxxxx",
  71. "xxxxxxxxxxxx"
  72. };
  73. static const char* rect_xpm[] =
  74. {
  75. "12 12 2 1",
  76. " c None",
  77. "x c #000080",
  78. "xxxxxxxxxxxx",
  79. "xxxxxxxxxxxx",
  80. "xx xx",
  81. "xx xx",
  82. "xx xx",
  83. "xx xx",
  84. "xx xx",
  85. "xx xx",
  86. "xx xx",
  87. "xx xx",
  88. "xxxxxxxxxxxx",
  89. "xxxxxxxxxxxx"
  90. };
  91. static const char* text_xpm[] =
  92. {
  93. "12 12 2 1",
  94. " c None",
  95. "x c #800000",
  96. " xxxxxxxxxx ",
  97. "xxxxxxxxxxxx",
  98. "xx xx xx",
  99. " xx ",
  100. " xx ",
  101. " xx ",
  102. " xx ",
  103. " xx ",
  104. " xx ",
  105. " xx ",
  106. " xxxx ",
  107. " xxxxxx "
  108. };
  109. static const char* poly_xpm[] =
  110. {
  111. "12 12 2 1",
  112. " c None",
  113. "x c #008000",
  114. " xx ",
  115. " xxxx ",
  116. " xxxxxx ",
  117. " xxxxxxxx ",
  118. " xxxxxxxxxx ",
  119. "xxxxxxxxxxxx",
  120. "xxxxxxxxxxxx",
  121. " xxxxxxxxxx ",
  122. " xxxxxxxx ",
  123. " xxxxxx ",
  124. " xxxx ",
  125. " xx "
  126. };
  127. static const char* img_xpm[] =
  128. {
  129. "12 12 2 1",
  130. " c None",
  131. "x c #800000",
  132. " xx ",
  133. " xxxxxx ",
  134. " xx xx ",
  135. "xx xx",
  136. "xx xx",
  137. " xx xx ",
  138. " xxxxxx ",
  139. " xx ",
  140. " xx ",
  141. " xx ",
  142. " xx ",
  143. " xx "
  144. };
  145. // A helper class to draw these bitmaps into a wxGrid cell:
  146. class BitmapGridCellRenderer : public wxGridCellStringRenderer
  147. {
  148. const char** m_BitmapXPM;
  149. public:
  150. BitmapGridCellRenderer( const char** aBitmapXPM )
  151. {
  152. m_BitmapXPM = aBitmapXPM;
  153. }
  154. void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr,
  155. wxDC& aDc, const wxRect& aRect,
  156. int aRow, int aCol, bool aIsSelected) override;
  157. };
  158. // Column ids for m_gridListItems
  159. enum COL_INDEX
  160. {
  161. COL_BITMAP,
  162. COL_TYPENAME,
  163. COL_REPEAT_NUMBER,
  164. COL_COMMENT,
  165. COL_TEXTSTRING,
  166. COL_COUNT //Sentinel
  167. };
  168. DIALOG_INSPECTOR::DIALOG_INSPECTOR( PL_EDITOR_FRAME* aParent ) :
  169. DIALOG_INSPECTOR_BASE( aParent )
  170. {
  171. m_editorFrame = aParent;
  172. ReCreateDesignList();
  173. // Now all widgets have the size fixed, call FinishDialogSettings
  174. FinishDialogSettings();
  175. }
  176. DIALOG_INSPECTOR::~DIALOG_INSPECTOR()
  177. {
  178. }
  179. void DIALOG_INSPECTOR::ReCreateDesignList()
  180. {
  181. wxWindowUpdateLocker dummy( this ); // Avoid flicker when rebuilding the tree
  182. const PAGE_INFO& page_info = m_editorFrame->GetPageLayout().GetPageSettings();
  183. if( m_gridListItems->GetNumberRows() > 1 )
  184. m_gridListItems->DeleteRows( 1, m_gridListItems->GetNumberRows() - 1 );
  185. m_itemsList.clear();
  186. WS_DATA_MODEL& pglayout = WS_DATA_MODEL::GetTheInstance();
  187. wxFileName fn( ((PL_EDITOR_FRAME*) GetParent())->GetCurrentFileName() );
  188. if( fn.GetName().IsEmpty() )
  189. SetTitle( "<default page layout>" );
  190. else
  191. SetTitle( fn.GetName() );
  192. // The first item is the layout: Display info about the page: fmt, size...
  193. int row = 0;
  194. GetGridList()->SetCellValue( row, COL_TYPENAME, _( "Layout" ) );
  195. GetGridList()->SetCellValue( row, COL_COMMENT, page_info.GetType() ); // Display page format name
  196. GetGridList()->SetCellValue( row, COL_REPEAT_NUMBER, "-" );
  197. wxSize page_sizeIU = m_editorFrame->GetPageSizeIU();
  198. GetGridList()->SetCellValue( row, COL_TEXTSTRING, wxString::Format( _( "Size: %.1fx%.1fmm" ),
  199. Iu2Millimeter( page_sizeIU.x ), Iu2Millimeter( page_sizeIU.y ) ) );
  200. GetGridList()->SetCellRenderer (row, COL_BITMAP, new BitmapGridCellRenderer( root_xpm ) );
  201. GetGridList()->SetReadOnly( row, COL_BITMAP );
  202. m_itemsList.push_back( nullptr ); // this item is not a WS_DATA_ITEM, just a pseudo item
  203. // Now adding all current items
  204. row++;
  205. for( WS_DATA_ITEM* item : pglayout.GetItems() )
  206. {
  207. const char** img = nullptr;
  208. switch( item->GetType() )
  209. {
  210. case WS_DATA_ITEM::WS_SEGMENT:
  211. img = line_xpm;
  212. break;
  213. case WS_DATA_ITEM::WS_RECT:
  214. img = rect_xpm;
  215. break;
  216. case WS_DATA_ITEM::WS_TEXT:
  217. img = text_xpm;
  218. break;
  219. case WS_DATA_ITEM::WS_POLYPOLYGON:
  220. img = poly_xpm;
  221. break;
  222. case WS_DATA_ITEM::WS_BITMAP:
  223. img = img_xpm;
  224. break;
  225. }
  226. GetGridList()->AppendRows( 1 );
  227. GetGridList()->SetCellRenderer (row, COL_BITMAP, new BitmapGridCellRenderer( img ) );
  228. GetGridList()->SetReadOnly( row, COL_BITMAP );
  229. GetGridList()->SetCellValue( row, COL_TYPENAME,item->GetClassName() );
  230. GetGridList()->SetCellValue( row, COL_REPEAT_NUMBER,
  231. wxString::Format( "%d", item->m_RepeatCount ) );
  232. GetGridList()->SetCellValue( row, COL_COMMENT, item->m_Info );
  233. if( item->GetType() == WS_DATA_ITEM::WS_TEXT )
  234. {
  235. WS_DATA_ITEM_TEXT* t_item = static_cast<WS_DATA_ITEM_TEXT*>( item );
  236. GetGridList()->SetCellValue( row, COL_TEXTSTRING, t_item->m_TextBase );
  237. }
  238. m_itemsList.push_back( item );
  239. row++;
  240. }
  241. // Now resize the columns:
  242. int cols_to_resize[] =
  243. {
  244. COL_BITMAP, COL_TYPENAME, COL_REPEAT_NUMBER, COL_COMMENT, COL_TEXTSTRING, COL_COUNT
  245. };
  246. for( int ii = 0; ; ii++ )
  247. {
  248. int col = cols_to_resize[ii];
  249. if( col == COL_COUNT )
  250. break;
  251. if( col == COL_BITMAP )
  252. {
  253. #define BITMAP_SIZE 16
  254. GetGridList()->SetColMinimalWidth( col, BITMAP_SIZE*2 );
  255. GetGridList()->AutoSizeColumn( col, false );
  256. }
  257. else
  258. GetGridList()->AutoSizeColumn( col );
  259. GetGridList()->AutoSizeColLabelSize( col );
  260. }
  261. }
  262. // Select the row corresponding to the WS_DATA_ITEM aItem
  263. void DIALOG_INSPECTOR::SelectRow( WS_DATA_ITEM* aItem )
  264. {
  265. // m_itemsList[0] is not a true WS_DATA_ITEM
  266. for( unsigned row = 1; row < m_itemsList.size(); ++row )
  267. {
  268. if( m_itemsList[row] == aItem )
  269. {
  270. GetGridList()->GoToCell( row, COL_TYPENAME );
  271. GetGridList()->SelectRow( row );
  272. break;
  273. }
  274. }
  275. }
  276. //return the page layout item managed by the cell
  277. WS_DATA_ITEM* DIALOG_INSPECTOR::GetWsDataItem( int aRow ) const
  278. {
  279. return ( aRow >= 0 && aRow < (int)m_itemsList.size() ) ? m_itemsList[aRow]: nullptr;
  280. }
  281. /* return the page layout item managed by the selected cell (or NULL)
  282. */
  283. WS_DATA_ITEM* DIALOG_INSPECTOR::GetSelectedWsDataItem() const
  284. {
  285. int idx = GetGridList()->GetGridCursorRow();
  286. return GetWsDataItem( idx );
  287. }
  288. void DIALOG_INSPECTOR::onCellClicked( wxGridEvent& event )
  289. {
  290. int row = event.GetRow();
  291. GetGridList()->SelectRow( row );
  292. WS_DATA_ITEM* item = GetWsDataItem( row );
  293. if( !item ) // only WS_DATA_ITEM are returned.
  294. return;
  295. // Select this item in page layout editor, and update the properties panel:
  296. PL_SELECTION_TOOL* selectionTool = m_editorFrame->GetToolManager()->GetTool<PL_SELECTION_TOOL>();
  297. selectionTool->ClearSelection();
  298. EDA_ITEM* draw_item = item->GetDrawItems()[0];
  299. selectionTool->AddItemToSel( draw_item );
  300. m_editorFrame->GetCanvas()->Refresh();
  301. m_editorFrame->GetPropertiesFrame()->CopyPrmsFromItemToPanel( item );
  302. }
  303. void BitmapGridCellRenderer::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr,
  304. wxDC& aDc, const wxRect& aRect,
  305. int aRow, int aCol, bool aIsSelected)
  306. {
  307. wxGridCellStringRenderer::Draw( aGrid, aAttr, aDc, aRect, aRow, aCol, aIsSelected);
  308. wxBitmap bm( m_BitmapXPM );
  309. aDc.DrawBitmap( bm,aRect.GetX()+5, aRect.GetY()+2, true);
  310. }
  311. void PL_EDITOR_FRAME::ShowDesignInspector()
  312. {
  313. DIALOG_INSPECTOR dlg( this );
  314. dlg.ShowModal();
  315. }