add more pure virtuals to wxBrushBase; fix the GetColour() functions to return a...
[wxWidgets.git] / src / cocoa / pen.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/cocoa/pen.mm
3 // Purpose:     wxPen
4 // Author:      David Elliott
5 // Modified by:
6 // Created:     2003/08/02
7 // RCS-ID:      $Id$
8 // Copyright:   (c) 2003 David Elliott
9 // Licence:     wxWidgets licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifndef WX_PRECOMP
15     #include "wx/pen.h"
16     #include "wx/bitmap.h"
17     #include "wx/colour.h"
18 #endif //WX_PRECOMP
19
20 #include "wx/cocoa/ObjcRef.h"
21
22 #import <AppKit/NSColor.h>
23
24 // ========================================================================
25 // wxPenRefData
26 // ========================================================================
27 class WXDLLEXPORT wxPenRefData: public wxGDIRefData
28 {
29 public:
30     wxPenRefData(const wxColour& colour = wxNullColour,
31         int width = 1, int style = wxSOLID,
32         const wxBitmap& stipple = wxNullBitmap);
33     wxPenRefData(const wxPenRefData& data);
34     ~wxPenRefData() { FreeCocoaNSColor(); FreeCocoaDash(); }
35
36     void SetWidth(int Width) { m_width = Width; }
37     void SetStyle(int Style)
38     {   FreeCocoaNSColor();
39         FreeCocoaDash();
40         m_style = Style;
41     }
42     void SetJoin(int Join) { m_join = Join; }
43     void SetCap(int Cap) { m_cap = Cap; }
44     void SetColour(const wxColour& col) { FreeCocoaNSColor(); m_colour = col; }
45     void SetDashes(int nb_dashes, const wxDash *Dash)
46     {
47         FreeCocoaDash();
48         m_nbDash = nb_dashes;
49         m_dash = (wxDash *)Dash;
50     }
51     void SetStipple(const wxBitmap& Stipple)
52     {
53         FreeCocoaNSColor();
54         m_stipple = Stipple;
55         m_style = wxSTIPPLE;
56     }
57     WX_NSColor GetNSColor();
58     int GetCocoaLineDash(const CGFloat **pattern);
59 protected:
60     void FreeCocoaNSColor();
61     void FreeCocoaDash();
62
63     int             m_width;
64     int             m_style;
65     int             m_join;
66     int             m_cap;
67     wxColour        m_colour;
68     int             m_nbDash;
69     wxDash         *m_dash;
70     wxBitmap        m_stipple;
71     WX_NSColor      m_cocoaNSColor;
72     CGFloat        *m_cocoaDash;
73
74     // Predefined dash patterns
75     static const int scm_countDot;
76     static const CGFloat scm_patternDot[];
77     static const int scm_countLongDash;
78     static const CGFloat scm_patternLongDash[];
79     static const int scm_countShortDash;
80     static const CGFloat scm_patternShortDash[];
81     static const int scm_countDotDash;
82     static const CGFloat scm_patternDotDash[];
83
84     friend class WXDLLIMPEXP_FWD_CORE wxPen;
85
86 private:
87     // Don't allow assignment
88     wxPenRefData& operator=(const wxPenRefData& data);
89 };
90
91 const int wxPenRefData::scm_countDot = 1;
92 const CGFloat wxPenRefData::scm_patternDot[] = {
93     1.0
94 };
95 const int wxPenRefData::scm_countLongDash = 1;
96 const CGFloat wxPenRefData::scm_patternLongDash[] = {
97     10.0
98 };
99 const int wxPenRefData::scm_countShortDash = 1;
100 const CGFloat wxPenRefData::scm_patternShortDash[] = {
101     5.0
102 };
103 const int wxPenRefData::scm_countDotDash = 4;
104 const CGFloat wxPenRefData::scm_patternDotDash[] = {
105     1.0
106 ,   1.0
107 ,   5.0
108 ,   1.0
109 };
110
111 #define M_PENDATA ((wxPenRefData *)m_refData)
112
113 inline wxPenRefData::wxPenRefData(const wxColour& colour,
114         int width, int style, const wxBitmap& stipple)
115 {
116     m_width = width;
117     m_style = style;
118     m_join = wxJOIN_ROUND;
119     m_cap = wxCAP_ROUND;
120     m_colour = colour;
121     m_nbDash = 0;
122     m_dash = 0;
123     m_stipple = stipple;
124     m_cocoaNSColor = nil;
125     m_cocoaDash = NULL;
126 }
127
128 inline wxPenRefData::wxPenRefData(const wxPenRefData& data)
129 {
130     m_width = data.m_width;
131     m_style = data.m_style;
132     m_join = data.m_join;
133     m_cap = data.m_cap;
134     m_colour = data.m_colour;
135     m_nbDash = data.m_nbDash;
136     m_dash = data.m_dash;
137     m_stipple = data.m_stipple;
138     m_cocoaNSColor = wxGCSafeRetain(data.m_cocoaNSColor);
139     m_cocoaDash = NULL;
140 }
141
142 inline void wxPenRefData::FreeCocoaNSColor()
143 {
144     wxGCSafeRelease(m_cocoaNSColor);
145     m_cocoaNSColor = nil;
146 }
147
148 inline void wxPenRefData::FreeCocoaDash()
149 {
150     delete m_cocoaDash;
151     m_cocoaDash = NULL;
152 }
153
154 inline WX_NSColor wxPenRefData::GetNSColor()
155 {
156     if(!m_cocoaNSColor)
157     {
158         switch( m_style )
159         {
160         case wxTRANSPARENT:
161             m_cocoaNSColor = wxGCSafeRetain([NSColor clearColor]);
162             break;
163         case wxSTIPPLE:
164 //  wxBitmap isn't implemented yet
165 //            m_cocoaNSColor = [[NSColor colorWithPatternImage: m_stipple.GetNSImage()] retain];
166 //            break;
167         // The hatch brushes are going to be tricky
168         case wxBDIAGONAL_HATCH:
169         case wxCROSSDIAG_HATCH:
170         case wxFDIAGONAL_HATCH:
171         case wxCROSS_HATCH:
172         case wxHORIZONTAL_HATCH:
173         case wxVERTICAL_HATCH:
174         default:
175         // Dot/dashed pens use solid colors
176         case wxDOT:
177         case wxLONG_DASH:
178         case wxSHORT_DASH:
179         case wxDOT_DASH:
180         case wxUSER_DASH:
181         case wxSOLID:
182             NSColor *colour_NSColor = m_colour.GetNSColor();
183             if(!colour_NSColor)
184                 colour_NSColor = [NSColor clearColor];
185             m_cocoaNSColor = [colour_NSColor copyWithZone:nil];
186             [wxGCSafeRetain(m_cocoaNSColor) release]; // retain in GC. no change in RR.
187             break;
188         }
189     }
190     return m_cocoaNSColor;
191 }
192
193 int wxPenRefData::GetCocoaLineDash(const CGFloat **pattern)
194 {
195     int count;
196     switch( m_style )
197     {
198     case wxDOT:
199         count = scm_countDot;
200         if(pattern)
201             *pattern = scm_patternDot;
202         break;
203     case wxLONG_DASH:
204         count = scm_countLongDash;
205         if(pattern)
206             *pattern = scm_patternLongDash;
207         break;
208     case wxSHORT_DASH:
209         count = scm_countShortDash;
210         if(pattern)
211             *pattern = scm_patternShortDash;
212         break;
213     case wxDOT_DASH:
214         count = scm_countDotDash;
215         if(pattern)
216             *pattern = scm_patternDotDash;
217         break;
218     case wxUSER_DASH:
219         count = m_nbDash;
220         if(pattern)
221         {
222             if(!m_cocoaDash)
223             {
224                 m_cocoaDash = new CGFloat[count];
225                 for(int i=0; i<count; i++)
226                     m_cocoaDash[i] = m_dash[i];
227             }
228             *pattern = m_cocoaDash;
229         }
230         break;
231     case wxTRANSPARENT:
232     case wxSTIPPLE:
233     case wxBDIAGONAL_HATCH:
234     case wxCROSSDIAG_HATCH:
235     case wxFDIAGONAL_HATCH:
236     case wxCROSS_HATCH:
237     case wxHORIZONTAL_HATCH:
238     case wxVERTICAL_HATCH:
239     case wxSOLID:
240     default:
241         count = 0;
242         if(pattern)
243             *pattern = NULL;
244     }
245     return count;
246 }
247
248 // ========================================================================
249 // wxPen
250 // ========================================================================
251 IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
252
253 wxPen::wxPen()
254 {
255 }
256
257 wxPen::~wxPen()
258 {
259 }
260
261 // Should implement Create
262 wxPen::wxPen(const wxColour& colour, int width, int style)
263 {
264     m_refData = new wxPenRefData(colour,width,style);
265 }
266
267 wxPen::wxPen(const wxBitmap& stipple, int width)
268 {
269     m_refData = new wxPenRefData(wxNullColour,width,wxSTIPPLE,stipple);
270 }
271
272 wxGDIRefData *wxPen::CreateGDIRefData() const
273 {
274     return new wxPenRefData;
275 }
276
277 wxGDIRefData *wxPen::CloneGDIRefData(const wxGDIRefData *data) const
278 {
279     return new wxPenRefData(*(wxPenRefData *)data);
280 }
281
282 void wxPen::SetWidth(int Width)
283 {
284     AllocExclusive();
285     M_PENDATA->SetWidth(Width);
286 }
287
288 void wxPen::SetStyle(int Style)
289 {
290     AllocExclusive();
291     M_PENDATA->SetStyle(Style);
292 }
293
294 void wxPen::SetJoin(int Join)
295 {
296     AllocExclusive();
297     M_PENDATA->SetJoin(Join);
298 }
299
300 void wxPen::SetCap(int Cap)
301 {
302     AllocExclusive();
303     M_PENDATA->SetCap(Cap);
304 }
305
306 void wxPen::SetColour(const wxColour& col)
307 {
308     AllocExclusive();
309     M_PENDATA->SetColour(col);
310 }
311
312 void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b)
313 {
314     AllocExclusive();
315     M_PENDATA->SetColour(wxColour(r, g, b));
316 }
317
318 void wxPen::SetDashes(int nb_dashes, const wxDash *Dash)
319 {
320     AllocExclusive();
321     M_PENDATA->SetDashes(nb_dashes, Dash);
322 }
323
324 void wxPen::SetStipple(const wxBitmap& Stipple)
325 {
326     AllocExclusive();
327     M_PENDATA->SetStipple(Stipple);
328 }
329
330 wxColour wxPen::GetColour() const
331 {
332     return (M_PENDATA ? M_PENDATA->m_colour : wxNullColour);
333 }
334
335 int wxPen::GetWidth() const
336 {
337     return (M_PENDATA ? M_PENDATA->m_width : 0);
338 }
339
340 int wxPen::GetStyle() const
341 {
342     return (M_PENDATA ? M_PENDATA->m_style : 0);
343 }
344
345 int wxPen::GetJoin() const
346 {
347     return (M_PENDATA ? M_PENDATA->m_join : 0);
348 }
349
350 int wxPen::GetCap() const
351 {
352     return (M_PENDATA ? M_PENDATA->m_cap : 0);
353 }
354
355 int wxPen::GetDashes(wxDash **ptr) const
356 {
357     *ptr = (M_PENDATA ? M_PENDATA->m_dash : (wxDash*) NULL); return (M_PENDATA ? M_PENDATA->m_nbDash : 0);
358 }
359
360 wxBitmap *wxPen::GetStipple() const
361 {
362     return (M_PENDATA ? (& M_PENDATA->m_stipple) : (wxBitmap*) NULL);
363 }
364
365 WX_NSColor wxPen::GetNSColor()
366 {
367     return (M_PENDATA ? M_PENDATA->GetNSColor() : nil);
368 }
369
370 int wxPen::GetCocoaLineDash(const CGFloat **pattern)
371 {
372     if(M_PENDATA)
373         return M_PENDATA->GetCocoaLineDash(pattern);
374     if(pattern)
375         *pattern = NULL;
376     return 0;
377 }