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