Motif: made file selector and message box properly take on background colour.
[wxWidgets.git] / src / motif / dc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dc.cpp
3 // Purpose: wxDC class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "dc.h"
14 #endif
15
16 #include "wx/dc.h"
17 #include "wx/dcmemory.h"
18 #include "wx/defs.h"
19
20 #if !USE_SHARED_LIBRARY
21 IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
22 #endif
23
24 //-----------------------------------------------------------------------------
25 // constants
26 //-----------------------------------------------------------------------------
27
28 #define mm2inches 0.0393700787402
29 #define inches2mm 25.4
30 #define mm2twips 56.6929133859
31 #define twips2mm 0.0176388888889
32 #define mm2pt 2.83464566929
33 #define pt2mm 0.352777777778
34
35 //-----------------------------------------------------------------------------
36 // wxDC
37 //-----------------------------------------------------------------------------
38
39 wxDC::wxDC()
40 {
41 m_ok = FALSE;
42
43 m_mm_to_pix_x = 1.0;
44 m_mm_to_pix_y = 1.0;
45
46 m_backgroundMode = wxTRANSPARENT;
47
48 m_isInteractive = FALSE;
49
50 m_internalDeviceOriginX = 0;
51 m_internalDeviceOriginY = 0;
52 m_externalDeviceOriginX = 0;
53 m_externalDeviceOriginY = 0;
54 }
55
56 void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y)
57 {
58 wxCHECK_RET( Ok(), "invalid dc" );
59 wxCHECK_RET( icon.Ok(), "invalid icon" );
60
61 DoDrawBitmap(icon, x, y, TRUE);
62 }
63
64 void wxDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y, bool useMask )
65 {
66 wxCHECK_RET( bitmap.Ok(), "invalid bitmap" );
67
68 wxMemoryDC memDC;
69 memDC.SelectObject(bitmap);
70
71 #if 0
72 // Not sure if we need this. The mask should leave the masked areas as per
73 // the original background of this DC.
74 if (useMask)
75 {
76 // There might be transparent areas, so make these the same colour as this
77 // DC
78 memDC.SetBackground(* GetBackground());
79 memDC.Clear();
80 }
81 #endif // 0
82
83 Blit(x, y, bitmap.GetWidth(), bitmap.GetHeight(), &memDC, 0, 0, wxCOPY, useMask);
84
85 memDC.SelectObject(wxNullBitmap);
86 }
87
88 void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
89 {
90 m_clipping = TRUE;
91 m_clipX1 = x;
92 m_clipY1 = y;
93 m_clipX2 = x + width;
94 m_clipY2 = y + height;
95 }
96
97 void wxDC::DestroyClippingRegion()
98 {
99 m_clipping = FALSE;
100 }
101
102 void wxDC::DoGetSize( int* width, int* height ) const
103 {
104 if ( width )
105 *width = m_maxX - m_minX;
106 if ( height )
107 *height = m_maxY - m_minY;
108 }
109
110 void wxDC::DoGetSizeMM( int* width, int* height ) const
111 {
112 int w, h;
113 GetSize( &w, &h );
114
115 if ( width )
116 *width = int( double(w) / (m_scaleX*m_mm_to_pix_x) );
117 if ( height )
118 *height = int( double(h) / (m_scaleY*m_mm_to_pix_y) );
119 }
120
121 // Resolution in pixels per logical inch
122 wxSize wxDC::GetPPI() const
123 {
124 // TODO (should probably be pure virtual)
125 return wxSize(0, 0);
126 }
127
128 void wxDC::SetMapMode( int mode )
129 {
130 switch (mode)
131 {
132 case wxMM_TWIPS:
133 SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
134 break;
135 case wxMM_POINTS:
136 SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
137 break;
138 case wxMM_METRIC:
139 SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
140 break;
141 case wxMM_LOMETRIC:
142 SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
143 break;
144 default:
145 case wxMM_TEXT:
146 SetLogicalScale( 1.0, 1.0 );
147 break;
148 }
149 if (mode != wxMM_TEXT)
150 {
151 m_needComputeScaleX = TRUE;
152 m_needComputeScaleY = TRUE;
153 }
154 }
155
156 void wxDC::SetUserScale( double x, double y )
157 {
158 // allow negative ? -> no
159 m_userScaleX = x;
160 m_userScaleY = y;
161 ComputeScaleAndOrigin();
162 }
163
164 void wxDC::SetLogicalScale( double x, double y )
165 {
166 // allow negative ?
167 m_logicalScaleX = x;
168 m_logicalScaleY = y;
169 ComputeScaleAndOrigin();
170 }
171
172 void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
173 {
174 m_logicalOriginX = x * m_signX; // is this still correct ?
175 m_logicalOriginY = y * m_signY;
176 ComputeScaleAndOrigin();
177 }
178
179 void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y )
180 {
181 m_externalDeviceOriginX = x;
182 m_externalDeviceOriginY = y;
183 ComputeScaleAndOrigin();
184 }
185
186 void wxDC::SetInternalDeviceOrigin( wxCoord x, wxCoord y )
187 {
188 m_internalDeviceOriginX = x;
189 m_internalDeviceOriginY = y;
190 ComputeScaleAndOrigin();
191 }
192
193 void wxDC::GetInternalDeviceOrigin( wxCoord *x, wxCoord *y )
194 {
195 if (x) *x = m_internalDeviceOriginX;
196 if (y) *y = m_internalDeviceOriginY;
197 }
198
199 void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
200 {
201 m_signX = xLeftRight ? 1 : -1;
202 m_signY = yBottomUp ? -1 : 1;
203 ComputeScaleAndOrigin();
204 }
205
206 wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
207 {
208 return ((wxDC *)this)->XDEV2LOG(x);
209 }
210
211 wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
212 {
213 return ((wxDC *)this)->YDEV2LOG(y);
214 }
215
216 wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
217 {
218 return ((wxDC *)this)->XDEV2LOGREL(x);
219 }
220
221 wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
222 {
223 return ((wxDC *)this)->YDEV2LOGREL(y);
224 }
225
226 wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
227 {
228 return ((wxDC *)this)->XLOG2DEV(x);
229 }
230
231 wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
232 {
233 return ((wxDC *)this)->YLOG2DEV(y);
234 }
235
236 wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
237 {
238 return ((wxDC *)this)->XLOG2DEVREL(x);
239 }
240
241 wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
242 {
243 return ((wxDC *)this)->YLOG2DEVREL(y);
244 }
245
246 void wxDC::ComputeScaleAndOrigin()
247 {
248 // CMB: copy scale to see if it changes
249 double origScaleX = m_scaleX;
250 double origScaleY = m_scaleY;
251
252 m_scaleX = m_logicalScaleX * m_userScaleX;
253 m_scaleY = m_logicalScaleY * m_userScaleY;
254
255 m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
256 m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
257
258 // CMB: if scale has changed call SetPen to recalulate the line width
259 if (m_scaleX != origScaleX || m_scaleY != origScaleY)
260 {
261 // this is a bit artificial, but we need to force wxDC to think
262 // the pen has changed
263 wxPen* pen = & GetPen();
264 wxPen tempPen;
265 m_pen = tempPen;
266 SetPen(* pen);
267 }
268 }
269