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