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