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 AUTHORS.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 <gal/cursors.h>
27 #include <kiplatform/ui.h>
28 
29 // Cursor files
30 #include <cursors/cursor-add.xpm>
31 #include <cursors/cursor-component.xpm>
32 #include <cursors/cursor-eraser.xpm>
33 #include <cursors/cursor-label-global.xpm>
34 #include <cursors/cursor-label-hier.xpm>
35 #include <cursors/cursor-label-net.xpm>
36 #include <cursors/cursor-line-bus.xpm>
37 #include <cursors/cursor-line-graphic.xpm>
38 #include <cursors/cursor-line-wire.xpm>
39 #include <cursors/cursor-line-wire-add.xpm>
40 #include <cursors/cursor-measure.xpm>
41 #include <cursors/cursor-pencil.xpm>
42 #include <cursors/cursor-select-lasso.xpm>
43 #include <cursors/cursor-select-window.xpm>
44 #include <cursors/cursor-subtract.xpm>
45 #include <cursors/cursor-text.xpm>
46 #include <cursors/cursor-xor.xpm>
47 #include <cursors/cursor-zoom.xpm>
48 #include <cursors/cursor-zoom-out.xpm>
49 
50 // Under MSW, the standard cursor is white on black. Elsewhere it is black on white
51 #ifdef __WINDOWS__
52 #include <cursors/cursor-place.xpm>
53 #include <cursors/cursor-select-m.xpm>
54 #else
55 #include <cursors/cursor-place-black.xpm>
56 #include <cursors/cursor-select-m-black.xpm>
57 #endif
58 
59 #include <wx/bitmap.h>
60 #include <wx/debug.h>
61 
62 
63 static const unsigned char voltage_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
66  0x00, 0x30, 0x06, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x0e, 0x08, 0x00, 0x80, 0x07, 0x08, 0x00,
67  0xc0, 0x07, 0x18, 0x00, 0xe0, 0x07, 0x30, 0x00, 0xf0, 0x03, 0x60, 0x00, 0xf8, 0x01, 0x00, 0x00,
68  0xfc, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
69  0x0f, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0xf0,
70  0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
71  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
72 
73 static const unsigned char current_probe[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00,
76  0x00, 0x30, 0x0c, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x80, 0x0f, 0x18, 0x00,
77  0xc0, 0x0f, 0x30, 0x80, 0xe1, 0x07, 0x60, 0x80, 0xf1, 0x03, 0x00, 0x80, 0xf9, 0x01, 0x00, 0x80,
78  0xfd, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0,
79  0x0f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x00, 0x83,
80  0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xfc,
81  0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00 };
82 
83 static const unsigned char cursor_tune[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00,
85  0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
86  0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00,
87  0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
88  0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
89  0x05, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x50,
90  0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a,
91  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
92 
93 static const unsigned char cursor_tune_mask[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xc0, 0x0f,
95  0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x07,
96  0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xff, 0x01, 0x00, 0x80, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0x00,
97  0x00, 0xe0, 0x3f, 0x00, 0x00, 0xe0, 0x1f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00,
98  0x00, 0xfc, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00,
99  0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
100  0x70, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
101  0x0e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
102 
103 
104 static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
105  {
109  nullptr,
110  { 32, 32 },
111  { 1, 31 },
112  },
113  {
117  nullptr,
118  { 32, 32 },
119  { 4, 27 },
120  },
121  {
123  cursor_tune,
125  nullptr,
126  { 32, 32 },
127  { 1, 30 },
128  },
129  {
131  nullptr,
132  nullptr,
133  cursor_pencil_xpm,
134  { 32, 32 },
135  { 4, 27 },
136  },
137  {
139  nullptr,
140  nullptr,
141 #ifdef __WINDOWS__
142  cursor_select_m_xpm,
143 #else
144  cursor_select_m_black_xpm,
145 #endif
146  { 32, 32 },
147  { 1, 1 },
148  },
149  {
151  nullptr,
152  nullptr,
153  cursor_eraser_xpm,
154  { 32, 32 },
155  { 4, 4 },
156  },
157  {
159  nullptr,
160  nullptr,
161  cursor_text_xpm,
162  { 32, 32 },
163  { 7, 7 },
164  },
165  {
167  nullptr,
168  nullptr,
169  cursor_measure_xpm,
170  { 32, 32 },
171  { 4, 4 },
172  },
173  {
175  nullptr,
176  nullptr,
177  cursor_add_xpm,
178  { 32, 32 },
179  { 7, 7 },
180  },
181  {
183  nullptr,
184  nullptr,
185  cursor_subtract_xpm,
186  { 32, 32 },
187  { 7, 7 },
188  },
189  {
191  nullptr,
192  nullptr,
193  cursor_xor_xpm,
194  { 32, 32 },
195  { 7, 7 },
196  },
197  {
199  nullptr,
200  nullptr,
201  cursor_zoom_xpm,
202  { 32, 32 },
203  { 6, 6 },
204  },
205  {
207  nullptr,
208  nullptr,
209  cursor_zoom_out_xpm,
210  { 32, 32 },
211  { 6, 6 },
212  },
213  {
215  nullptr,
216  nullptr,
217  cursor_label_net_xpm,
218  { 32, 32 },
219  { 7, 7 },
220  },
221  {
223  nullptr,
224  nullptr,
225  cursor_label_global_xpm,
226  { 32, 32 },
227  { 7, 7 },
228  },
229  {
231  nullptr,
232  nullptr,
233  cursor_component_xpm,
234  { 32, 32 },
235  { 7, 7 },
236  },
237  {
239  nullptr,
240  nullptr,
241  cursor_select_lasso_xpm,
242  { 32, 32 },
243  { 7, 7 },
244  },
245  {
247  nullptr,
248  nullptr,
249  cursor_select_window_xpm,
250  { 32, 32 },
251  { 7, 10 },
252  },
253  {
255  nullptr,
256  nullptr,
257  cursor_line_bus_xpm,
258  { 32, 32 },
259  { 5, 26 },
260  },
261  {
263  nullptr,
264  nullptr,
265  cursor_line_wire_xpm,
266  { 32, 32 },
267  { 5, 26 },
268  },
269  {
271  nullptr,
272  nullptr,
273  cursor_line_wire_add_xpm,
274  { 32, 32 },
275  { 5, 26 },
276  },
277  {
279  nullptr,
280  nullptr,
281  cursor_line_graphic_xpm,
282  { 32, 32 },
283  { 5, 26 },
284  },
285  {
287  nullptr,
288  nullptr,
289  cursor_label_hier_xpm,
290  { 32, 32 },
291  { 7, 7 },
292  },
293  {
295  nullptr,
296  nullptr,
297 #ifdef __WINDOWS__
298  cursor_place_xpm,
299 #else
300  cursor_place_black_xpm,
301 #endif
302  { 32, 32 },
303  { 1, 1 },
304  },
305 };
306 
307 
319 {
320  if( aDef.m_xpm != nullptr )
321  {
322  wxImage xpmImage = wxImage( aDef.m_xpm );
323 
324  xpmImage.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, aDef.m_hotspot.x );
325  xpmImage.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, aDef.m_hotspot.y );
326 
327  return wxCursor( xpmImage );
328  }
329  else if( aDef.m_image_data != nullptr && aDef.m_mask_data != nullptr )
330  {
331 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
332 
333  wxBitmap img_bitmap(
334  reinterpret_cast<const char*>( aDef.m_image_data ), aDef.m_size.x, aDef.m_size.y );
335  wxBitmap msk_bitmap(
336  reinterpret_cast<const char*>( aDef.m_mask_data ), aDef.m_size.x, aDef.m_size.y );
337  img_bitmap.SetMask( new wxMask( msk_bitmap ) );
338 
339  wxImage image( img_bitmap.ConvertToImage() );
340 
341 #if defined( __WXMSW__ )
342  image.SetMaskColour( 255, 255, 255 );
343 #endif
344 
345  image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, aDef.m_hotspot.x );
346  image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, aDef.m_hotspot.y );
347 
348  return wxCursor{ image };
349 
350 #elif defined( __WXGTK__ ) || defined( __WXMOTIF__ )
351 
352  return wxCursor{
353  reinterpret_cast<const char*>( aDef.m_image_data ),
354  aDef.m_size.x,
355  aDef.m_size.y,
356  aDef.m_hotspot.x,
357  aDef.m_hotspot.y,
358  reinterpret_cast<const char*>( aDef.m_mask_data ),
359  };
360 
361 #else
362  wxASSERT_MSG( false, "Unknown platform for cursor construction." );
363  return wxNullCursor;
364 #endif
365  }
366 
367  wxASSERT_MSG( false, "Unknown to find cursor" );
368  return wxNullCursor;
369 }
370 
371 
372 CURSOR_STORE::CURSOR_STORE( const std::vector<CURSOR_DEF>& aDefs )
373 {
374  for( const auto& def : aDefs )
375  {
376  m_store[def.m_id_key] = constructCursor( def );
377  }
378 }
379 
380 
381 const wxCursor& CURSOR_STORE::Get( KICURSOR aIdKey ) const
382 {
383  const auto find_iter = m_store.find( aIdKey );
384 
385  if( find_iter != m_store.end() )
386  return find_iter->second;
387 
388  wxASSERT_MSG( false, wxString::Format( "Could not find cursor with ID %d",
389  static_cast<int>( aIdKey ) ) );
390  return wxNullCursor;
391 }
392 
393 
394 const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
395 {
396  wxStockCursor stock =
397  GetStockCursor( aCursorType );
398  if( stock != wxCURSOR_MAX )
399  {
400  return wxCursor( stock );
401  }
402 
403  static CURSOR_STORE store( standard_cursors );
404  return store.Get( aCursorType );
405 }
406 
407 
408 const wxStockCursor CURSOR_STORE::GetStockCursor( KICURSOR aCursorType )
409 {
410  wxStockCursor stockCursor;
411  switch( aCursorType )
412  {
413  case KICURSOR::MOVING:
414  stockCursor = wxCURSOR_SIZING;
415  break;
416  case KICURSOR::BULLSEYE:
417  stockCursor = wxCURSOR_BULLSEYE;
418  break;
419  case KICURSOR::HAND:
420  stockCursor = wxCURSOR_HAND;
421  break;
422  case KICURSOR::ARROW:
423  stockCursor = wxCURSOR_ARROW;
424  break;
425  default:
426  stockCursor = wxCURSOR_MAX;
427  break;
428  }
429 
430  if( !KIPLATFORM::UI::IsStockCursorOk( stockCursor ) )
431  {
432  stockCursor = wxCURSOR_MAX;
433  }
434 
435  return stockCursor;
436 }
const unsigned char * m_mask_data
Definition: cursors.h:86
KICURSOR
Definition: cursors.h:33
static const unsigned char current_probe[]
Definition: cursors.cpp:73
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:381
static const wxCursor GetCursor(KICURSOR aCursorType)
Definition: cursors.cpp:394
wxCursor constructCursor(const CURSOR_STORE::CURSOR_DEF &aDef)
Construct a cursor for the given definition.
Definition: cursors.cpp:318
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:372
static const wxStockCursor GetStockCursor(KICURSOR aCursorType)
Definition: cursors.cpp:408
static const unsigned char cursor_tune_mask[]
Definition: cursors.cpp:93
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:83
static const unsigned char voltage_probe[]
Definition: cursors.cpp:63
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:77
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:104