]> git.saurik.com Git - wxWidgets.git/blame - src/xrc/xh_ribbon.cpp
Disable wxUSE_ENH_METAFILE for wxGTK builds.
[wxWidgets.git] / src / xrc / xh_ribbon.cpp
CommitLineData
74a59798
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/xrc/xh_ribbon.cpp
3// Purpose: XML resource handler for wxRibbon related classes
4// Author: Armel Asselin
5// Created: 2010-04-23
6// RCS-ID: $Id$
7// Copyright: (c) 2010 Armel Asselin
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
18#if wxUSE_XRC && wxUSE_RIBBON
19
20#include "wx/xrc/xh_ribbon.h"
21
22#include "wx/ribbon/bar.h"
23#include "wx/ribbon/buttonbar.h"
24#include "wx/ribbon/gallery.h"
25
26#include "wx/scopeguard.h"
27
65e9e9c3
VZ
28#ifndef WX_PRECOMP
29 #include "wx/menu.h"
30#endif
31
74a59798
VZ
32// Ribbon bars can contain only pages which are usually panels but may contain
33// any wxWindow.
34//
35// Panels are usually for wxRibbonControls but may as well contain any
36// wxWindow.
37//
38// Galleries are wxRibbonControl and simply contain bitmaps with IDs.
39//
40// Button bars are wxRibbonControl and contain buttons (normal/dropdown/mixed),
41// with id/bitmap/label/short help.
42
43wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonXmlHandler, wxXmlResourceHandler);
44
45wxRibbonXmlHandler::wxRibbonXmlHandler()
46 : wxXmlResourceHandler(),
47 m_isInside(NULL)
48{
49 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PAGE_LABELS);
50 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PAGE_ICONS);
51 XRC_ADD_STYLE(wxRIBBON_BAR_FLOW_HORIZONTAL);
52 XRC_ADD_STYLE(wxRIBBON_BAR_FLOW_VERTICAL);
53 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PANEL_EXT_BUTTONS);
54 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PANEL_MINIMISE_BUTTONS);
55 XRC_ADD_STYLE(wxRIBBON_BAR_ALWAYS_SHOW_TABS);
56 XRC_ADD_STYLE(wxRIBBON_BAR_DEFAULT_STYLE);
57 XRC_ADD_STYLE(wxRIBBON_BAR_FOLDBAR_STYLE);
58}
59
60wxObject *wxRibbonXmlHandler::DoCreateResource()
61{
62 if (m_class == wxT("button"))
63 return Handle_button();
64 if (m_class == wxT("wxRibbonButtonBar"))
65 return Handle_buttonbar();
66 else if (m_class == wxT("item"))
67 return Handle_galleryitem();
68 else if (m_class == wxT("wxRibbonGallery"))
69 return Handle_gallery();
70 else if (m_class == wxT("wxRibbonPanel") || m_class == wxT("panel"))
71 return Handle_panel();
72 else if (m_class == wxT("wxRibbonPage") || m_class == wxT("page"))
73 return Handle_page();
74 else if (m_class == wxT("wxRibbonBar"))
75 return Handle_bar();
76 else
77 return Handle_control ();
78}
79
80bool wxRibbonXmlHandler::CanHandle(wxXmlNode *node)
81{
82 return IsRibbonControl(node) ||
83 (m_isInside == &wxRibbonButtonBar::ms_classInfo &&
84 IsOfClass(node, wxT("button"))) ||
85 (m_isInside == &wxRibbonBar::ms_classInfo &&
86 IsOfClass(node, wxT("page"))) ||
87 (m_isInside == &wxRibbonPage::ms_classInfo &&
88 IsOfClass(node, wxT("panel"))) ||
89 (m_isInside == &wxRibbonGallery::ms_classInfo &&
90 IsOfClass(node, wxT("item")));
91}
92
93bool wxRibbonXmlHandler::IsRibbonControl (wxXmlNode *node)
94{
95 return IsOfClass(node, wxT("wxRibbonBar")) ||
96 IsOfClass(node, wxT("wxRibbonButtonBar")) ||
97 IsOfClass(node, wxT("wxRibbonPage")) ||
98 IsOfClass(node, wxT("wxRibbonPanel")) ||
99 IsOfClass(node, wxT("wxRibbonGallery")) ||
100 IsOfClass(node, wxT("wxRibbonControl"));
101}
102
103void wxRibbonXmlHandler::Handle_RibbonArtProvider(wxRibbonControl *control)
104{
105 wxString provider = GetText("art-provider", false);
106
107 if (provider == "default" || provider.IsEmpty())
108 control->SetArtProvider(new wxRibbonDefaultArtProvider);
109 else if (provider.CmpNoCase("aui") == 0)
110 control->SetArtProvider(new wxRibbonAUIArtProvider);
111 else if (provider.CmpNoCase("msw") == 0)
112 control->SetArtProvider(new wxRibbonMSWArtProvider);
113 else
114 ReportError("invalid ribbon art provider");
115}
116
117wxObject* wxRibbonXmlHandler::Handle_buttonbar()
118{
119 XRC_MAKE_INSTANCE (buttonBar, wxRibbonButtonBar);
120
121 if (!buttonBar->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
122 GetPosition(), GetSize(), GetStyle()))
123 {
124 ReportError("could not create ribbon panel");
125 }
126 else
127 {
128 const wxClassInfo* const wasInside = m_isInside;
129 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
130 m_isInside = &wxRibbonButtonBar::ms_classInfo;
131
132 CreateChildren (buttonBar, true);
133
134 buttonBar->Realize();
135 }
136
137 return buttonBar;
138}
139
140wxObject* wxRibbonXmlHandler::Handle_button()
141{
142 wxRibbonButtonBar *buttonBar = wxStaticCast(m_parent, wxRibbonButtonBar);
143
144 wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL;
145
146 if (GetBool(wxT("hybrid")))
147 kind = wxRIBBON_BUTTON_HYBRID;
148
3142ae07
VZ
149 // FIXME: The code below uses wxXmlNode directly but this can't be done
150 // in the ribbon library code as it would force it to always link
151 // with the xml library. Disable it for now but the real solution
152 // would be to virtualize GetChildren() and GetNext() methods via
153 // wxXmlResourceHandler, just as we already do for many others.
154#if 0 // wxUSE_MENUS
74a59798
VZ
155 // check whether we have dropdown tag inside
156 wxMenu *menu = NULL; // menu for drop down items
157 wxXmlNode * const nodeDropdown = GetParamNode("dropdown");
158 if ( nodeDropdown )
159 {
160 if (kind == wxRIBBON_BUTTON_NORMAL)
161 kind = wxRIBBON_BUTTON_DROPDOWN;
162
163 // also check for the menu specified inside dropdown (it is
164 // optional and may be absent for e.g. dynamically-created
165 // menus)
166 wxXmlNode * const nodeMenu = nodeDropdown->GetChildren();
167 if ( nodeMenu )
168 {
169 wxObject *res = CreateResFromNode(nodeMenu, NULL);
170 menu = wxDynamicCast(res, wxMenu);
171 if ( !menu )
172 {
173 ReportError
174 (
175 nodeMenu,
176 "drop-down tool contents can only be a wxMenu"
177 );
178 }
179
180 if ( nodeMenu->GetNext() )
181 {
182 ReportError
183 (
184 nodeMenu->GetNext(),
185 "unexpected extra contents under drop-down tool"
186 );
187 }
188 }
189 }
190#endif // wxUSE_MENUS
191
192 if (!buttonBar->AddButton(GetID(),
193 GetText("label"),
194 GetBitmap ("bitmap"),
195 GetBitmap ("small-bitmap"),
196 GetBitmap ("disabled-bitmap"),
197 GetBitmap ("small-disabled-bitmap"),
198 kind,
199 GetText("help")))
200 {
201 ReportError ("could not create button");
202 }
203
204 if ( GetBool(wxT("disabled")) )
205 buttonBar->EnableButton(GetID(), false);
206
207 return NULL; // nothing to return
208}
209
210wxObject* wxRibbonXmlHandler::Handle_control()
211{
212 wxRibbonControl *control = wxDynamicCast (m_instance, wxRibbonControl);
213
214 if (!m_instance)
215 ReportError("wxRibbonControl must be subclassed");
216 else if (!control)
217 ReportError("controls must derive from wxRibbonControl");
218
219 control->Create(wxDynamicCast(m_parent, wxWindow), GetID(),
220 GetPosition(), GetSize(), GetStyle());
221
222 return m_instance;
223}
224
225wxObject* wxRibbonXmlHandler::Handle_page()
226{
227 XRC_MAKE_INSTANCE (ribbonPage, wxRibbonPage);
228
229 if (!ribbonPage->Create (wxDynamicCast(m_parent, wxRibbonBar), GetID(),
230 GetText ("label"), GetBitmap ("icon"), GetStyle()))
231 {
232 ReportError("could not create ribbon page");
233 }
234 else
235 {
236 const wxClassInfo* const wasInside = m_isInside;
237 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
238 m_isInside = &wxRibbonPage::ms_classInfo;
239
240 CreateChildren (ribbonPage);
241
242 ribbonPage->Realize();
243 }
244
245 return ribbonPage;
246}
247
248wxObject* wxRibbonXmlHandler::Handle_gallery()
249{
250 XRC_MAKE_INSTANCE (ribbonGallery, wxRibbonGallery);
251
252 if (!ribbonGallery->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
253 GetPosition(), GetSize(), GetStyle()))
254 {
255 ReportError("could not create ribbon gallery");
256 }
257 else
258 {
259 const wxClassInfo* const wasInside = m_isInside;
260 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
261 m_isInside = &wxRibbonGallery::ms_classInfo;
262
263 CreateChildren (ribbonGallery);
264
265 ribbonGallery->Realize();
266 }
267
268 return ribbonGallery;
269}
270
271wxObject* wxRibbonXmlHandler::Handle_galleryitem()
272{
273 wxRibbonGallery *gallery = wxStaticCast(m_parent, wxRibbonGallery);
274 wxCHECK (gallery, NULL);
275
276 gallery->Append (GetBitmap(), GetID());
277
278 return NULL; // nothing to return
279}
280
281wxObject* wxRibbonXmlHandler::Handle_panel()
282{
283 XRC_MAKE_INSTANCE (ribbonPanel, wxRibbonPanel);
284
285 if (!ribbonPanel->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
286 GetText ("label"), GetBitmap ("icon"), GetPosition(), GetSize(),
287 GetStyle("style", wxRIBBON_PANEL_DEFAULT_STYLE)))
288 {
289 ReportError("could not create ribbon panel");
290 }
291 else
292 {
293 CreateChildren (ribbonPanel);
294
295 ribbonPanel->Realize();
296 }
297
298 return ribbonPanel;
299}
300
301wxObject* wxRibbonXmlHandler::Handle_bar()
302{
303 XRC_MAKE_INSTANCE (ribbonBar, wxRibbonBar);
304
305 Handle_RibbonArtProvider (ribbonBar);
306
307 if ( !ribbonBar->Create(wxDynamicCast(m_parent, wxWindow),
308 GetID(),
309 GetPosition(),
310 GetSize(),
311 GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE)) )
312 {
313 ReportError ("could not create ribbonbar");
314 }
315 else
316 {
317 // Currently the art provider style must be explicitly set to the
318 // ribbon style too.
319 ribbonBar->GetArtProvider()
320 ->SetFlags(GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE));
321
322 const wxClassInfo* const wasInside = m_isInside;
323 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
324 m_isInside = &wxRibbonBar::ms_classInfo;
325
326 CreateChildren (ribbonBar, true);
327
328 ribbonBar->Realize();
329 }
330
331 return ribbonBar;
332}
333
334#endif // wxUSE_XRC && wxUSE_RIBBON