make it possible to create wxWindowDC for a hidden window
[wxWidgets.git] / src / dfb / dcclient.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/dcclient.cpp
3 // Purpose: wxWindowDC, wxClientDC and wxPaintDC
4 // Author: Vaclav Slavik
5 // Created: 2006-08-10
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ===========================================================================
12 // declarations
13 // ===========================================================================
14
15 // ---------------------------------------------------------------------------
16 // headers
17 // ---------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #include "wx/dcclient.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/window.h"
30 #endif
31
32 #include "wx/dfb/private.h"
33
34 // ===========================================================================
35 // implementation
36 // ===========================================================================
37
38 //-----------------------------------------------------------------------------
39 // wxWindowDC
40 //-----------------------------------------------------------------------------
41
42 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
43
44 wxWindowDC::wxWindowDC(wxWindow *win)
45 {
46 InitForWin(win, NULL);
47 }
48
49 void wxWindowDC::InitForWin(wxWindow *win, const wxRect *rect)
50 {
51 wxCHECK_RET( win, _T("invalid window") );
52
53 // check if the rectangle covers full window and so is not needed:
54 if ( rect && *rect == wxRect(win->GetSize()) )
55 rect = NULL;
56
57 // obtain the surface used for painting:
58 wxIDirectFBSurfacePtr surface;
59
60 if ( !win->IsVisible() )
61 {
62 // we're painting on invisible window: the changes won't have any
63 // effect, as the window will be repainted anyhow when it is shown, but
64 // we still need a valid DC so that e.g. text extents can be measured,
65 // so let's create a dummy surface that has the same format as the real
66 // one would have and let the code paint on it:
67 wxSize size(rect ? rect->GetSize() : win->GetSize());
68 surface = wxDfbCreateCompatibleSurface(win->GetDfbSurface(), size);
69 }
70 else if ( !rect )
71 {
72 wxCHECK_RET( win->GetSize().x > 0 && win->GetSize().y > 0,
73 _T("window has invalid size") );
74
75 surface = win->GetDfbSurface();
76 }
77 else
78 {
79 wxCHECK_RET( !rect || !rect->IsEmpty(), _T("invalid rectangle") );
80
81 DFBRectangle dfbrect = { rect->x, rect->y, rect->width, rect->height };
82 surface = win->GetDfbSurface()->GetSubSurface(&dfbrect);
83 }
84
85 if ( !surface )
86 return;
87
88 Init(surface);
89 SetFont(win->GetFont());
90
91 // offset coordinates to account for subsurface's origin coordinates:
92 if ( rect )
93 SetDeviceOrigin(rect->x, rect->y);
94 }
95
96 //-----------------------------------------------------------------------------
97 // base class for wxClientDC and wxPaintDC
98 //-----------------------------------------------------------------------------
99
100 wxClientDCBase::wxClientDCBase(wxWindow *win)
101 {
102 wxCHECK_RET( win, _T("invalid window") );
103
104 wxRect rect = win->GetClientRect();
105 InitForWin(win, &rect);
106 }
107
108 //-----------------------------------------------------------------------------
109 // wxClientDC
110 //-----------------------------------------------------------------------------
111
112 IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
113
114 wxClientDC::~wxClientDC()
115 {
116 // flip to surface so that the changes become visible
117 wxIDirectFBSurfacePtr surface(GetDirectFBSurface());
118
119 // FIXME: do this only if the surface was modified (as opposed to e.g.
120 // used only to obtain text metrics)
121 if ( surface )
122 surface->Flip(NULL, DSFLIP_NONE);
123 }
124
125 //-----------------------------------------------------------------------------
126 // wxPaintDC
127 //-----------------------------------------------------------------------------
128
129 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
130
131 #warning "wxPaintDC ctor must respect m_updateRegion"
132
133 wxPaintDC::~wxPaintDC()
134 {
135 // NB: do *not* flip the surface: wxPaintDC is used with EVT_PAINT and the
136 // surface will be flipped for the entire TLW once all children are
137 // repainted
138 }