COW cleanup patch (1583966):
[wxWidgets.git] / src / msw / brush.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/brush.cpp
3 // Purpose: wxBrush
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #include "wx/brush.h"
28
29 #ifndef WX_PRECOMP
30 #include "wx/list.h"
31 #include "wx/utils.h"
32 #include "wx/app.h"
33 #endif // WX_PRECOMP
34
35 #include "wx/msw/private.h"
36
37 // ----------------------------------------------------------------------------
38 // private classes
39 // ----------------------------------------------------------------------------
40
41 class WXDLLEXPORT wxBrushRefData: public wxGDIRefData
42 {
43 public:
44 wxBrushRefData(const wxColour& colour = wxNullColour, int style = wxSOLID);
45 wxBrushRefData(const wxBitmap& stipple);
46 wxBrushRefData(const wxBrushRefData& data);
47 virtual ~wxBrushRefData();
48
49 bool operator==(const wxBrushRefData& data) const;
50
51 HBRUSH GetHBRUSH();
52 void Free();
53
54 const wxColour& GetColour() const { return m_colour; }
55 int GetStyle() const { return m_style; }
56 wxBitmap *GetStipple() { return &m_stipple; }
57
58 void SetColour(const wxColour& colour) { Free(); m_colour = colour; }
59 void SetStyle(int style) { Free(); m_style = style; }
60 void SetStipple(const wxBitmap& stipple) { Free(); DoSetStipple(stipple); }
61
62 private:
63 void DoSetStipple(const wxBitmap& stipple);
64
65 int m_style;
66 wxBitmap m_stipple;
67 wxColour m_colour;
68 HBRUSH m_hBrush;
69
70 // no assignment operator, the objects of this class are shared and never
71 // assigned after being created once
72 wxBrushRefData& operator=(const wxBrushRefData&);
73 };
74
75 #define M_BRUSHDATA ((wxBrushRefData *)m_refData)
76
77 // ============================================================================
78 // wxBrushRefData implementation
79 // ============================================================================
80
81 IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
82
83 // ----------------------------------------------------------------------------
84 // wxBrushRefData ctors/dtor
85 // ----------------------------------------------------------------------------
86
87 wxBrushRefData::wxBrushRefData(const wxColour& colour, int style)
88 : m_colour(colour)
89 {
90 m_style = style;
91
92 m_hBrush = NULL;
93 }
94
95 wxBrushRefData::wxBrushRefData(const wxBitmap& stipple)
96 {
97 DoSetStipple(stipple);
98
99 m_hBrush = NULL;
100 }
101
102 wxBrushRefData::wxBrushRefData(const wxBrushRefData& data)
103 : wxGDIRefData(),
104 m_stipple(data.m_stipple),
105 m_colour(data.m_colour)
106 {
107 m_style = data.m_style;
108
109 // we can't share HBRUSH, we'd need to create another one ourselves
110 m_hBrush = NULL;
111 }
112
113 wxBrushRefData::~wxBrushRefData()
114 {
115 Free();
116 }
117
118 // ----------------------------------------------------------------------------
119 // wxBrushRefData accesors
120 // ----------------------------------------------------------------------------
121
122 bool wxBrushRefData::operator==(const wxBrushRefData& data) const
123 {
124 // don't compare HBRUSHes
125 return m_style == data.m_style &&
126 m_colour == data.m_colour &&
127 m_stipple.IsRefTo(&data.m_stipple);
128 }
129
130 void wxBrushRefData::DoSetStipple(const wxBitmap& stipple)
131 {
132 m_stipple = stipple;
133 m_style = stipple.GetMask() ? wxSTIPPLE_MASK_OPAQUE : wxSTIPPLE;
134 }
135
136 // ----------------------------------------------------------------------------
137 // wxBrushRefData resource handling
138 // ----------------------------------------------------------------------------
139
140 void wxBrushRefData::Free()
141 {
142 if ( m_hBrush )
143 {
144 ::DeleteObject(m_hBrush);
145
146 m_hBrush = NULL;
147 }
148 }
149
150 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
151
152 static int TranslateHatchStyle(int style)
153 {
154 switch ( style )
155 {
156 case wxBDIAGONAL_HATCH: return HS_BDIAGONAL;
157 case wxCROSSDIAG_HATCH: return HS_DIAGCROSS;
158 case wxFDIAGONAL_HATCH: return HS_FDIAGONAL;
159 case wxCROSS_HATCH: return HS_CROSS;
160 case wxHORIZONTAL_HATCH:return HS_HORIZONTAL;
161 case wxVERTICAL_HATCH: return HS_VERTICAL;
162 default: return -1;
163 }
164 }
165
166 #endif // !__WXMICROWIN__ && !__WXWINCE__
167
168 HBRUSH wxBrushRefData::GetHBRUSH()
169 {
170 if ( !m_hBrush )
171 {
172 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
173 int hatchStyle = TranslateHatchStyle(m_style);
174 if ( hatchStyle == -1 )
175 #endif // !__WXMICROWIN__ && !__WXWINCE__
176 {
177 switch ( m_style )
178 {
179 case wxTRANSPARENT:
180 m_hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
181 break;
182
183 case wxSTIPPLE:
184 m_hBrush = ::CreatePatternBrush(GetHbitmapOf(m_stipple));
185 break;
186
187 case wxSTIPPLE_MASK_OPAQUE:
188 m_hBrush = ::CreatePatternBrush((HBITMAP)m_stipple.GetMask()
189 ->GetMaskBitmap());
190 break;
191
192 default:
193 wxFAIL_MSG( _T("unknown brush style") );
194 // fall through
195
196 case wxSOLID:
197 m_hBrush = ::CreateSolidBrush(m_colour.GetPixel());
198 break;
199 }
200 }
201 #ifndef __WXWINCE__
202 else // create a hatched brush
203 {
204 m_hBrush = ::CreateHatchBrush(hatchStyle, m_colour.GetPixel());
205 }
206 #endif
207
208 if ( !m_hBrush )
209 {
210 wxLogLastError(_T("CreateXXXBrush()"));
211 }
212 }
213
214 return m_hBrush;
215 }
216
217 // ============================================================================
218 // wxBrush implementation
219 // ============================================================================
220
221 // ----------------------------------------------------------------------------
222 // wxBrush ctors/dtor
223 // ----------------------------------------------------------------------------
224
225 wxBrush::wxBrush()
226 {
227 }
228
229 wxBrush::wxBrush(const wxColour& col, int style)
230 {
231 m_refData = new wxBrushRefData(col, style);
232 }
233
234 wxBrush::wxBrush(const wxBitmap& stipple)
235 {
236 m_refData = new wxBrushRefData(stipple);
237 }
238
239 wxBrush::~wxBrush()
240 {
241 }
242
243 // ----------------------------------------------------------------------------
244 // wxBrush house keeping stuff
245 // ----------------------------------------------------------------------------
246
247 bool wxBrush::operator==(const wxBrush& brush) const
248 {
249 const wxBrushRefData *brushData = (wxBrushRefData *)brush.m_refData;
250
251 // an invalid brush is considered to be only equal to another invalid brush
252 return m_refData ? (brushData && *M_BRUSHDATA == *brushData) : !brushData;
253 }
254
255 wxObjectRefData *wxBrush::CreateRefData() const
256 {
257 return new wxBrushRefData;
258 }
259
260 wxObjectRefData *wxBrush::CloneRefData(const wxObjectRefData *data) const
261 {
262 return new wxBrushRefData(*(const wxBrushRefData *)data);
263 }
264
265 // ----------------------------------------------------------------------------
266 // wxBrush accessors
267 // ----------------------------------------------------------------------------
268
269 wxColour wxBrush::GetColour() const
270 {
271 wxCHECK_MSG( Ok(), wxNullColour, _T("invalid brush") );
272
273 return M_BRUSHDATA->GetColour();
274 }
275
276 int wxBrush::GetStyle() const
277 {
278 wxCHECK_MSG( Ok(), 0, _T("invalid brush") );
279
280 return M_BRUSHDATA->GetStyle();
281 }
282
283 wxBitmap *wxBrush::GetStipple() const
284 {
285 wxCHECK_MSG( Ok(), NULL, _T("invalid brush") );
286
287 return M_BRUSHDATA->GetStipple();
288 }
289
290 WXHANDLE wxBrush::GetResourceHandle() const
291 {
292 wxCHECK_MSG( Ok(), FALSE, _T("invalid brush") );
293
294 return (WXHANDLE)M_BRUSHDATA->GetHBRUSH();
295 }
296
297 // ----------------------------------------------------------------------------
298 // wxBrush setters
299 // ----------------------------------------------------------------------------
300
301 void wxBrush::SetColour(const wxColour& col)
302 {
303 AllocExclusive();
304
305 M_BRUSHDATA->SetColour(col);
306 }
307
308 void wxBrush::SetColour(unsigned char r, unsigned char g, unsigned char b)
309 {
310 AllocExclusive();
311
312 M_BRUSHDATA->SetColour(wxColour(r, g, b));
313 }
314
315 void wxBrush::SetStyle(int style)
316 {
317 AllocExclusive();
318
319 M_BRUSHDATA->SetStyle(style);
320 }
321
322 void wxBrush::SetStipple(const wxBitmap& stipple)
323 {
324 AllocExclusive();
325
326 M_BRUSHDATA->SetStipple(stipple);
327 }