KiCad PCB EDA Suite
cursors.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <vector>
25 
26 #include <cursors.h>
27 #include <kiplatform/ui.h>
28 #include <cursors/cursor-add.xpm>
29 #include <cursors/cursor-component.xpm>
30 #include <cursors/cursor-eraser.xpm>
31 #include <cursors/cursor-label-global.xpm>
32 #include <cursors/cursor-label-hier.xpm>
33 #include <cursors/cursor-label-net.xpm>
34 #include <cursors/cursor-line-bus.xpm>
35 #include <cursors/cursor-line-graphic.xpm>
36 #include <cursors/cursor-line-wire.xpm>
37 #include <cursors/cursor-line-wire-add.xpm>
38 #include <cursors/cursor-measure.xpm>
39 #include <cursors/cursor-pencil.xpm>
40 #include <cursors/cursor-select-lasso.xpm>
41 #include <cursors/cursor-select-window.xpm>
42 #include <cursors/cursor-subtract.xpm>
43 #include <cursors/cursor-text.xpm>
44 #include <cursors/cursor-xor.xpm>
45 #include <cursors/cursor-zoom.xpm>
46 #include <cursors/cursor-zoom-out.xpm>
47 
48 // Under MSW, the standard cursor is white on black. Elsewhere it is black on white
49 #ifdef __WINDOWS__
50 #include <cursors/cursor-place.xpm>
51 #include <cursors/cursor-select-m.xpm>
52 #else
53 #include <cursors/cursor-place-black.xpm>
54 #include <cursors/cursor-select-m-black.xpm>
55 #endif
56 
57 #include <wx/bitmap.h>
58 #include <wx/debug.h>
59 
60 
61 static const unsigned char voltage_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
64  0x00, 0x30, 0x06, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x80, 0x07, 0x08, 0x00,
65  0xc0, 0x07, 0x18, 0x00, 0xe0, 0x07, 0x30, 0x00, 0xf0, 0x03, 0x60, 0x00, 0xf8, 0x01, 0x00, 0x00,
66  0xfc, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
67  0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xf0,
68  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
69  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
70 
71 static const unsigned char current_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00,
74  0x00, 0x30, 0x0c, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x80, 0x0f, 0x18, 0x00,
75  0xc0, 0x0f, 0x30, 0x80, 0xe1, 0x07, 0x60, 0x80, 0xf1, 0x03, 0x00, 0x80, 0xf9, 0x01, 0x00, 0x80,
76  0xfd, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
77  0x0f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x00, 0x83,
78  0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xfc,
79  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00 };
80 
81 static const unsigned char cursor_tune[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00,
83  0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
84  0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
85  0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
86  0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
87  0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x50,
88  0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a,
89  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
90 
91 static const unsigned char cursor_tune_mask[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f,
93  0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07,
94  0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00,
95  0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
96  0x00, 0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00,
97  0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
98  0x70, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
99  0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
100 
101 
102 static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
103  {
107  nullptr,
108  { 32, 32 },
109  { 1, 31 },
110  },
111  {
115  nullptr,
116  { 32, 32 },
117  { 4, 27 },
118  },
119  {
121  cursor_tune,
123  nullptr,
124  { 32, 32 },
125  { 1, 30 },
126  },
127  {
129  nullptr,
130  nullptr,
131  cursor_pencil_xpm,
132  { 32, 32 },
133  { 4, 27 },
134  },
135  {
137  nullptr,
138  nullptr,
139 #ifdef __WINDOWS__
140  cursor_select_m_xpm,
141 #else
142  cursor_select_m_black_xpm,
143 #endif
144  { 32, 32 },
145  { 1, 1 },
146  },
147  {
149  nullptr,
150  nullptr,
151  cursor_eraser_xpm,
152  { 32, 32 },
153  { 4, 4 },
154  },
155  {
157  nullptr,
158  nullptr,
159  cursor_text_xpm,
160  { 32, 32 },
161  { 7, 7 },
162  },
163  {
165  nullptr,
166  nullptr,
167  cursor_measure_xpm,
168  { 32, 32 },
169  { 4, 4 },
170  },
171  {
173  nullptr,
174  nullptr,
175  cursor_add_xpm,
176  { 32, 32 },
177  { 7, 7 },
178  },
179  {
181  nullptr,
182  nullptr,
183  cursor_subtract_xpm,
184  { 32, 32 },
185  { 7, 7 },
186  },
187  {
189  nullptr,
190  nullptr,
191  cursor_xor_xpm,
192  { 32, 32 },
193  { 7, 7 },
194  },
195  {
197  nullptr,
198  nullptr,
199  cursor_zoom_xpm,
200  { 32, 32 },
201  { 6, 6 },
202  },
203  {
205  nullptr,
206  nullptr,
207  cursor_zoom_out_xpm,
208  { 32, 32 },
209  { 6, 6 },
210  },
211  {
213  nullptr,
214  nullptr,
215  cursor_label_net_xpm,
216  { 32, 32 },
217  { 7, 7 },
218  },
219  {
221  nullptr,
222  nullptr,
223  cursor_label_global_xpm,
224  { 32, 32 },
225  { 7, 7 },
226  },
227  {
229  nullptr,
230  nullptr,
231  cursor_component_xpm,
232  { 32, 32 },
233  { 7, 7 },
234  },
235  {
237  nullptr,
238  nullptr,
239  cursor_select_lasso_xpm,
240  { 32, 32 },
241  { 7, 7 },
242  },
243  {
245  nullptr,
246  nullptr,
247  cursor_select_window_xpm,
248  { 32, 32 },
249  { 7, 10 },
250  },
251  {
253  nullptr,
254  nullptr,
255  cursor_line_bus_xpm,
256  { 32, 32 },
257  { 5, 26 },
258  },
259  {
261  nullptr,
262  nullptr,
263  cursor_line_wire_xpm,
264  { 32, 32 },
265  { 5, 26 },
266  },
267  {
269  nullptr,
270  nullptr,
271  cursor_line_wire_add_xpm,
272  { 32, 32 },
273  { 5, 26 },
274  },
275  {
277  nullptr,
278  nullptr,
279  cursor_line_graphic_xpm,
280  { 32, 32 },
281  { 5, 26 },
282  },
283  {
285  nullptr,
286  nullptr,
287  cursor_label_hier_xpm,
288  { 32, 32 },
289  { 7, 7 },
290  },
291  {
293  nullptr,
294  nullptr,
295 #ifdef __WINDOWS__
296  cursor_place_xpm,
297 #else
298  cursor_place_black_xpm,
299 #endif
300  { 32, 32 },
301  { 1, 1 },
302  },
303 };
304 
305 
317 {
318  if( aDef.m_xpm != nullptr )
319  {
320  wxImage xpmImage = wxImage( aDef.m_xpm );
321 
322  xpmImage.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, aDef.m_hotspot.x );
323  xpmImage.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, aDef.m_hotspot.y );
324 
325  return wxCursor( xpmImage );
326  }
327  else if( aDef.m_image_data != nullptr && aDef.m_mask_data != nullptr )
328  {
329 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
330 
331  wxBitmap img_bitmap(
332  reinterpret_cast<const char*>( aDef.m_image_data ), aDef.m_size.x, aDef.m_size.y );
333  wxBitmap msk_bitmap(
334  reinterpret_cast<const char*>( aDef.m_mask_data ), aDef.m_size.x, aDef.m_size.y );
335  img_bitmap.SetMask( new wxMask( msk_bitmap ) );
336 
337  wxImage image( img_bitmap.ConvertToImage() );
338 
339 #if defined( __WXMSW__ )
340  image.SetMaskColour( 255, 255, 255 );
341 #endif
342 
343  image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, aDef.m_hotspot.x );
344  image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, aDef.m_hotspot.y );
345 
346  return wxCursor{ image };
347 
348 #elif defined( __WXGTK__ ) || defined( __WXMOTIF__ )
349 
350  return wxCursor{
351  reinterpret_cast<const char*>( aDef.m_image_data ),
352  aDef.m_size.x,
353  aDef.m_size.y,
354  aDef.m_hotspot.x,
355  aDef.m_hotspot.y,
356  reinterpret_cast<const char*>( aDef.m_mask_data ),
357  };
358 
359 #else
360  wxASSERT_MSG( false, "Unknown platform for cursor construction." );
361  return wxNullCursor;
362 #endif
363  }
364 
365  wxASSERT_MSG( false, "Unknown to find cursor" );
366  return wxNullCursor;
367 }
368 
369 
370 CURSOR_STORE::CURSOR_STORE( const std::vector<CURSOR_DEF>& aDefs )
371 {
372  for( const auto& def : aDefs )
373  {
374  m_store[def.m_id_key] = constructCursor( def );
375  }
376 }
377 
378 
379 const wxCursor& CURSOR_STORE::Get( KICURSOR aIdKey ) const
380 {
381  const auto find_iter = m_store.find( aIdKey );
382 
383  if( find_iter != m_store.end() )
384  return find_iter->second;
385 
386  wxASSERT_MSG( false, wxString::Format( "Could not find cursor with ID %d",
387  static_cast<int>( aIdKey ) ) );
388  return wxNullCursor;
389 }
390 
391 
392 const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
393 {
394  wxStockCursor stock =
395  GetStockCursor( aCursorType );
396  if( stock != wxCURSOR_MAX )
397  {
398  return wxCursor( stock );
399  }
400 
401  static CURSOR_STORE store( standard_cursors );
402  return store.Get( aCursorType );
403 }
404 
405 
406 const wxStockCursor CURSOR_STORE::GetStockCursor( KICURSOR aCursorType )
407 {
408  wxStockCursor stockCursor;
409  switch( aCursorType )
410  {
411  case KICURSOR::MOVING:
412  stockCursor = wxCURSOR_SIZING;
413  break;
414  case KICURSOR::BULLSEYE:
415  stockCursor = wxCURSOR_BULLSEYE;
416  break;
417  case KICURSOR::HAND:
418  stockCursor = wxCURSOR_HAND;
419  break;
420  case KICURSOR::ARROW:
421  stockCursor = wxCURSOR_ARROW;
422  break;
423  default:
424  stockCursor = wxCURSOR_MAX;
425  break;
426  }
427 
428  if( !KIPLATFORM::UI::IsStockCursorOk( stockCursor ) )
429  {
430  stockCursor = wxCURSOR_MAX;
431  }
432 
433  return stockCursor;
434 }
const unsigned char * m_mask_data
Definition: cursors.h:86
KICURSOR
Definition: cursors.h:33
static const unsigned char current_probe[]
Definition: cursors.cpp:71
std::map< KICURSOR, wxCursor > m_store
< Internal store of cursors by ID
Definition: cursors.h:120
const unsigned char * m_image_data
The mask data bitmap.
Definition: cursors.h:83
Simple class to construct and store cursors against unique ID keys.
Definition: cursors.h:71
const wxCursor & Get(KICURSOR aIdKey) const
Get a given cursor by its ID.
Definition: cursors.cpp:379
static const wxCursor GetCursor(KICURSOR aCursorType)
Definition: cursors.cpp:392
wxCursor constructCursor(const CURSOR_STORE::CURSOR_DEF &aDef)
Construct a cursor for the given definition.
Definition: cursors.cpp:316
Definition of a cursor.
Definition: cursors.h:77
wxSize m_size
The "hotspot" where the cursor "is" in the image.
Definition: cursors.h:91
CURSOR_STORE(const std::vector< CURSOR_DEF > &aDefs)
Construct a store with a pre-set list of cursors.
Definition: cursors.cpp:370
static const wxStockCursor GetStockCursor(KICURSOR aCursorType)
Definition: cursors.cpp:406
static const unsigned char cursor_tune_mask[]
Definition: cursors.cpp:91
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
static const unsigned char cursor_tune[]
Definition: cursors.cpp:81
static const unsigned char voltage_probe[]
Definition: cursors.cpp:61
bool IsStockCursorOk(wxStockCursor aCursor)
Checks if we designated a stock cursor for this OS as "OK" or else we may need to load a custom one.
Definition: gtk/ui.cpp:62
const char ** m_xpm
The image size in pixels.
Definition: cursors.h:88
static const std::vector< CURSOR_STORE::CURSOR_DEF > standard_cursors
Definition: cursors.cpp:102