1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/xrc/xh_ribbon.cpp
3 // Purpose: XML resource handler for wxRibbon related classes
4 // Author: Armel Asselin
7 // Copyright: (c) 2010 Armel Asselin
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #if wxUSE_XRC && wxUSE_RIBBON
20 #include "wx/xrc/xh_ribbon.h"
22 #include "wx/ribbon/bar.h"
23 #include "wx/ribbon/buttonbar.h"
24 #include "wx/ribbon/gallery.h"
26 #include "wx/scopeguard.h"
32 // Ribbon bars can contain only pages which are usually panels but may contain
35 // Panels are usually for wxRibbonControls but may as well contain any
38 // Galleries are wxRibbonControl and simply contain bitmaps with IDs.
40 // Button bars are wxRibbonControl and contain buttons (normal/dropdown/mixed),
41 // with id/bitmap/label/short help.
43 wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonXmlHandler
, wxXmlResourceHandler
);
45 wxRibbonXmlHandler::wxRibbonXmlHandler()
46 : wxXmlResourceHandler(),
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
);
60 wxObject
*wxRibbonXmlHandler::DoCreateResource()
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"))
74 else if (m_class
== wxT("wxRibbonBar"))
77 return Handle_control ();
80 bool wxRibbonXmlHandler::CanHandle(wxXmlNode
*node
)
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")));
93 bool wxRibbonXmlHandler::IsRibbonControl (wxXmlNode
*node
)
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"));
103 void wxRibbonXmlHandler::Handle_RibbonArtProvider(wxRibbonControl
*control
)
105 wxString provider
= GetText("art-provider", false);
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
);
114 ReportError("invalid ribbon art provider");
117 wxObject
* wxRibbonXmlHandler::Handle_buttonbar()
119 XRC_MAKE_INSTANCE (buttonBar
, wxRibbonButtonBar
);
121 if (!buttonBar
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
122 GetPosition(), GetSize(), GetStyle()))
124 ReportError("could not create ribbon panel");
128 const wxClassInfo
* const wasInside
= m_isInside
;
129 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
130 m_isInside
= &wxRibbonButtonBar::ms_classInfo
;
132 CreateChildren (buttonBar
, true);
134 buttonBar
->Realize();
140 wxObject
* wxRibbonXmlHandler::Handle_button()
142 wxRibbonButtonBar
*buttonBar
= wxStaticCast(m_parent
, wxRibbonButtonBar
);
144 wxRibbonButtonKind kind
= wxRIBBON_BUTTON_NORMAL
;
146 if (GetBool(wxT("hybrid")))
147 kind
= wxRIBBON_BUTTON_HYBRID
;
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.
155 // check whether we have dropdown tag inside
156 wxMenu
*menu
= NULL
; // menu for drop down items
157 wxXmlNode
* const nodeDropdown
= GetParamNode("dropdown");
160 if (kind
== wxRIBBON_BUTTON_NORMAL
)
161 kind
= wxRIBBON_BUTTON_DROPDOWN
;
163 // also check for the menu specified inside dropdown (it is
164 // optional and may be absent for e.g. dynamically-created
166 wxXmlNode
* const nodeMenu
= nodeDropdown
->GetChildren();
169 wxObject
*res
= CreateResFromNode(nodeMenu
, NULL
);
170 menu
= wxDynamicCast(res
, wxMenu
);
176 "drop-down tool contents can only be a wxMenu"
180 if ( nodeMenu
->GetNext() )
185 "unexpected extra contents under drop-down tool"
190 #endif // wxUSE_MENUS
192 if (!buttonBar
->AddButton(GetID(),
194 GetBitmap ("bitmap"),
195 GetBitmap ("small-bitmap"),
196 GetBitmap ("disabled-bitmap"),
197 GetBitmap ("small-disabled-bitmap"),
201 ReportError ("could not create button");
204 if ( GetBool(wxT("disabled")) )
205 buttonBar
->EnableButton(GetID(), false);
207 return NULL
; // nothing to return
210 wxObject
* wxRibbonXmlHandler::Handle_control()
212 wxRibbonControl
*control
= wxDynamicCast (m_instance
, wxRibbonControl
);
215 ReportError("wxRibbonControl must be subclassed");
217 ReportError("controls must derive from wxRibbonControl");
219 control
->Create(wxDynamicCast(m_parent
, wxWindow
), GetID(),
220 GetPosition(), GetSize(), GetStyle());
225 wxObject
* wxRibbonXmlHandler::Handle_page()
227 XRC_MAKE_INSTANCE (ribbonPage
, wxRibbonPage
);
229 if (!ribbonPage
->Create (wxDynamicCast(m_parent
, wxRibbonBar
), GetID(),
230 GetText ("label"), GetBitmap ("icon"), GetStyle()))
232 ReportError("could not create ribbon page");
236 const wxClassInfo
* const wasInside
= m_isInside
;
237 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
238 m_isInside
= &wxRibbonPage::ms_classInfo
;
240 CreateChildren (ribbonPage
);
242 ribbonPage
->Realize();
248 wxObject
* wxRibbonXmlHandler::Handle_gallery()
250 XRC_MAKE_INSTANCE (ribbonGallery
, wxRibbonGallery
);
252 if (!ribbonGallery
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
253 GetPosition(), GetSize(), GetStyle()))
255 ReportError("could not create ribbon gallery");
259 const wxClassInfo
* const wasInside
= m_isInside
;
260 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
261 m_isInside
= &wxRibbonGallery::ms_classInfo
;
263 CreateChildren (ribbonGallery
);
265 ribbonGallery
->Realize();
268 return ribbonGallery
;
271 wxObject
* wxRibbonXmlHandler::Handle_galleryitem()
273 wxRibbonGallery
*gallery
= wxStaticCast(m_parent
, wxRibbonGallery
);
274 wxCHECK (gallery
, NULL
);
276 gallery
->Append (GetBitmap(), GetID());
278 return NULL
; // nothing to return
281 wxObject
* wxRibbonXmlHandler::Handle_panel()
283 XRC_MAKE_INSTANCE (ribbonPanel
, wxRibbonPanel
);
285 if (!ribbonPanel
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
286 GetText ("label"), GetBitmap ("icon"), GetPosition(), GetSize(),
287 GetStyle("style", wxRIBBON_PANEL_DEFAULT_STYLE
)))
289 ReportError("could not create ribbon panel");
293 CreateChildren (ribbonPanel
);
295 ribbonPanel
->Realize();
301 wxObject
* wxRibbonXmlHandler::Handle_bar()
303 XRC_MAKE_INSTANCE (ribbonBar
, wxRibbonBar
);
305 Handle_RibbonArtProvider (ribbonBar
);
307 if ( !ribbonBar
->Create(wxDynamicCast(m_parent
, wxWindow
),
311 GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE
)) )
313 ReportError ("could not create ribbonbar");
317 // Currently the art provider style must be explicitly set to the
319 ribbonBar
->GetArtProvider()
320 ->SetFlags(GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE
));
322 const wxClassInfo
* const wasInside
= m_isInside
;
323 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
324 m_isInside
= &wxRibbonBar::ms_classInfo
;
326 CreateChildren (ribbonBar
, true);
328 ribbonBar
->Realize();
334 #endif // wxUSE_XRC && wxUSE_RIBBON