]> git.saurik.com Git - wxWidgets.git/blob - src/common/rendcmn.cpp
switched to using a real class instead of a namespace because of Mac base/GUI problems
[wxWidgets.git] / src / common / rendcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/rendcmn.cpp
3 // Purpose: wxRendererNative common functions
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 28.07.03
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #endif //WX_PRECOMP
31
32 #include "wx/apptrait.h"
33 #include "wx/renderer.h"
34
35 #include "wx/ptr_scpd.h"
36
37 #if wxUSE_DYNLIB_CLASS
38 #include "wx/dynlib.h"
39 #endif // wxUSE_DYNLIB_CLASS
40
41 // ----------------------------------------------------------------------------
42 // wxRendererPtr: auto pointer holding the global renderer
43 // ----------------------------------------------------------------------------
44
45 wxDECLARE_SCOPED_PTR(wxRendererNative, wxRendererPtrBase);
46 wxDEFINE_SCOPED_PTR(wxRendererNative, wxRendererPtrBase);
47
48 class wxRendererPtr : public wxRendererPtrBase
49 {
50 public:
51 // return true if we have a renderer, false otherwise
52 bool IsOk()
53 {
54 if ( !m_initialized )
55 {
56 // only try to create the renderer once
57 m_initialized = true;
58
59 DoInit();
60 }
61
62 return get() != NULL;
63 }
64
65 // return the global and unique wxRendererPtr
66 static wxRendererPtr& Get()
67 {
68 static wxRendererPtr s_renderer;
69
70 return s_renderer;
71 }
72
73 private:
74 wxRendererPtr() : wxRendererPtrBase(NULL) { m_initialized = false; }
75
76 void DoInit()
77 {
78 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
79 if ( traits )
80 {
81 // ask the traits object to create a renderer for us
82 reset(traits->CreateRenderer());
83 }
84 }
85
86 bool m_initialized;
87
88 // just to suppress a gcc warning
89 friend class wxRendererPtrDummyFriend;
90
91 DECLARE_NO_COPY_CLASS(wxRendererPtr)
92 };
93
94 #if wxUSE_DYNLIB_CLASS
95
96 // ----------------------------------------------------------------------------
97 // wxRendererFromDynLib: represents a renderer dynamically loaded from a DLL
98 // ----------------------------------------------------------------------------
99
100 class wxRendererFromDynLib : public wxDelegateRendererNative
101 {
102 public:
103 // create the object wrapping the given renderer created from this DLL
104 //
105 // we take ownership of the pointer and will delete it (and also unload the
106 // DLL) when we're deleted
107 wxRendererFromDynLib(wxDynamicLibrary& dll, wxRendererNative *renderer)
108 : wxDelegateRendererNative(*renderer),
109 m_renderer(renderer),
110 m_dllHandle(dll.Detach())
111 {
112 }
113
114 virtual ~wxRendererFromDynLib()
115 {
116 delete m_renderer;
117 wxDynamicLibrary::Unload(m_dllHandle);
118 }
119
120 private:
121 wxRendererNative *m_renderer;
122 wxDllType m_dllHandle;
123 };
124
125 #endif // wxUSE_DYNLIB_CLASS
126
127 // ============================================================================
128 // wxRendererNative implementation
129 // ============================================================================
130
131 wxRendererNative::~wxRendererNative()
132 {
133 // empty but necessary
134 }
135
136 // ----------------------------------------------------------------------------
137 // Managing the global renderer
138 // ----------------------------------------------------------------------------
139
140 /* static */
141 wxRendererNative& wxRendererNative::Get()
142 {
143 wxRendererPtr& renderer = wxRendererPtr::Get();
144
145 return renderer.IsOk() ? *renderer.get() : GetDefault();
146 }
147
148 /* static */
149 wxRendererNative *wxRendererNative::Set(wxRendererNative *rendererNew)
150 {
151 wxRendererPtr& renderer = wxRendererPtr::Get();
152
153 wxRendererNative *rendererOld = renderer.release();
154
155 renderer.reset(rendererNew);
156
157 return rendererOld;
158 }
159
160
161 // ----------------------------------------------------------------------------
162 // Dynamic renderers loading
163 // ----------------------------------------------------------------------------
164
165 #if wxUSE_DYNLIB_CLASS
166
167 /* static */
168 wxRendererNative *wxRendererNative::Load(const wxString& name)
169 {
170 wxString fullname = wxDynamicLibrary::CanonicalizePluginName(name);
171
172 wxDynamicLibrary dll(fullname);
173 if ( !dll.IsLoaded() )
174 return NULL;
175
176 // each theme DLL must export a wxCreateRenderer() function with this
177 // signature
178 typedef wxRendererNative *(*wxCreateRenderer_t)();
179
180 wxDYNLIB_FUNCTION(wxCreateRenderer_t, wxCreateRenderer, dll);
181 if ( !pfnwxCreateRenderer )
182 return NULL;
183
184 // create a renderer object
185 wxRendererNative *renderer = (*pfnwxCreateRenderer)();
186 if ( !renderer )
187 return NULL;
188
189 // check that its version is compatible with ours
190 wxRendererVersion ver = renderer->GetVersion();
191 if ( !wxRendererVersion::IsCompatible(ver) )
192 {
193 wxLogError(_("Renderer \"%s\" has incompatible version %d.%d and couldn't be loaded."),
194 name.c_str(), ver.version, ver.age);
195 delete renderer;
196
197 return NULL;
198 }
199
200 // finally wrap the renderer in an object which will delete it and unload
201 // the library when it is deleted and return it to the caller
202 return new wxRendererFromDynLib(dll, renderer);
203 }
204
205 #endif // wxUSE_DYNLIB_CLASS
206