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