renaming because of conflicts with base Create::
[wxWidgets.git] / src / mac / carbon / cursor.cpp
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
16 #include "wx/defs.h"
17
18 #include "wx/app.h"
19 #include "wx/cursor.h"
20 #include "wx/icon.h"
21 #include "wx/image.h"
22 #include "wx/mac/private.h"
23
24 #if !USE_SHARED_LIBRARIES
25 IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
26 #endif
27
28 const short kwxCursorBullseye = 10 ;
29 const short kwxCursorBlank = 11 ;
30 const short kwxCursorPencil = 12 ;
31 const short kwxCursorMagnifier = 13 ;
32 const short kwxCursorNoEntry = 14 ;
33 const short kwxCursorPaintBrush = 15 ;
34 const short kwxCursorPointRight = 16 ;
35 const short kwxCursorPointLeft = 17 ;
36 const short kwxCursorQuestionArrow = 18 ;
37 const short kwxCursorRightArrow = 19 ;
38 const short kwxCursorSizeNS = 20 ;
39 const short kwxCursorSize = 21 ;
40 const short kwxCursorSizeNESW = 22 ;
41 const short kwxCursorSizeNWSE = 23 ;
42 const short kwxCursorRoller = 24 ;
43
44 wxCursor gMacCurrentCursor ;
45
46 wxCursorRefData::wxCursorRefData()
47 {
48 m_width = 16;
49 m_height = 16;
50 m_hCursor = NULL ;
51 m_disposeHandle = false ;
52 m_releaseHandle = false ;
53 m_isColorCursor = false ;
54 m_themeCursor = -1 ;
55 }
56
57 wxCursorRefData::~wxCursorRefData()
58 {
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 }
70 }
71
72 // Cursors
73 wxCursor::wxCursor()
74 {
75 }
76
77 wxCursor::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
82 wxCursor::wxCursor( const wxImage &image )
83 {
84 CreateFromImage( image ) ;
85 }
86
87 void wxCursor::CreateFromImage(const wxImage & image)
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
154 wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
155 {
156 m_refData = new wxCursorRefData;
157 if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE )
158 {
159 Str255 theName ;
160
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 ;
190 CreateFromImage(image) ;
191 }
192 }
193 }
194
195 // Cursors by stock number
196 wxCursor::wxCursor(int cursor_type)
197 {
198 m_refData = new wxCursorRefData;
199
200 switch (cursor_type)
201 {
202 case wxCURSOR_WAIT:
203 M_CURSORDATA->m_themeCursor = kThemeWatchCursor ;
204 break;
205 case wxCURSOR_IBEAM:
206 M_CURSORDATA->m_themeCursor = kThemeIBeamCursor ;
207 break;
208 case wxCURSOR_CROSS:
209 M_CURSORDATA->m_themeCursor = kThemeCrossCursor;
210 break;
211 case wxCURSOR_SIZENWSE:
212 {
213 wxStAppResource resload ;
214 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNWSE);
215 }
216 break;
217 case wxCURSOR_SIZENESW:
218 {
219 wxStAppResource resload ;
220 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNESW);
221 }
222 break;
223 case wxCURSOR_SIZEWE:
224 {
225 M_CURSORDATA->m_themeCursor = kThemeResizeLeftRightCursor;
226 }
227 break;
228 case wxCURSOR_SIZENS:
229 {
230 wxStAppResource resload ;
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);
238 }
239 break;
240 case wxCURSOR_HAND:
241 {
242 M_CURSORDATA->m_themeCursor = kThemePointingHandCursor;
243 }
244 break;
245 case wxCURSOR_BULLSEYE:
246 {
247 wxStAppResource resload ;
248 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBullseye);
249 }
250 break;
251 case wxCURSOR_PENCIL:
252 {
253 wxStAppResource resload ;
254 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPencil);
255 }
256 break;
257 case wxCURSOR_MAGNIFIER:
258 {
259 wxStAppResource resload ;
260 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorMagnifier);
261 }
262 break;
263 case wxCURSOR_NO_ENTRY:
264 {
265 wxStAppResource resload ;
266 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorNoEntry);
267 }
268 break;
269 case wxCURSOR_WATCH:
270 {
271 M_CURSORDATA->m_themeCursor = kThemeWatchCursor;
272 break;
273 }
274 case wxCURSOR_PAINT_BRUSH:
275 {
276 wxStAppResource resload ;
277 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPaintBrush);
278 break;
279 }
280 case wxCURSOR_POINT_LEFT:
281 {
282 wxStAppResource resload ;
283 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointLeft);
284 break;
285 }
286 case wxCURSOR_POINT_RIGHT:
287 {
288 wxStAppResource resload ;
289 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointRight);
290 break;
291 }
292 case wxCURSOR_QUESTION_ARROW:
293 {
294 wxStAppResource resload ;
295 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorQuestionArrow);
296 break;
297 }
298 case wxCURSOR_BLANK:
299 {
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);
308 break;
309 }
310 case wxCURSOR_SPRAYCAN:
311 {
312 wxStAppResource resload ;
313 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRoller);
314 break;
315 }
316 case wxCURSOR_CHAR:
317 case wxCURSOR_ARROW:
318 case wxCURSOR_LEFT_BUTTON:
319 case wxCURSOR_RIGHT_BUTTON:
320 case wxCURSOR_MIDDLE_BUTTON:
321 default:
322 M_CURSORDATA->m_themeCursor = kThemeArrowCursor ;
323 break;
324 }
325 if ( M_CURSORDATA->m_themeCursor == -1 )
326 M_CURSORDATA->m_releaseHandle = true ;
327 }
328
329 void wxCursor::MacInstall() const
330 {
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 )
337 {
338 if ( M_CURSORDATA->m_isColorCursor )
339 ::SetCCursor( (CCrsrHandle) M_CURSORDATA->m_hCursor ) ;
340 else
341 ::SetCursor( * (CursHandle) M_CURSORDATA->m_hCursor ) ;
342 }
343 else
344 {
345 SetThemeCursor( kThemeArrowCursor ) ;
346 }
347 }
348
349 wxCursor::~wxCursor()
350 {
351 }
352
353 // Global cursor setting
354 void wxSetCursor(const wxCursor& cursor)
355 {
356 cursor.MacInstall() ;
357 }
358
359