KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-in.xpm>
48#include <cursors/cursor-zoom-out.xpm>
49#include <cursors/cursor_tune.xpm>
50#include <cursors/voltage_probe.xpm>
51#include <cursors/current_probe.xpm>
52
53// HiDPI cursor files
54#include <cursors/cursor-add64.xpm>
55#include <cursors/cursor-component64.xpm>
56#include <cursors/cursor-eraser64.xpm>
57#include <cursors/cursor-label-global64.xpm>
58#include <cursors/cursor-label-hier64.xpm>
59#include <cursors/cursor-label-net64.xpm>
60#include <cursors/cursor-line-bus64.xpm>
61#include <cursors/cursor-line-graphic64.xpm>
62#include <cursors/cursor-line-wire64.xpm>
63#include <cursors/cursor-line-wire-add64.xpm>
64#include <cursors/cursor-measure64.xpm>
65#include <cursors/cursor-pencil64.xpm>
66#include <cursors/cursor-select-lasso64.xpm>
67#include <cursors/cursor-select-window64.xpm>
68#include <cursors/cursor-subtract64.xpm>
69#include <cursors/cursor-text64.xpm>
70#include <cursors/cursor-xor64.xpm>
71#include <cursors/cursor-zoom-in64.xpm>
72#include <cursors/cursor-zoom-out64.xpm>
73#include <cursors/cursor_tune64.xpm>
74#include <cursors/voltage_probe64.xpm>
75#include <cursors/current_probe64.xpm>
76
77
78// Under MSW, the standard cursor is white on black. Elsewhere it is black on white
79#ifdef __WINDOWS__
80#include <cursors/cursor-place.xpm>
81#include <cursors/cursor-place64.xpm>
82#include <cursors/cursor-select-m.xpm>
83#include <cursors/cursor-select-m64.xpm>
84#else
85#include <cursors/cursor-place-black.xpm>
86#include <cursors/cursor-place-black64.xpm>
87#include <cursors/cursor-select-m-black.xpm>
88#include <cursors/cursor-select-m-black64.xpm>
89#endif
90
91#include <wx/bitmap.h>
92#include <wx/debug.h>
93
94
95static const std::vector<CURSOR_STORE::CURSOR_DEF> standard_cursors = {
96 {
98 nullptr,
99 nullptr,
100 voltage_probe_xpm,
101 { 32, 32 },
102 { 1, 31 },
103 },
104 {
106 nullptr,
107 nullptr,
108 current_probe_xpm,
109 { 32, 32 },
110 { 4, 27 },
111 },
112 {
114 nullptr,
115 nullptr,
116 cursor_tune_xpm,
117 { 32, 32 },
118 { 1, 30 },
119 },
120 {
122 nullptr,
123 nullptr,
124 cursor_pencil_xpm,
125 { 32, 32 },
126 { 4, 27 },
127 },
128 {
130 nullptr,
131 nullptr,
132#ifdef __WINDOWS__
133 cursor_select_m_xpm,
134#else
135 cursor_select_m_black_xpm,
136#endif
137 { 32, 32 },
138 { 1, 1 },
139 },
140 {
142 nullptr,
143 nullptr,
144 cursor_eraser_xpm,
145 { 32, 32 },
146 { 4, 4 },
147 },
148 {
150 nullptr,
151 nullptr,
152 cursor_text_xpm,
153 { 32, 32 },
154 { 7, 7 },
155 },
156 {
158 nullptr,
159 nullptr,
160 cursor_measure_xpm,
161 { 32, 32 },
162 { 4, 4 },
163 },
164 {
166 nullptr,
167 nullptr,
168 cursor_add_xpm,
169 { 32, 32 },
170 { 7, 7 },
171 },
172 {
174 nullptr,
175 nullptr,
176 cursor_subtract_xpm,
177 { 32, 32 },
178 { 7, 7 },
179 },
180 {
182 nullptr,
183 nullptr,
184 cursor_xor_xpm,
185 { 32, 32 },
186 { 7, 7 },
187 },
188 {
190 nullptr,
191 nullptr,
192 cursor_zoom_in_xpm,
193 { 32, 32 },
194 { 6, 6 },
195 },
196 {
198 nullptr,
199 nullptr,
200 cursor_zoom_out_xpm,
201 { 32, 32 },
202 { 6, 6 },
203 },
204 {
206 nullptr,
207 nullptr,
208 cursor_label_net_xpm,
209 { 32, 32 },
210 { 7, 7 },
211 },
212 {
214 nullptr,
215 nullptr,
216 cursor_label_global_xpm,
217 { 32, 32 },
218 { 7, 7 },
219 },
220 {
222 nullptr,
223 nullptr,
224 cursor_component_xpm,
225 { 32, 32 },
226 { 7, 7 },
227 },
228 {
230 nullptr,
231 nullptr,
232 cursor_select_lasso_xpm,
233 { 32, 32 },
234 { 7, 7 },
235 },
236 {
238 nullptr,
239 nullptr,
240 cursor_select_window_xpm,
241 { 32, 32 },
242 { 7, 10 },
243 },
244 {
246 nullptr,
247 nullptr,
248 cursor_line_bus_xpm,
249 { 32, 32 },
250 { 5, 26 },
251 },
252 {
254 nullptr,
255 nullptr,
256 cursor_line_wire_xpm,
257 { 32, 32 },
258 { 5, 26 },
259 },
260 {
262 nullptr,
263 nullptr,
264 cursor_line_wire_add_xpm,
265 { 32, 32 },
266 { 5, 26 },
267 },
268 {
270 nullptr,
271 nullptr,
272 cursor_line_graphic_xpm,
273 { 32, 32 },
274 { 5, 26 },
275 },
276 {
278 nullptr,
279 nullptr,
280 cursor_label_hier_xpm,
281 { 32, 32 },
282 { 7, 7 },
283 },
284 {
286 nullptr,
287 nullptr,
288#ifdef __WINDOWS__
289 cursor_place_xpm,
290#else
291 cursor_place_black_xpm,
292#endif
293 { 32, 32 },
294 { 1, 1 },
295 },
296};
297
298
299static const std::vector<CURSOR_STORE::CURSOR_DEF> hidpi_cursors = {
300 {
302 nullptr,
303 nullptr,
304 voltage_probe64_xpm,
305 { 64, 64 },
306 { 1, 62 },
307 },
308 {
310 nullptr,
311 nullptr,
312 current_probe64_xpm,
313 { 64, 64 },
314 { 8, 54 },
315 },
316 {
318 nullptr,
319 nullptr,
320 cursor_tune64_xpm,
321 { 64, 64 },
322 { 2, 60 },
323 },
324 {
326 nullptr,
327 nullptr,
328 cursor_pencil64_xpm,
329 { 64, 64 },
330 { 8, 54 },
331 },
332 {
334 nullptr,
335 nullptr,
336#ifdef __WINDOWS__
337 cursor_select_m64_xpm,
338#else
339 cursor_select_m_black64_xpm,
340#endif
341 { 64, 64 },
342 { 2, 2 },
343 },
344 {
346 nullptr,
347 nullptr,
348 cursor_eraser64_xpm,
349 { 64, 64 },
350 { 8, 8 },
351 },
352 {
354 nullptr,
355 nullptr,
356 cursor_text64_xpm,
357 { 64, 64 },
358 { 14, 14 },
359 },
360 {
362 nullptr,
363 nullptr,
364 cursor_measure64_xpm,
365 { 64, 64 },
366 { 8, 8 },
367 },
368 {
370 nullptr,
371 nullptr,
372 cursor_add64_xpm,
373 { 64, 64 },
374 { 14, 14 },
375 },
376 {
378 nullptr,
379 nullptr,
380 cursor_subtract64_xpm,
381 { 64, 64 },
382 { 14, 14 },
383 },
384 {
386 nullptr,
387 nullptr,
388 cursor_xor64_xpm,
389 { 64, 64 },
390 { 14, 14 },
391 },
392 {
394 nullptr,
395 nullptr,
396 cursor_zoom_in64_xpm,
397 { 64, 64 },
398 { 12, 12 },
399 },
400 {
402 nullptr,
403 nullptr,
404 cursor_zoom_out64_xpm,
405 { 64, 64 },
406 { 12, 12 },
407 },
408 {
410 nullptr,
411 nullptr,
412 cursor_label_net64_xpm,
413 { 64, 64 },
414 { 14, 14 },
415 },
416 {
418 nullptr,
419 nullptr,
420 cursor_label_global64_xpm,
421 { 64, 64 },
422 { 14, 14 },
423 },
424 {
426 nullptr,
427 nullptr,
428 cursor_component64_xpm,
429 { 64, 64 },
430 { 14, 14 },
431 },
432 {
434 nullptr,
435 nullptr,
436 cursor_select_lasso64_xpm,
437 { 64, 64 },
438 { 14, 14 },
439 },
440 {
442 nullptr,
443 nullptr,
444 cursor_select_window64_xpm,
445 { 64, 64 },
446 { 14, 20 },
447 },
448 {
450 nullptr,
451 nullptr,
452 cursor_line_bus64_xpm,
453 { 64, 64 },
454 { 10, 52 },
455 },
456 {
458 nullptr,
459 nullptr,
460 cursor_line_wire64_xpm,
461 { 64, 64 },
462 { 10, 52 },
463 },
464 {
466 nullptr,
467 nullptr,
468 cursor_line_wire_add64_xpm,
469 { 64, 64 },
470 { 10, 52 },
471 },
472 {
474 nullptr,
475 nullptr,
476 cursor_line_graphic64_xpm,
477 { 64, 64 },
478 { 10, 52 },
479 },
480 {
482 nullptr,
483 nullptr,
484 cursor_label_hier64_xpm,
485 { 64, 64 },
486 { 14, 14 },
487 },
488 {
490 nullptr,
491 nullptr,
492#ifdef __WINDOWS__
493 cursor_place64_xpm,
494#else
495 cursor_place_black64_xpm,
496#endif
497 { 64, 64 },
498 { 2, 2 },
499 },
500};
501
513{
514 if( aDef.m_xpm != nullptr )
515 {
516 wxImage xpmImage = wxImage( aDef.m_xpm );
517
518 xpmImage.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, aDef.m_hotspot.x );
519 xpmImage.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, aDef.m_hotspot.y );
520
521 return wxCursor( xpmImage );
522 }
523 else if( aDef.m_image_data != nullptr && aDef.m_mask_data != nullptr )
524 {
525#if defined( __WXMSW__ ) || defined( __WXMAC__ )
526
527 wxBitmap img_bitmap(
528 reinterpret_cast<const char*>( aDef.m_image_data ), aDef.m_size.x, aDef.m_size.y );
529 wxBitmap msk_bitmap(
530 reinterpret_cast<const char*>( aDef.m_mask_data ), aDef.m_size.x, aDef.m_size.y );
531 img_bitmap.SetMask( new wxMask( msk_bitmap ) );
532
533 wxImage image( img_bitmap.ConvertToImage() );
534
535#if defined( __WXMSW__ )
536 image.SetMaskColour( 255, 255, 255 );
537#endif
538
539 image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_X, aDef.m_hotspot.x );
540 image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, aDef.m_hotspot.y );
541
542 return wxCursor{ image };
543
544#elif defined( __WXGTK__ ) || defined( __WXMOTIF__ )
545
546 return wxCursor{
547 reinterpret_cast<const char*>( aDef.m_image_data ),
548 aDef.m_size.x,
549 aDef.m_size.y,
550 aDef.m_hotspot.x,
551 aDef.m_hotspot.y,
552 reinterpret_cast<const char*>( aDef.m_mask_data ),
553 };
554
555#else
556 wxASSERT_MSG( false, wxS( "Unknown platform for cursor construction." ) );
557 return wxNullCursor;
558#endif
559 }
560
561 wxASSERT_MSG( false, wxS( "Unknown to find cursor" ) );
562 return wxNullCursor;
563}
564
565
566CURSOR_STORE::CURSOR_STORE( const std::vector<CURSOR_DEF>& aDefs )
567{
568 for( const auto& def : aDefs )
569 {
570 m_store[def.m_id_key] = constructCursor( def );
571 }
572}
573
574
575const wxCursor& CURSOR_STORE::Get( KICURSOR aIdKey ) const
576{
577 const auto find_iter = m_store.find( aIdKey );
578
579 if( find_iter != m_store.end() )
580 return find_iter->second;
581
582 wxASSERT_MSG( false, wxString::Format( "Could not find cursor with ID %d",
583 static_cast<int>( aIdKey ) ) );
584 return wxNullCursor;
585}
586
587
588const wxCursor CURSOR_STORE::GetCursor( KICURSOR aCursorType )
589{
590 wxStockCursor stock = GetStockCursor( aCursorType );
591
592 if( stock != wxCURSOR_MAX )
593 {
594 return wxCursor( stock );
595 }
596
597 static CURSOR_STORE store( standard_cursors );
598 return store.Get( aCursorType );
599}
600
601
602const wxCursor CURSOR_STORE::GetHiDPICursor( KICURSOR aCursorType )
603{
604 wxStockCursor stock = GetStockCursor( aCursorType );
605
606 if( stock != wxCURSOR_MAX )
607 {
608 return wxCursor( stock );
609 }
610
611 static CURSOR_STORE store( hidpi_cursors );
612 return store.Get( aCursorType );
613}
614
615
616wxStockCursor CURSOR_STORE::GetStockCursor( KICURSOR aCursorType )
617{
618 wxStockCursor stockCursor;
619 switch( aCursorType )
620 {
621 case KICURSOR::MOVING:
622 stockCursor = wxCURSOR_SIZING;
623 break;
624 case KICURSOR::BULLSEYE:
625 stockCursor = wxCURSOR_BULLSEYE;
626 break;
627 case KICURSOR::HAND:
628 stockCursor = wxCURSOR_HAND;
629 break;
630 case KICURSOR::ARROW:
631 stockCursor = wxCURSOR_ARROW;
632 break;
633 default:
634 stockCursor = wxCURSOR_MAX;
635 break;
636 }
637
638 if( !KIPLATFORM::UI::IsStockCursorOk( stockCursor ) )
639 {
640 stockCursor = wxCURSOR_MAX;
641 }
642
643 return stockCursor;
644}
Simple class to construct and store cursors against unique ID keys.
Definition: cursors.h:99
const wxCursor & Get(KICURSOR aIdKey) const
Get a given cursor by its ID.
Definition: cursors.cpp:575
static wxStockCursor GetStockCursor(KICURSOR aCursorType)
Definition: cursors.cpp:616
static const wxCursor GetHiDPICursor(KICURSOR aCursorType)
Definition: cursors.cpp:602
static const wxCursor GetCursor(KICURSOR aCursorType)
Definition: cursors.cpp:588
CURSOR_STORE(const std::vector< CURSOR_DEF > &aDefs)
Construct a store with a pre-set list of cursors.
Definition: cursors.cpp:566
std::map< KICURSOR, wxCursor > m_store
< Internal store of cursors by ID
Definition: cursors.h:149
wxCursor constructCursor(const CURSOR_STORE::CURSOR_DEF &aDef)
Construct a cursor for the given definition.
Definition: cursors.cpp:512
static const std::vector< CURSOR_STORE::CURSOR_DEF > hidpi_cursors
Definition: cursors.cpp:299
static const std::vector< CURSOR_STORE::CURSOR_DEF > standard_cursors
Definition: cursors.cpp:95
KICURSOR
Definition: cursors.h:34
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: wxgtk/ui.cpp:100
Definition of a cursor.
Definition: cursors.h:105
const unsigned char * m_image_data
The mask data bitmap.
Definition: cursors.h:110
const char ** m_xpm
The image size in pixels.
Definition: cursors.h:115
const unsigned char * m_mask_data
Definition: cursors.h:113
wxSize m_size
The "hotspot" where the cursor "is" in the image.
Definition: cursors.h:118