]> git.saurik.com Git - wxWidgets.git/blame - src/mac/cursor.cpp
Make wxr resources work in Unicode mode.
[wxWidgets.git] / src / mac / cursor.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: cursor.cpp
3// Purpose: wxCursor class
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "cursor.h"
14#endif
15
0e13e965
GD
16#include "wx/defs.h"
17
18#include "wx/app.h"
e9576ca5
SC
19#include "wx/cursor.h"
20#include "wx/icon.h"
c6a071d2 21#include "wx/image.h"
76a5e5d2 22#include "wx/mac/private.h"
e9576ca5 23
2f1ae414 24#if !USE_SHARED_LIBRARIES
e9576ca5 25IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
2f1ae414 26#endif
e9576ca5 27
c6a071d2
SC
28const short kwxCursorBullseye = 10 ;
29const short kwxCursorBlank = 11 ;
30const short kwxCursorPencil = 12 ;
31const short kwxCursorMagnifier = 13 ;
32const short kwxCursorNoEntry = 14 ;
33const short kwxCursorPaintBrush = 15 ;
34const short kwxCursorPointRight = 16 ;
35const short kwxCursorPointLeft = 17 ;
36const short kwxCursorQuestionArrow = 18 ;
37const short kwxCursorRightArrow = 19 ;
38const short kwxCursorSizeNS = 20 ;
39const short kwxCursorSize = 21 ;
40const short kwxCursorSizeNESW = 22 ;
41const short kwxCursorSizeNWSE = 23 ;
42const short kwxCursorRoller = 24 ;
43
44wxCursor gMacCurrentCursor ;
519cb848 45
e9576ca5
SC
46wxCursorRefData::wxCursorRefData()
47{
c6a071d2
SC
48 m_width = 16;
49 m_height = 16;
519cb848 50 m_hCursor = NULL ;
c6a071d2
SC
51 m_disposeHandle = false ;
52 m_releaseHandle = false ;
53 m_isColorCursor = false ;
54 m_themeCursor = -1 ;
e9576ca5
SC
55}
56
57wxCursorRefData::~wxCursorRefData()
58{
c6a071d2
SC
59 if ( m_isColorCursor )
60 {
61 ::DisposeCCursor( (CCrsrHandle) m_hCursor ) ;
62 }
63 else if ( m_disposeHandle )
64 {
65 ::DisposeHandle( (Handle ) m_hCursor ) ;
66 } else if ( m_releaseHandle )
67 {
68 ::ReleaseResource( (Handle ) m_hCursor ) ;
69 }
e9576ca5
SC
70}
71
72// Cursors
73wxCursor::wxCursor()
74{
75}
76
77wxCursor::wxCursor(const char WXUNUSED(bits)[], int WXUNUSED(width), int WXUNUSED(height),
78 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY), const char WXUNUSED(maskBits)[])
79{
80}
81
c6a071d2
SC
82wxCursor::wxCursor( const wxImage &image )
83{
ce72eadb 84 CreateFromImage( image ) ;
c6a071d2
SC
85}
86
ce72eadb 87void wxCursor::CreateFromImage(const wxImage & image)
c6a071d2
SC
88{
89 m_refData = new wxCursorRefData;
90
91 wxImage image16 = image.Scale(16,16) ;
92 unsigned char * rgbBits = image16.GetData();
93
94
95 int w = image16.GetWidth() ;
96 int h = image16.GetHeight() ;
97 bool bHasMask = image16.HasMask() ;
98
99 int hotSpotX = image16.GetOptionInt(wxCUR_HOTSPOT_X);
100 int hotSpotY = image16.GetOptionInt(wxCUR_HOTSPOT_Y);
101 if (hotSpotX < 0 || hotSpotX >= w)
102 hotSpotX = 0;
103 if (hotSpotY < 0 || hotSpotY >= h)
104 hotSpotY = 0;
105
106 M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ;
107 M_CURSORDATA->m_disposeHandle = true ;
108 HLock( (Handle) M_CURSORDATA->m_hCursor ) ;
109 CursPtr cp = *(CursHandle)M_CURSORDATA->m_hCursor ;
110 memset( cp->data , 0 , sizeof( Bits16 ) ) ;
111 memset( cp->mask , 0 , sizeof( Bits16 ) ) ;
112
113 unsigned char mr = image16.GetMaskRed() ;
114 unsigned char mg = image16.GetMaskGreen() ;
115 unsigned char mb = image16.GetMaskBlue() ;
116 for ( int y = 0 ; y < h ; ++y )
117 {
118 short rowbits = 0 ;
119 short maskbits = 0 ;
120
121 for ( int x = 0 ; x < w ; ++x )
122 {
123 long pos = (y * w + x) * 3;
124
125 unsigned char r = rgbBits[pos] ;
126 unsigned char g = rgbBits[pos+1] ;
127 unsigned char b = rgbBits[pos+2] ;
128 if ( bHasMask && r==mr && g==mg && b==mb )
129 {
130 // masked area, does not appear anywhere
131 }
132 else
133 {
134 if ( (int)r + (int)g + (int)b < 0x60 )
135 {
136 rowbits |= ( 1 << (15-x) ) ;
137 }
138 maskbits |= ( 1 << (15-x) ) ;
139 }
140 }
141 cp->data[y] = rowbits ;
142 cp->mask[y] = maskbits ;
143 }
144 if ( !bHasMask )
145 {
146 memcpy( cp->mask , cp->data , sizeof( Bits16) ) ;
147 }
148
149 cp->hotSpot.h = hotSpotX ;
150 cp->hotSpot.v = hotSpotY ;
151 HUnlock( (Handle) M_CURSORDATA->m_hCursor ) ;
152}
153
e9576ca5
SC
154wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
155{
156 m_refData = new wxCursorRefData;
c6a071d2
SC
157 if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE )
158 {
159 Str255 theName ;
e9576ca5 160
c6a071d2
SC
161 #if TARGET_CARBON
162 c2pstrcpy( (StringPtr) theName , cursor_file ) ;
163 #else
164 strcpy( (char *) theName , cursor_file ) ;
165 c2pstr( (char *) theName ) ;
166 #endif
167
168 wxStAppResource resload ;
169 M_CURSORDATA->m_hCursor = ::GetNamedResource( 'crsr' , theName ) ;
170 if ( M_CURSORDATA->m_hCursor )
171 {
172 M_CURSORDATA->m_isColorCursor = true ;
173 }
174 else
175 {
176 M_CURSORDATA->m_hCursor = ::GetNamedResource( 'CURS' , theName ) ;
177 if ( M_CURSORDATA->m_hCursor )
178 M_CURSORDATA->m_releaseHandle = true ;
179 }
180 }
181 else
182 {
183 wxImage image ;
184 image.LoadFile( cursor_file , flags ) ;
185 if( image.Ok() )
186 {
187 image.SetOption(wxCUR_HOTSPOT_X,hotSpotX ) ;
188 image.SetOption(wxCUR_HOTSPOT_Y,hotSpotY ) ;
189 delete m_refData ;
ce72eadb 190 CreateFromImage(image) ;
c6a071d2
SC
191 }
192 }
e9576ca5
SC
193}
194
195// Cursors by stock number
196wxCursor::wxCursor(int cursor_type)
197{
198 m_refData = new wxCursorRefData;
c6a071d2 199
e9576ca5
SC
200 switch (cursor_type)
201 {
202 case wxCURSOR_WAIT:
c6a071d2 203 M_CURSORDATA->m_themeCursor = kThemeWatchCursor ;
e9576ca5
SC
204 break;
205 case wxCURSOR_IBEAM:
c6a071d2 206 M_CURSORDATA->m_themeCursor = kThemeIBeamCursor ;
e9576ca5
SC
207 break;
208 case wxCURSOR_CROSS:
c6a071d2 209 M_CURSORDATA->m_themeCursor = kThemeCrossCursor;
e9576ca5
SC
210 break;
211 case wxCURSOR_SIZENWSE:
fe3fcb05
SC
212 {
213 wxStAppResource resload ;
c6a071d2 214 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNWSE);
fe3fcb05 215 }
e9576ca5
SC
216 break;
217 case wxCURSOR_SIZENESW:
fe3fcb05
SC
218 {
219 wxStAppResource resload ;
c6a071d2 220 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNESW);
fe3fcb05 221 }
e9576ca5
SC
222 break;
223 case wxCURSOR_SIZEWE:
fe3fcb05 224 {
c6a071d2 225 M_CURSORDATA->m_themeCursor = kThemeResizeLeftRightCursor;
fe3fcb05 226 }
e9576ca5
SC
227 break;
228 case wxCURSOR_SIZENS:
fe3fcb05
SC
229 {
230 wxStAppResource resload ;
c6a071d2
SC
231 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNS);
232 }
233 break;
234 case wxCURSOR_SIZING:
235 {
236 wxStAppResource resload ;
237 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSize);
fe3fcb05 238 }
e9576ca5 239 break;
e9576ca5 240 case wxCURSOR_HAND:
c6a071d2
SC
241 {
242 M_CURSORDATA->m_themeCursor = kThemePointingHandCursor;
243 }
244 break;
e9576ca5 245 case wxCURSOR_BULLSEYE:
fe3fcb05
SC
246 {
247 wxStAppResource resload ;
c6a071d2 248 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBullseye);
fe3fcb05
SC
249 }
250 break;
e9576ca5 251 case wxCURSOR_PENCIL:
fe3fcb05
SC
252 {
253 wxStAppResource resload ;
c6a071d2 254 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPencil);
fe3fcb05
SC
255 }
256 break;
e9576ca5 257 case wxCURSOR_MAGNIFIER:
fe3fcb05
SC
258 {
259 wxStAppResource resload ;
c6a071d2 260 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorMagnifier);
fe3fcb05
SC
261 }
262 break;
e9576ca5 263 case wxCURSOR_NO_ENTRY:
fe3fcb05
SC
264 {
265 wxStAppResource resload ;
c6a071d2 266 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorNoEntry);
fe3fcb05
SC
267 }
268 break;
e9576ca5
SC
269 case wxCURSOR_WATCH:
270 {
c6a071d2 271 M_CURSORDATA->m_themeCursor = kThemeWatchCursor;
e9576ca5
SC
272 break;
273 }
274 case wxCURSOR_PAINT_BRUSH:
275 {
c6a071d2
SC
276 wxStAppResource resload ;
277 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPaintBrush);
e9576ca5
SC
278 break;
279 }
280 case wxCURSOR_POINT_LEFT:
281 {
c6a071d2
SC
282 wxStAppResource resload ;
283 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointLeft);
e9576ca5
SC
284 break;
285 }
286 case wxCURSOR_POINT_RIGHT:
287 {
c6a071d2
SC
288 wxStAppResource resload ;
289 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointRight);
e9576ca5
SC
290 break;
291 }
292 case wxCURSOR_QUESTION_ARROW:
293 {
c6a071d2
SC
294 wxStAppResource resload ;
295 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorQuestionArrow);
e9576ca5
SC
296 break;
297 }
298 case wxCURSOR_BLANK:
299 {
c6a071d2
SC
300 wxStAppResource resload ;
301 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBlank);
302 break;
303 }
304 case wxCURSOR_RIGHT_ARROW:
305 {
306 wxStAppResource resload ;
307 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRightArrow);
e9576ca5
SC
308 break;
309 }
c6a071d2
SC
310 case wxCURSOR_SPRAYCAN:
311 {
312 wxStAppResource resload ;
313 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRoller);
314 break;
315 }
316 case wxCURSOR_CHAR:
e9576ca5 317 case wxCURSOR_ARROW:
c6a071d2
SC
318 case wxCURSOR_LEFT_BUTTON:
319 case wxCURSOR_RIGHT_BUTTON:
320 case wxCURSOR_MIDDLE_BUTTON:
321 default:
322 M_CURSORDATA->m_themeCursor = kThemeArrowCursor ;
e9576ca5 323 break;
519cb848 324 }
c6a071d2
SC
325 if ( M_CURSORDATA->m_themeCursor == -1 )
326 M_CURSORDATA->m_releaseHandle = true ;
519cb848 327}
e9576ca5 328
519cb848
SC
329void wxCursor::MacInstall() const
330{
c6a071d2
SC
331 gMacCurrentCursor = *this ;
332 if ( m_refData && M_CURSORDATA->m_themeCursor != -1 )
333 {
334 SetThemeCursor( M_CURSORDATA->m_themeCursor ) ;
335 }
336 else if ( m_refData && M_CURSORDATA->m_hCursor )
519cb848 337 {
c6a071d2
SC
338 if ( M_CURSORDATA->m_isColorCursor )
339 ::SetCCursor( (CCrsrHandle) M_CURSORDATA->m_hCursor ) ;
340 else
341 ::SetCursor( * (CursHandle) M_CURSORDATA->m_hCursor ) ;
519cb848
SC
342 }
343 else
344 {
c6a071d2 345 SetThemeCursor( kThemeArrowCursor ) ;
519cb848 346 }
e9576ca5
SC
347}
348
349wxCursor::~wxCursor()
350{
351}
352
353// Global cursor setting
354void wxSetCursor(const wxCursor& cursor)
355{
519cb848 356 cursor.MacInstall() ;
e9576ca5
SC
357}
358
359