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.

364 lines
9.5 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/dc.h>
  24. #include <wx/imaglist.h>
  25. #include <wx/wupdlock.h>
  26. #include <eda_item.h>
  27. #include <drawing_sheet/ds_draw_item.h>
  28. #include <drawing_sheet/ds_data_item.h>
  29. #include <drawing_sheet/ds_data_model.h>
  30. #include <tool/tool_manager.h>
  31. #include "dialogs/dialog_design_inspector_base.h"
  32. #include "design_inspector.h"
  33. #include "pl_editor_frame.h"
  34. #include "properties_frame.h"
  35. #include "tools/pl_actions.h"
  36. #include "tools/pl_selection_tool.h"
  37. /* XPM
  38. * This bitmap is used to show item types
  39. */
  40. static const char* root_xpm[] =
  41. {
  42. "12 12 2 1",
  43. " c None",
  44. "x c #008080",
  45. " xxxx ",
  46. " xxx ",
  47. " xxx ",
  48. " xxx ",
  49. "xxxxxxxxxxx ",
  50. "xxxxxxxxxxxx",
  51. "xxxxxxxxxxx ",
  52. " xxx ",
  53. " xxx ",
  54. " xxx ",
  55. " xxxx ",
  56. " "
  57. };
  58. static const char* line_xpm[] =
  59. {
  60. "12 12 2 1",
  61. " c None",
  62. "x c #008080",
  63. "xx ",
  64. "xx ",
  65. "xx ",
  66. "xx ",
  67. "xx ",
  68. "xx ",
  69. "xx ",
  70. "xx ",
  71. "xx ",
  72. "xx ",
  73. "xxxxxxxxxxxx",
  74. "xxxxxxxxxxxx"
  75. };
  76. static const char* rect_xpm[] =
  77. {
  78. "12 12 2 1",
  79. " c None",
  80. "x c #000080",
  81. "xxxxxxxxxxxx",
  82. "xxxxxxxxxxxx",
  83. "xx xx",
  84. "xx xx",
  85. "xx xx",
  86. "xx xx",
  87. "xx xx",
  88. "xx xx",
  89. "xx xx",
  90. "xx xx",
  91. "xxxxxxxxxxxx",
  92. "xxxxxxxxxxxx"
  93. };
  94. static const char* text_xpm[] =
  95. {
  96. "12 12 2 1",
  97. " c None",
  98. "x c #800000",
  99. " xxxxxxxxxx ",
  100. "xxxxxxxxxxxx",
  101. "xx xx xx",
  102. " xx ",
  103. " xx ",
  104. " xx ",
  105. " xx ",
  106. " xx ",
  107. " xx ",
  108. " xx ",
  109. " xxxx ",
  110. " xxxxxx "
  111. };
  112. static const char* poly_xpm[] =
  113. {
  114. "12 12 2 1",
  115. " c None",
  116. "x c #008000",
  117. " xx ",
  118. " xxxx ",
  119. " xxxxxx ",
  120. " xxxxxxxx ",
  121. " xxxxxxxxxx ",
  122. "xxxxxxxxxxxx",
  123. "xxxxxxxxxxxx",
  124. " xxxxxxxxxx ",
  125. " xxxxxxxx ",
  126. " xxxxxx ",
  127. " xxxx ",
  128. " xx "
  129. };
  130. static const char* img_xpm[] =
  131. {
  132. "12 12 2 1",
  133. " c None",
  134. "x c #800000",
  135. " xx ",
  136. " xxxxxx ",
  137. " xx xx ",
  138. "xx xx",
  139. "xx xx",
  140. " xx xx ",
  141. " xxxxxx ",
  142. " xx ",
  143. " xx ",
  144. " xx ",
  145. " xx ",
  146. " xx "
  147. };
  148. // A helper class to draw these bitmaps into a wxGrid cell:
  149. class BitmapGridCellRenderer : public wxGridCellStringRenderer
  150. {
  151. const char** m_BitmapXPM;
  152. public:
  153. BitmapGridCellRenderer( const char** aBitmapXPM )
  154. {
  155. m_BitmapXPM = aBitmapXPM;
  156. }
  157. void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr,
  158. wxDC& aDc, const wxRect& aRect,
  159. int aRow, int aCol, bool aIsSelected) override;
  160. };
  161. // Column ids for m_gridListItems
  162. enum COL_INDEX
  163. {
  164. COL_BITMAP,
  165. COL_TYPENAME,
  166. COL_REPEAT_NUMBER,
  167. COL_COMMENT,
  168. COL_TEXTSTRING,
  169. COL_COUNT //Sentinel
  170. };
  171. DIALOG_INSPECTOR::DIALOG_INSPECTOR( PL_EDITOR_FRAME* aParent ) :
  172. DIALOG_INSPECTOR_BASE( aParent )
  173. {
  174. m_editorFrame = aParent;
  175. ReCreateDesignList();
  176. // Now all widgets have the size fixed, call FinishDialogSettings
  177. finishDialogSettings();
  178. }
  179. DIALOG_INSPECTOR::~DIALOG_INSPECTOR()
  180. {
  181. }
  182. void DIALOG_INSPECTOR::ReCreateDesignList()
  183. {
  184. wxWindowUpdateLocker dummy( this ); // Avoid flicker when rebuilding the tree
  185. const PAGE_INFO& page_info = m_editorFrame->GetPageLayout().GetPageSettings();
  186. if( m_gridListItems->GetNumberRows() > 1 )
  187. m_gridListItems->DeleteRows( 1, m_gridListItems->GetNumberRows() - 1 );
  188. m_itemsList.clear();
  189. DS_DATA_MODEL& drawingSheet = DS_DATA_MODEL::GetTheInstance();
  190. wxFileName fn( static_cast<PL_EDITOR_FRAME*>( GetParent() )->GetCurrentFileName() );
  191. if( fn.GetName().IsEmpty() )
  192. SetTitle( "<default drawing sheet>" );
  193. else
  194. SetTitle( fn.GetName() );
  195. // The first item is the layout: Display info about the page: fmt, size...
  196. int row = 0;
  197. GetGridList()->SetCellValue( row, COL_TYPENAME, _( "Layout" ) );
  198. GetGridList()->SetCellValue( row, COL_COMMENT, page_info.GetType() ); // Display page format name
  199. GetGridList()->SetCellValue( row, COL_REPEAT_NUMBER, "-" );
  200. wxSize page_sizeIU = m_editorFrame->GetPageSizeIU();
  201. GetGridList()->SetCellValue( row, COL_TEXTSTRING, wxString::Format( _( "Size: %.1fx%.1fmm" ),
  202. Iu2Millimeter( page_sizeIU.x ), Iu2Millimeter( page_sizeIU.y ) ) );
  203. GetGridList()->SetCellRenderer (row, COL_BITMAP, new BitmapGridCellRenderer( root_xpm ) );
  204. GetGridList()->SetReadOnly( row, COL_BITMAP );
  205. m_itemsList.push_back( nullptr ); // this item is not a DS_DATA_ITEM, just a pseudo item
  206. // Now adding all current items
  207. row++;
  208. for( DS_DATA_ITEM* item : drawingSheet.GetItems() )
  209. {
  210. const char** img = nullptr;
  211. switch( item->GetType() )
  212. {
  213. case DS_DATA_ITEM::DS_SEGMENT:
  214. img = line_xpm;
  215. break;
  216. case DS_DATA_ITEM::DS_RECT:
  217. img = rect_xpm;
  218. break;
  219. case DS_DATA_ITEM::DS_TEXT:
  220. img = text_xpm;
  221. break;
  222. case DS_DATA_ITEM::DS_POLYPOLYGON:
  223. img = poly_xpm;
  224. break;
  225. case DS_DATA_ITEM::DS_BITMAP:
  226. img = img_xpm;
  227. break;
  228. }
  229. GetGridList()->AppendRows( 1 );
  230. GetGridList()->SetCellRenderer (row, COL_BITMAP, new BitmapGridCellRenderer( img ) );
  231. GetGridList()->SetReadOnly( row, COL_BITMAP );
  232. GetGridList()->SetCellValue( row, COL_TYPENAME,item->GetClassName() );
  233. GetGridList()->SetCellValue( row, COL_REPEAT_NUMBER,
  234. wxString::Format( "%d", item->m_RepeatCount ) );
  235. GetGridList()->SetCellValue( row, COL_COMMENT, item->m_Info );
  236. if( item->GetType() == DS_DATA_ITEM::DS_TEXT )
  237. {
  238. DS_DATA_ITEM_TEXT* t_item = static_cast<DS_DATA_ITEM_TEXT*>( item );
  239. GetGridList()->SetCellValue( row, COL_TEXTSTRING, t_item->m_TextBase );
  240. }
  241. m_itemsList.push_back( item );
  242. row++;
  243. }
  244. // Now resize the columns:
  245. int cols_to_resize[] =
  246. {
  247. COL_BITMAP, COL_TYPENAME, COL_REPEAT_NUMBER, COL_COMMENT, COL_TEXTSTRING, COL_COUNT
  248. };
  249. for( int ii = 0; ; ii++ )
  250. {
  251. int col = cols_to_resize[ii];
  252. if( col == COL_COUNT )
  253. break;
  254. if( col == COL_BITMAP )
  255. {
  256. #define BITMAP_SIZE 16
  257. GetGridList()->SetColMinimalWidth( col, BITMAP_SIZE*2 );
  258. GetGridList()->AutoSizeColumn( col, false );
  259. }
  260. else
  261. GetGridList()->AutoSizeColumn( col );
  262. GetGridList()->AutoSizeColLabelSize( col );
  263. }
  264. }
  265. // Select the row corresponding to the DS_DATA_ITEM aItem
  266. void DIALOG_INSPECTOR::SelectRow( DS_DATA_ITEM* aItem )
  267. {
  268. // m_itemsList[0] is not a true DS_DATA_ITEM
  269. for( unsigned row = 1; row < m_itemsList.size(); ++row )
  270. {
  271. if( m_itemsList[row] == aItem )
  272. {
  273. GetGridList()->GoToCell( row, COL_TYPENAME );
  274. GetGridList()->SelectRow( row );
  275. break;
  276. }
  277. }
  278. }
  279. //return the drawing sheet item managed by the cell
  280. DS_DATA_ITEM* DIALOG_INSPECTOR::GetDrawingSheetDataItem( int aRow ) const
  281. {
  282. return ( aRow >= 0 && aRow < (int)m_itemsList.size() ) ? m_itemsList[aRow]: nullptr;
  283. }
  284. void DIALOG_INSPECTOR::onCellClicked( wxGridEvent& event )
  285. {
  286. int row = event.GetRow();
  287. GetGridList()->SelectRow( row );
  288. DS_DATA_ITEM* item = GetDrawingSheetDataItem( row );
  289. if( !item ) // only DS_DATA_ITEM are returned.
  290. return;
  291. // Select this item in drawing sheet editor, and update the properties panel:
  292. PL_SELECTION_TOOL* selectionTool = m_editorFrame->GetToolManager()->GetTool<PL_SELECTION_TOOL>();
  293. selectionTool->ClearSelection();
  294. EDA_ITEM* draw_item = item->GetDrawItems()[0];
  295. selectionTool->AddItemToSel( draw_item );
  296. m_editorFrame->GetCanvas()->Refresh();
  297. m_editorFrame->GetPropertiesFrame()->CopyPrmsFromItemToPanel( item );
  298. }
  299. void BitmapGridCellRenderer::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr,
  300. wxDC& aDc, const wxRect& aRect,
  301. int aRow, int aCol, bool aIsSelected)
  302. {
  303. wxGridCellStringRenderer::Draw( aGrid, aAttr, aDc, aRect, aRow, aCol, aIsSelected);
  304. wxBitmap bm( m_BitmapXPM );
  305. aDc.DrawBitmap( bm,aRect.GetX()+5, aRect.GetY()+2, true);
  306. }
  307. void PL_EDITOR_FRAME::ShowDesignInspector()
  308. {
  309. DIALOG_INSPECTOR dlg( this );
  310. dlg.ShowModal();
  311. }