]> git.saurik.com Git - wxWidgets.git/blame - src/os2/brush.cpp
Refactor owner-drawing code.
[wxWidgets.git] / src / os2 / brush.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
46562151 2// Name: src/os2/brush.cpp
0e320a79 3// Purpose: wxBrush
37f214d5 4// Author: David Webster
0e320a79 5// Modified by:
37f214d5 6// Created: 10/13/99
0e320a79 7// RCS-ID: $Id$
37f214d5 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
37f214d5
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
0e320a79 14
37f214d5 15#ifndef WX_PRECOMP
8ecff181
WS
16 #include <stdio.h>
17 #include "wx/list.h"
18 #include "wx/utils.h"
19 #include "wx/app.h"
20 #include "wx/brush.h"
21 #include "wx/log.h"
37f214d5
DW
22#endif
23
24#include "wx/os2/private.h"
25
1aca6611
SN
26class WXDLLEXPORT wxBrushRefData: public wxGDIRefData
27{
28 friend class WXDLLIMPEXP_FWD_CORE wxBrush;
29public:
30 wxBrushRefData(const wxColour& colour = wxNullColour, wxBrushStyle style = wxBRUSHSTYLE_SOLID);
31 wxBrushRefData(const wxBitmap& stipple);
32 wxBrushRefData(const wxBrushRefData& rData);
33 virtual ~wxBrushRefData();
34
35 bool operator == (const wxBrushRefData& data) const
36 {
37 return (m_nStyle == data.m_nStyle &&
38 m_vStipple.IsSameAs(data.m_vStipple) &&
39 m_vColour == data.m_vColour);
40 }
41
42protected:
43 wxBrushStyle m_nStyle;
44 wxBitmap m_vStipple;
45 wxColour m_vColour;
46 WXHBRUSH m_hBrush; // in OS/2 GPI this will be the PS the pen is associated with
47 AREABUNDLE m_vBundle;
48};
49
50#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
51
52// ============================================================================
53// wxBrushRefData implementation
54// ============================================================================
0e320a79 55
0e320a79 56IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
0e320a79 57
1aca6611
SN
58// ----------------------------------------------------------------------------
59// wxBrushRefData ctors/dtor
60// ----------------------------------------------------------------------------
61
62wxBrushRefData::wxBrushRefData(const wxColour& colour, wxBrushStyle style)
63 : m_vColour(colour)
0e320a79 64{
1aca6611 65 m_nStyle = style;
37f214d5 66 m_hBrush = 0;
15f03b25
DW
67 memset(&m_vBundle, '\0', sizeof(AREABUNDLE));
68} // end of wxBrushRefData::wxBrushRefData
0e320a79 69
1aca6611
SN
70wxBrushRefData::wxBrushRefData(const wxBitmap& stipple)
71{
72 m_vStipple = stipple;
73 m_nStyle = stipple.GetMask() ? wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE
74 : wxBRUSHSTYLE_STIPPLE;
75
76 m_hBrush = NULL;
77 memset(&m_vBundle, '\0', sizeof(AREABUNDLE));
78}
79
8ecff181 80wxBrushRefData::wxBrushRefData(const wxBrushRefData& rData)
1aca6611
SN
81 : wxGDIRefData(),
82 m_vStipple(rData.m_vStipple),
83 m_vColour(rData.m_vColour)
0e320a79 84{
15f03b25 85 m_nStyle = rData.m_nStyle;
15f03b25
DW
86 m_hBrush = 0;
87 memcpy(&m_vBundle, &rData.m_vBundle, sizeof(AREABUNDLE));
88} // end of wxBrushRefData::wxBrushRefData
0e320a79
DW
89
90wxBrushRefData::~wxBrushRefData()
91{
15f03b25 92} // end of wxBrushRefData::~wxBrushRefData
0e320a79 93
1aca6611
SN
94// ============================================================================
95// wxBrush implementation
96// ============================================================================
97
98// ----------------------------------------------------------------------------
99// wxBrush ctors/dtor
100// ----------------------------------------------------------------------------
101
0e320a79
DW
102wxBrush::wxBrush()
103{
15f03b25 104} // end of wxBrush::wxBrush
0e320a79
DW
105
106wxBrush::~wxBrush()
107{
15f03b25 108} // end of wxBrush::~wxBrush
0e320a79 109
15f03b25
DW
110wxBrush::wxBrush(
111 const wxColour& rColour
3e6858cd 112, wxBrushStyle nStyle
15f03b25 113)
0e320a79 114{
1aca6611 115 m_refData = new wxBrushRefData(rColour, nStyle);
0e320a79
DW
116
117 RealizeResource();
15f03b25 118} // end of wxBrush::wxBrush
0e320a79 119
ac3688c0
FM
120#if FUTURE_WXWIN_COMPATIBILITY_3_0
121wxBrush::wxBrush(const wxColour& col, int style)
122{
1aca6611 123 m_refData = new wxBrushRefData(col, (wxBrushStyle)style);
ac3688c0
FM
124
125 RealizeResource();
126}
127#endif
128
8ecff181 129wxBrush::wxBrush(const wxBitmap& rStipple)
0e320a79 130{
1aca6611 131 m_refData = new wxBrushRefData(rStipple);
0e320a79
DW
132
133 RealizeResource();
15f03b25 134} // end of wxBrush::wxBrush
0e320a79 135
15f03b25 136bool wxBrush::RealizeResource()
37f214d5 137{
6670f564
WS
138 bool bOk;
139 ERRORID vError;
140 wxString sError;
15f03b25
DW
141
142 if (M_BRUSHDATA && M_BRUSHDATA->m_hBrush == 0L)
37f214d5 143 {
15f03b25
DW
144 SIZEL vSize = {0, 0};
145 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
146 HDC hDC = ::DevOpenDC( vHabmain
147 ,OD_MEMORY
148 ,"*"
149 ,5L
150 ,(PDEVOPENDATA)&vDop
151 ,NULLHANDLE
152 );
153 M_BRUSHDATA->m_hBrush = (WXHPEN)::GpiCreatePS( vHabmain
154 ,hDC
155 ,&vSize
156 ,PU_PELS | GPIT_MICRO | GPIA_ASSOC
157 );
158 }
159 if (M_BRUSHDATA)
160 {
161 //
162 // Set the color table to RGB mode
163 //
164 if (!::GpiCreateLogColorTable( (HPS)M_BRUSHDATA->m_hBrush
165 ,0L
166 ,LCOLF_RGB
167 ,0L
168 ,0L
169 ,NULL
170 ))
171 {
172 vError = ::WinGetLastError(vHabmain);
173 sError = wxPMErrorToStr(vError);
9a83f860 174 wxLogError(wxT("Unable to set current color table to RGB mode. Error: %s\n"), sError.c_str());
46562151 175 return false;
15f03b25
DW
176 }
177
178 if (M_BRUSHDATA->m_nStyle==wxTRANSPARENT)
37f214d5 179 {
6670f564 180 return true;
37f214d5 181 }
15f03b25 182 COLORREF vPmColour = 0L;
37f214d5 183
15f03b25 184 vPmColour = M_BRUSHDATA->m_vColour.GetPixel() ;
37f214d5 185
15f03b25
DW
186 M_BRUSHDATA->m_vBundle.usSet = LCID_DEFAULT;
187 switch (M_BRUSHDATA->m_nStyle)
37f214d5 188 {
15f03b25
DW
189 case wxTRANSPARENT:
190 M_BRUSHDATA->m_hBrush = NULL; // Must always select a suitable background brush
191 break; // - could choose white always for a quick solution
192
37f214d5 193 case wxBDIAGONAL_HATCH:
15f03b25
DW
194 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG3;
195 break;
37f214d5
DW
196
197 case wxCROSSDIAG_HATCH:
15f03b25
DW
198 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAGHATCH;
199 break;
37f214d5
DW
200
201 case wxFDIAGONAL_HATCH:
15f03b25
DW
202 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG1;
203 break;
37f214d5
DW
204
205 case wxCROSS_HATCH:
15f03b25
DW
206 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HATCH;
207 break;
37f214d5
DW
208
209 case wxHORIZONTAL_HATCH:
15f03b25
DW
210 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HORIZ;
211 break;
37f214d5
DW
212
213 case wxVERTICAL_HATCH:
15f03b25
DW
214 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_VERT;
215 break;
37f214d5
DW
216
217 case wxSTIPPLE:
15f03b25
DW
218 if (M_BRUSHDATA->m_vStipple.Ok())
219 {
220 ::GpiSetBitmapId( M_BRUSHDATA->m_hBrush
221 ,(USHORT)M_BRUSHDATA->m_vStipple.GetHBITMAP()
222 ,(USHORT)M_BRUSHDATA->m_vStipple.GetId()
223 );
224 ::GpiSetPatternSet( M_BRUSHDATA->m_hBrush
225 ,(USHORT)M_BRUSHDATA->m_vStipple.GetId()
226 );
227 }
37f214d5 228 else
15f03b25 229 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID;
37f214d5
DW
230 break ;
231
232 case wxSOLID:
233 default:
15f03b25 234 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID;
37f214d5
DW
235 break;
236 }
237#ifdef WXDEBUG_CREATE
238 if (M_BRUSHDATA->m_hBrush==NULL) wxError("Cannot create brush","Internal error") ;
239#endif
15f03b25 240 M_BRUSHDATA->m_vBundle.lColor = vPmColour;
8d854fa9 241 M_BRUSHDATA->m_vBundle.lBackColor = RGB_WHITE;
15f03b25
DW
242 M_BRUSHDATA->m_vBundle.usMixMode = FM_OVERPAINT;
243 M_BRUSHDATA->m_vBundle.usBackMixMode = BM_OVERPAINT;
244
6670f564
WS
245 bOk = (bool)::GpiSetAttrs( M_BRUSHDATA->m_hBrush
246 ,PRIM_AREA
247 ,ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE |
c9ab2da6
SN
248 ABB_SET | ABB_SYMBOL | ABB_REF_POINT
249 ,ABB_SET | ABB_SYMBOL | ABB_REF_POINT
6670f564
WS
250 ,&M_BRUSHDATA->m_vBundle
251 );
15f03b25
DW
252 if (!bOk)
253 {
254 vError = ::WinGetLastError(vHabmain);
255 sError = wxPMErrorToStr(vError);
9a83f860 256 wxLogError(wxT("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError.c_str());
15f03b25
DW
257 }
258 return bOk;
37f214d5 259 }
46562151 260 return false;
15f03b25 261} // end of wxBrush::RealizeResource
37f214d5 262
1aca6611
SN
263// ----------------------------------------------------------------------------
264// wxBrush accessors
265// ----------------------------------------------------------------------------
266
267wxColour wxBrush::GetColour() const
268{
9a83f860 269 wxCHECK_MSG( Ok(), wxNullColour, wxT("invalid brush") );
1aca6611
SN
270
271 return M_BRUSHDATA->m_vColour;
272}
273
274wxBrushStyle wxBrush::GetStyle() const
275{
9a83f860 276 wxCHECK_MSG( Ok(), wxBRUSHSTYLE_INVALID, wxT("invalid brush") );
1aca6611
SN
277
278 return M_BRUSHDATA->m_nStyle;
279}
280
281wxBitmap *wxBrush::GetStipple() const
282{
9a83f860 283 wxCHECK_MSG( Ok(), NULL, wxT("invalid brush") );
1aca6611
SN
284
285 return &(M_BRUSHDATA->m_vStipple);
286}
287
288int wxBrush::GetPS() const
289{
9a83f860 290 wxCHECK_MSG( Ok(), 0, wxT("invalid brush") );
1aca6611
SN
291
292 return M_BRUSHDATA->m_hBrush;
293}
294
17b1d76b 295WXHANDLE wxBrush::GetResourceHandle() const
37f214d5 296{
9a83f860 297 wxCHECK_MSG( Ok(), 0, wxT("invalid brush") );
1aca6611 298
15f03b25
DW
299 return (WXHANDLE)M_BRUSHDATA->m_hBrush;
300} // end of wxBrush::GetResourceHandle
301
6670f564 302bool wxBrush::FreeResource( bool WXUNUSED(bForce) )
37f214d5
DW
303{
304 if (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush != 0))
305 {
37f214d5 306 M_BRUSHDATA->m_hBrush = 0;
6670f564 307 return true;
37f214d5 308 }
46562151 309 else return false;
15f03b25 310} // end of wxBrush::FreeResource
37f214d5
DW
311
312bool wxBrush::IsFree() const
313{
314 return (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush == 0));
15f03b25 315} // end of wxBrush::IsFree
37f214d5 316
1aca6611
SN
317// ----------------------------------------------------------------------------
318// wxBrush setters
319// ----------------------------------------------------------------------------
320
46562151 321void wxBrush::SetColour( const wxColour& rColour )
0e320a79 322{
4b3f61d1 323 AllocExclusive();
15f03b25 324 M_BRUSHDATA->m_vColour = rColour;
0e320a79
DW
325 RealizeResource();
326}
327
1a1498c0 328void wxBrush::SetColour(unsigned char cRed, unsigned char cGreen, unsigned char cBlue)
0e320a79 329{
4b3f61d1 330 AllocExclusive();
46562151 331 M_BRUSHDATA->m_vColour.Set( cRed, cGreen, cBlue );
0e320a79 332 RealizeResource();
15f03b25 333} // end of wxBrush::SetColour
0e320a79 334
3e6858cd 335void wxBrush::SetStyle(wxBrushStyle nStyle)
0e320a79 336{
4b3f61d1 337 AllocExclusive();
15f03b25 338 M_BRUSHDATA->m_nStyle = nStyle;
0e320a79 339 RealizeResource();
15f03b25 340} // end of wxBrush::SetStyle
0e320a79 341
15f03b25
DW
342void wxBrush::SetStipple(
343 const wxBitmap& rStipple
344)
0e320a79 345{
4b3f61d1 346 AllocExclusive();
15f03b25
DW
347 M_BRUSHDATA->m_vStipple = rStipple;
348 RealizeResource();
349} // end of wxBrush::SetStipple
0e320a79 350
15f03b25
DW
351void wxBrush::SetPS(
352 HPS hPS
353)
354{
4b3f61d1 355 AllocExclusive();
15f03b25
DW
356 if (M_BRUSHDATA->m_hBrush)
357 ::GpiDestroyPS(M_BRUSHDATA->m_hBrush);
358 M_BRUSHDATA->m_hBrush = hPS;
0e320a79 359 RealizeResource();
15f03b25 360} // end of WxWinGdi_CPen::SetPS
7aa920b5 361
1aca6611
SN
362// ----------------------------------------------------------------------------
363// wxBrush house keeping stuff
364// ----------------------------------------------------------------------------
7aa920b5
VZ
365
366bool wxBrush::operator == (
367 const wxBrush& brush
368) const
369{
370 if (m_refData == brush.m_refData) return true;
371
372 if (!m_refData || !brush.m_refData) return false;
373
374 return ( *(wxBrushRefData*)m_refData == *(wxBrushRefData*)brush.m_refData );
375} // end of wxBrush::operator ==
376
4b3f61d1
SN
377wxGDIRefData *wxBrush::CreateGDIRefData() const
378{
379 return new wxBrushRefData;
380}
381
382wxGDIRefData *wxBrush::CloneGDIRefData(const wxGDIRefData *data) const
383{
384 return new wxBrushRefData(*(const wxBrushRefData *)data);
385}