]> git.saurik.com Git - wxWidgets.git/blame - src/palmos/dcclient.cpp
Implement support for gradient stops for OS X.
[wxWidgets.git] / src / palmos / dcclient.cpp
CommitLineData
ffecfa5a 1/////////////////////////////////////////////////////////////////////////////
e2731512 2// Name: src/palmos/dcclient.cpp
ffecfa5a 3// Purpose: wxClientDC class
e2731512 4// Author: William Osborne - minimal working wxPalmOS port
ffecfa5a
JS
5// Modified by:
6// Created: 10/13/04
e2731512 7// RCS-ID: $Id$
ffecfa5a
JS
8// Copyright: (c) William Osborne
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
ffecfa5a
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
df91131c 27#include "wx/dcclient.h"
e2fc40b4 28#include "wx/palmos/dcclient.h"
df91131c
WS
29
30#ifndef WX_PRECOMP
31 #include "wx/string.h"
e4db172a 32 #include "wx/log.h"
cdccdfab 33 #include "wx/window.h"
df91131c
WS
34#endif
35
ffecfa5a
JS
36// ----------------------------------------------------------------------------
37// array/list types
38// ----------------------------------------------------------------------------
39
40struct WXDLLEXPORT wxPaintDCInfo
41{
e2fc40b4 42 wxPaintDCInfo(wxWindow *win, wxPaintDCImpl *dc)
ffecfa5a 43 {
e2fc40b4
VZ
44 hwnd = win->GetHWND();
45 hdc = dc->GetHDC();
46 count = 1;
ffecfa5a
JS
47 }
48
e2fc40b4
VZ
49 WXHWND hwnd; // window for this DC
50 WXHDC hdc; // the DC handle
51 size_t count; // usage count
ffecfa5a
JS
52};
53
54#include "wx/arrimpl.cpp"
55
e2fc40b4 56WX_DEFINE_OBJARRAY(wxArrayDCInfo)
ffecfa5a 57
ffecfa5a
JS
58// ===========================================================================
59// implementation
60// ===========================================================================
61
62// ----------------------------------------------------------------------------
e2fc40b4 63// wxWindowDCImpl
ffecfa5a
JS
64// ----------------------------------------------------------------------------
65
e2fc40b4
VZ
66IMPLEMENT_ABSTRACT_CLASS(wxWindowDCImpl, wxPalmDCImpl)
67
68wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) :
69 wxPalmDCImpl( owner )
ffecfa5a
JS
70{
71}
72
e2fc40b4
VZ
73wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *window ) :
74 wxPalmDCImpl( owner )
ffecfa5a 75{
9a83f860 76 wxCHECK_RET( window, wxT("invalid window in wxWindowDCImpl") );
ffecfa5a
JS
77}
78
e2fc40b4 79void wxWindowDCImpl::InitDC()
ffecfa5a 80{
e2fc40b4
VZ
81
82 // since we are a window dc we need to grab the palette from the window
83#if wxUSE_PALETTE
84 InitializePalette();
85#endif
ffecfa5a
JS
86}
87
e2fc40b4 88void wxWindowDCImpl::DoGetSize(int *width, int *height) const
ffecfa5a 89{
9a83f860 90 wxCHECK_RET( m_window, wxT("wxWindowDCImpl without a window?") );
e2fc40b4
VZ
91
92 m_window->GetSize(width, height);
ffecfa5a
JS
93}
94
95// ----------------------------------------------------------------------------
e2fc40b4 96// wxClientDCImpl
ffecfa5a
JS
97// ----------------------------------------------------------------------------
98
e2fc40b4
VZ
99IMPLEMENT_ABSTRACT_CLASS(wxClientDCImpl, wxWindowDCImpl)
100
101wxClientDCImpl::wxClientDCImpl( wxDC *owner ) :
102 wxWindowDCImpl( owner )
ffecfa5a
JS
103{
104}
105
e2fc40b4
VZ
106wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *window ) :
107 wxWindowDCImpl( owner )
ffecfa5a
JS
108{
109}
110
e2fc40b4 111void wxClientDCImpl::InitDC()
ffecfa5a 112{
e2fc40b4
VZ
113 wxWindowDCImpl::InitDC();
114
115 // in wxUniv build we must manually do some DC adjustments usually
116 // performed by Windows for us
117 //
118 // we also need to take the menu/toolbar manually into account under
119 // Windows CE because they're just another control there, not anything
120 // special as usually under Windows
121#if defined(__WXUNIVERSAL__) || defined(__WXWINCE__)
122 wxPoint ptOrigin = m_window->GetClientAreaOrigin();
123 if ( ptOrigin.x || ptOrigin.y )
124 {
125 // no need to shift DC origin if shift is null
126 SetDeviceOrigin(ptOrigin.x, ptOrigin.y);
127 }
128
129 // clip the DC to avoid overwriting the non client area
130 SetClippingRegion(wxPoint(0,0), m_window->GetClientSize());
131#endif // __WXUNIVERSAL__ || __WXWINCE__
ffecfa5a
JS
132}
133
e2fc40b4 134wxClientDCImpl::~wxClientDCImpl()
ffecfa5a
JS
135{
136}
137
e2fc40b4 138void wxClientDCImpl::DoGetSize(int *width, int *height) const
ffecfa5a 139{
9a83f860 140 wxCHECK_RET( m_window, wxT("wxClientDCImpl without a window?") );
e2fc40b4
VZ
141
142 m_window->GetClientSize(width, height);
ffecfa5a
JS
143}
144
145// ----------------------------------------------------------------------------
e2fc40b4 146// wxPaintDCImpl
ffecfa5a
JS
147// ----------------------------------------------------------------------------
148
e2fc40b4
VZ
149// VZ: initial implementation (by JACS) only remembered the last wxPaintDC
150// created and tried to reuse it - this was supposed to take care of a
151// situation when a derived class OnPaint() calls base class OnPaint()
152// because in this case ::BeginPaint() shouldn't be called second time.
153//
154// I'm not sure how useful this is, however we must remember the HWND
155// associated with the last HDC as well - otherwise we may (and will!) try
156// to reuse the HDC for another HWND which is a nice recipe for disaster.
157//
158// So we store a list of windows for which we already have the DC and not
159// just one single hDC. This seems to work, but I'm really not sure about
160// the usefullness of the whole idea - IMHO it's much better to not call
161// base class OnPaint() at all, or, if we really want to allow it, add a
162// "wxPaintDC *" parameter to wxPaintEvent which should be used if it's
163// !NULL instead of creating a new DC.
164
165IMPLEMENT_ABSTRACT_CLASS(wxPaintDCImpl, wxClientDCImpl)
166
167wxArrayDCInfo wxPaintDCImpl::ms_cache;
168
169wxPaintDCImpl::wxPaintDCImpl( wxDC *owner ) :
170 wxClientDCImpl( owner )
ffecfa5a
JS
171{
172}
173
e2fc40b4
VZ
174wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *window ) :
175 wxClientDCImpl( owner )
ffecfa5a 176{
e2fc40b4 177 wxCHECK_RET( window, wxT("NULL canvas in wxPaintDCImpl ctor") );
ffecfa5a 178
e2fc40b4
VZ
179 m_window = window;
180
181 // do we have a DC for this window in the cache?
182 wxPaintDCInfo *info = FindInCache();
183 if ( info )
184 {
185 m_hDC = info->hdc;
186 info->count++;
187 }
188 else // not in cache, create a new one
189 {
190 //m_hDC = (WXHDC)::BeginPaint(GetHwndOf(m_window), &g_paintStruct);
191 if (m_hDC)
192 ms_cache.Add(new wxPaintDCInfo(m_window, this));
193 }
194
195 // Note: at this point m_hDC can be NULL under MicroWindows, when dragging.
196 if (!GetHDC())
197 return;
198
199 // (re)set the DC parameters.
200 InitDC();
201
202 // the HDC can have a clipping box (which we didn't set), make sure our
203 // DoGetClippingBox() checks for it
204 m_clipping = true;
ffecfa5a
JS
205}
206
e2fc40b4 207wxPaintDCImpl::~wxPaintDCImpl()
ffecfa5a 208{
e2fc40b4
VZ
209 if ( m_hDC )
210 {
211 SelectOldObjects(m_hDC);
212
213 size_t index;
214 wxPaintDCInfo *info = FindInCache(&index);
215
216 wxCHECK_RET( info, wxT("existing DC should have a cache entry") );
ffecfa5a 217
e2fc40b4
VZ
218 if ( --info->count == 0 )
219 {
220 //::EndPaint(GetHwndOf(m_window), &g_paintStruct);
e2731512 221
e2fc40b4
VZ
222 ms_cache.RemoveAt(index);
223
224 // Reduce the number of bogus reports of non-freed memory
225 // at app exit
226 if (ms_cache.IsEmpty())
227 ms_cache.Clear();
228 }
229 //else: cached DC entry is still in use
230
231 // prevent the base class dtor from ReleaseDC()ing it again
232 m_hDC = 0;
233 }
234}
235
236wxPaintDCInfo *wxPaintDCImpl::FindInCache(size_t *index) const
ffecfa5a 237{
e2fc40b4
VZ
238 wxPaintDCInfo *info = NULL;
239 size_t nCache = ms_cache.GetCount();
240 for ( size_t n = 0; n < nCache; n++ )
241 {
242 wxPaintDCInfo *info1 = &ms_cache[n];
243 if ( info1->hwnd == m_window->GetHWND() )
244 {
245 info = info1;
246 if ( index )
247 *index = n;
248 break;
249 }
250 }
251
252 return info;
ffecfa5a
JS
253}
254
e2fc40b4
VZ
255// find the entry for this DC in the cache (keyed by the window)
256WXHDC wxPaintDCImpl::FindDCInCache(wxWindow* win)
ffecfa5a 257{
e2fc40b4
VZ
258 size_t nCache = ms_cache.GetCount();
259 for ( size_t n = 0; n < nCache; n++ )
260 {
261 wxPaintDCInfo *info = &ms_cache[n];
262 if ( info->hwnd == win->GetHWND() )
263 {
264 return info->hdc;
265 }
266 }
267 return 0;
ffecfa5a 268}