1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/cocoa/brush.mm
3// Purpose:     wxBrush
4// Author:      David Elliott <dfe@cox.net>
5// Modified by:
6// Created:     2003/07/03
7// Copyright:   (c) 2003 David Elliott
8// Licence:     wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
13#include "wx/brush.h"
14
15#ifndef WX_PRECOMP
16    #include "wx/utils.h"
17    #include "wx/colour.h"
18#endif //WX_PRECOMP
19
20#import <AppKit/NSColor.h>
21
22class WXDLLEXPORT wxBrushRefData: public wxGDIRefData
23{
24public:
25    wxBrushRefData(const wxColour& colour = wxNullColour,
26                   wxBrushStyle style = wxBRUSHSTYLE_SOLID);
27    wxBrushRefData(const wxBitmap& stipple);
28    wxBrushRefData(const wxBrushRefData& data);
29    virtual ~wxBrushRefData();
30
31    WX_NSColor GetNSColor();
32    void Free();
33
34    bool operator==(const wxBrushRefData& data) const;
35
36    // accessors
37    const wxColour& GetColour() const { return m_colour; }
38    wxBrushStyle GetStyle() const { return m_style; }
39    wxBitmap *GetStipple() { return &m_stipple; }
40
41    void SetColour(const wxColour& colour) { Free(); m_colour = colour; }
42    void SetStyle(wxBrushStyle style) { Free(); m_style = style; }
43    void SetStipple(const wxBitmap& stipple) { Free(); DoSetStipple(stipple); }
44
45private:
46    void DoSetStipple(const wxBitmap& stipple);
47
48    WX_NSColor    m_cocoaNSColor;
49    wxBrushStyle  m_style;
50    wxBitmap      m_stipple;
51    wxColour      m_colour;
52
53    // no assignment operator, the objects of this class are shared and never
54    // assigned after being created once
55    wxBrushRefData& operator=(const wxBrushRefData&);
56};
57
58#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
59IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
60
61wxBrushRefData::wxBrushRefData(const wxColour& colour, wxBrushStyle style)
62{
63    m_cocoaNSColor = NULL;
64    m_style = style;
65    m_colour = colour;
66}
67
68wxBrushRefData::wxBrushRefData(const wxBitmap& stipple)
69{
70    m_cocoaNSColor = NULL;
71    DoSetStipple(stipple);
72}
73
74wxBrushRefData::wxBrushRefData(const wxBrushRefData& data)
75{
76    m_cocoaNSColor = data.m_cocoaNSColor;
77    [m_cocoaNSColor retain];
78    m_style = data.m_style;
79    m_stipple = data.m_stipple;
80    m_colour = data.m_colour;
81}
82
83wxBrushRefData::~wxBrushRefData()
84{
85    Free();
86}
87
88void wxBrushRefData::Free()
89{
90    [m_cocoaNSColor release];
91    m_cocoaNSColor = NULL;
92}
93
94bool wxBrushRefData::operator==(const wxBrushRefData& data) const
95{
96    // don't compare our NSColor
97    return m_style == data.m_style &&
98           m_colour == data.m_colour &&
99           m_stipple.IsSameAs(data.m_stipple);
100}
101
102void wxBrushRefData::DoSetStipple(const wxBitmap& stipple)
103{
104    m_stipple = stipple;
105    m_style = stipple.GetMask() ? wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE
106                                : wxBRUSHSTYLE_STIPPLE;
107}
108
109WX_NSColor wxBrushRefData::GetNSColor()
110{
111    if(!m_cocoaNSColor)
112    {
113        switch( m_style )
114        {
115        case wxTRANSPARENT:
116            m_cocoaNSColor = [[NSColor clearColor] retain];
117            break;
118        case wxSTIPPLE:
119//  wxBitmap isn't implemented yet
120//            m_cocoaNSColor = [[NSColor colorWithPatternImage: m_stipple.GetNSImage()] retain];
121//            break;
122        case wxSTIPPLE_MASK_OPAQUE:
123            // This should be easy when wxBitmap works.
124//            break;
125        // The hatch brushes are going to be tricky
126        case wxBDIAGONAL_HATCH:
127        case wxCROSSDIAG_HATCH:
128        case wxFDIAGONAL_HATCH:
129        case wxCROSS_HATCH:
130        case wxHORIZONTAL_HATCH:
131        case wxVERTICAL_HATCH:
132        default:
133        case wxSOLID:
134            NSColor *colour_NSColor = m_colour.GetNSColor();
135            if(!colour_NSColor)
136                colour_NSColor = [NSColor clearColor];
137            m_cocoaNSColor = [colour_NSColor copyWithZone:nil];
138            break;
139        }
140    }
141    return m_cocoaNSColor;
142}
143
144// Brushes
145wxBrush::wxBrush()
146{
147}
148
149wxBrush::~wxBrush()
150{
151}
152
153wxBrush::wxBrush(const wxColour& col, wxBrushStyle style)
154{
155    m_refData = new wxBrushRefData(col, style);
156}
157
158wxBrush::wxBrush(const wxColour& col, int style)
159{
160    m_refData = new wxBrushRefData(col, (wxBrushStyle)style);
161}
162
163wxBrush::wxBrush(const wxBitmap& stipple)
164{
165    m_refData = new wxBrushRefData(stipple);
166}
167
168wxGDIRefData *wxBrush::CreateGDIRefData() const
169{
170    return new wxBrushRefData;
171}
172
173wxGDIRefData *wxBrush::CloneGDIRefData(const wxGDIRefData *data) const
174{
175    return new wxBrushRefData(*(wxBrushRefData *)data);
176}
177
178void wxBrush::SetColour(const wxColour& col)
179{
180    AllocExclusive();
181    M_BRUSHDATA->SetColour(col);
182}
183
184void wxBrush::SetColour(unsigned char r, unsigned char g, unsigned char b)
185{
186    AllocExclusive();
187    M_BRUSHDATA->SetColour(wxColour(r,g,b));
188}
189
190void wxBrush::SetStyle(wxBrushStyle style)
191{
192    AllocExclusive();
193    M_BRUSHDATA->SetStyle(style);
194}
195
196void wxBrush::SetStipple(const wxBitmap& stipple)
197{
198    AllocExclusive();
199    M_BRUSHDATA->SetStipple(stipple);
200}
201
202wxColour wxBrush::GetColour() const
203{
204    wxCHECK_MSG( IsOk(), wxNullColour, wxT("invalid brush") );
205    return M_BRUSHDATA->GetColour();
206}
207
208wxBrushStyle wxBrush::GetStyle() const
209{
210    wxCHECK_MSG( IsOk(), wxBRUSHSTYLE_INVALID, wxT("invalid brush") );
211    return M_BRUSHDATA->GetStyle();
212}
213
214wxBitmap *wxBrush::GetStipple() const
215{
216    wxCHECK_MSG( IsOk(), 0, wxT("invalid brush") );
217    return M_BRUSHDATA->GetStipple();
218}
219
220WX_NSColor wxBrush::GetNSColor()
221{
222    if(!m_refData)
223        return [NSColor clearColor];
224    return M_BRUSHDATA->GetNSColor();
225}
226