1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/xrc/xh_ribbon.cpp
3 // Purpose: XML resource handler for wxRibbon related classes
4 // Author: Armel Asselin
6 // Copyright: (c) 2010 Armel Asselin
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
17 #if wxUSE_XRC && wxUSE_RIBBON
19 #include "wx/xrc/xh_ribbon.h"
21 #include "wx/ribbon/bar.h"
22 #include "wx/ribbon/buttonbar.h"
23 #include "wx/ribbon/gallery.h"
25 #include "wx/scopeguard.h"
31 // Ribbon bars can contain only pages which are usually panels but may contain
34 // Panels are usually for wxRibbonControls but may as well contain any
37 // Galleries are wxRibbonControl and simply contain bitmaps with IDs.
39 // Button bars are wxRibbonControl and contain buttons (normal/dropdown/mixed),
40 // with id/bitmap/label/short help.
42 wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonXmlHandler
, wxXmlResourceHandler
);
44 wxRibbonXmlHandler::wxRibbonXmlHandler()
45 : wxXmlResourceHandler(),
48 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PAGE_LABELS
);
49 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PAGE_ICONS
);
50 XRC_ADD_STYLE(wxRIBBON_BAR_FLOW_HORIZONTAL
);
51 XRC_ADD_STYLE(wxRIBBON_BAR_FLOW_VERTICAL
);
52 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PANEL_EXT_BUTTONS
);
53 XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PANEL_MINIMISE_BUTTONS
);
54 XRC_ADD_STYLE(wxRIBBON_BAR_ALWAYS_SHOW_TABS
);
55 XRC_ADD_STYLE(wxRIBBON_BAR_DEFAULT_STYLE
);
56 XRC_ADD_STYLE(wxRIBBON_BAR_FOLDBAR_STYLE
);
59 wxObject
*wxRibbonXmlHandler::DoCreateResource()
61 if (m_class
== wxT("button"))
62 return Handle_button();
63 if (m_class
== wxT("wxRibbonButtonBar"))
64 return Handle_buttonbar();
65 else if (m_class
== wxT("item"))
66 return Handle_galleryitem();
67 else if (m_class
== wxT("wxRibbonGallery"))
68 return Handle_gallery();
69 else if (m_class
== wxT("wxRibbonPanel") || m_class
== wxT("panel"))
70 return Handle_panel();
71 else if (m_class
== wxT("wxRibbonPage") || m_class
== wxT("page"))
73 else if (m_class
== wxT("wxRibbonBar"))
76 return Handle_control ();
79 bool wxRibbonXmlHandler::CanHandle(wxXmlNode
*node
)
81 return IsRibbonControl(node
) ||
82 (m_isInside
== &wxRibbonButtonBar::ms_classInfo
&&
83 IsOfClass(node
, wxT("button"))) ||
84 (m_isInside
== &wxRibbonBar::ms_classInfo
&&
85 IsOfClass(node
, wxT("page"))) ||
86 (m_isInside
== &wxRibbonPage::ms_classInfo
&&
87 IsOfClass(node
, wxT("panel"))) ||
88 (m_isInside
== &wxRibbonGallery::ms_classInfo
&&
89 IsOfClass(node
, wxT("item")));
92 bool wxRibbonXmlHandler::IsRibbonControl (wxXmlNode
*node
)
94 return IsOfClass(node
, wxT("wxRibbonBar")) ||
95 IsOfClass(node
, wxT("wxRibbonButtonBar")) ||
96 IsOfClass(node
, wxT("wxRibbonPage")) ||
97 IsOfClass(node
, wxT("wxRibbonPanel")) ||
98 IsOfClass(node
, wxT("wxRibbonGallery")) ||
99 IsOfClass(node
, wxT("wxRibbonControl"));
102 void wxRibbonXmlHandler::Handle_RibbonArtProvider(wxRibbonControl
*control
)
104 wxString provider
= GetText("art-provider", false);
106 if (provider
== "default" || provider
.IsEmpty())
107 control
->SetArtProvider(new wxRibbonDefaultArtProvider
);
108 else if (provider
.CmpNoCase("aui") == 0)
109 control
->SetArtProvider(new wxRibbonAUIArtProvider
);
110 else if (provider
.CmpNoCase("msw") == 0)
111 control
->SetArtProvider(new wxRibbonMSWArtProvider
);
113 ReportError("invalid ribbon art provider");
116 wxObject
* wxRibbonXmlHandler::Handle_buttonbar()
118 XRC_MAKE_INSTANCE (buttonBar
, wxRibbonButtonBar
);
120 if (!buttonBar
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
121 GetPosition(), GetSize(), GetStyle()))
123 ReportError("could not create ribbon panel");
127 const wxClassInfo
* const wasInside
= m_isInside
;
128 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
129 m_isInside
= &wxRibbonButtonBar::ms_classInfo
;
131 CreateChildren (buttonBar
, true);
133 buttonBar
->Realize();
139 wxObject
* wxRibbonXmlHandler::Handle_button()
141 wxRibbonButtonBar
*buttonBar
= wxStaticCast(m_parent
, wxRibbonButtonBar
);
143 wxRibbonButtonKind kind
= wxRIBBON_BUTTON_NORMAL
;
145 if (GetBool(wxT("hybrid")))
146 kind
= wxRIBBON_BUTTON_HYBRID
;
148 // FIXME: The code below uses wxXmlNode directly but this can't be done
149 // in the ribbon library code as it would force it to always link
150 // with the xml library. Disable it for now but the real solution
151 // would be to virtualize GetChildren() and GetNext() methods via
152 // wxXmlResourceHandler, just as we already do for many others.
154 // check whether we have dropdown tag inside
155 wxMenu
*menu
= NULL
; // menu for drop down items
156 wxXmlNode
* const nodeDropdown
= GetParamNode("dropdown");
159 if (kind
== wxRIBBON_BUTTON_NORMAL
)
160 kind
= wxRIBBON_BUTTON_DROPDOWN
;
162 // also check for the menu specified inside dropdown (it is
163 // optional and may be absent for e.g. dynamically-created
165 wxXmlNode
* const nodeMenu
= nodeDropdown
->GetChildren();
168 wxObject
*res
= CreateResFromNode(nodeMenu
, NULL
);
169 menu
= wxDynamicCast(res
, wxMenu
);
175 "drop-down tool contents can only be a wxMenu"
179 if ( nodeMenu
->GetNext() )
184 "unexpected extra contents under drop-down tool"
189 #endif // wxUSE_MENUS
191 if (!buttonBar
->AddButton(GetID(),
193 GetBitmap ("bitmap"),
194 GetBitmap ("small-bitmap"),
195 GetBitmap ("disabled-bitmap"),
196 GetBitmap ("small-disabled-bitmap"),
200 ReportError ("could not create button");
203 if ( GetBool(wxT("disabled")) )
204 buttonBar
->EnableButton(GetID(), false);
206 return NULL
; // nothing to return
209 wxObject
* wxRibbonXmlHandler::Handle_control()
211 wxRibbonControl
*control
= wxDynamicCast (m_instance
, wxRibbonControl
);
214 ReportError("wxRibbonControl must be subclassed");
216 ReportError("controls must derive from wxRibbonControl");
218 control
->Create(wxDynamicCast(m_parent
, wxWindow
), GetID(),
219 GetPosition(), GetSize(), GetStyle());
224 wxObject
* wxRibbonXmlHandler::Handle_page()
226 XRC_MAKE_INSTANCE (ribbonPage
, wxRibbonPage
);
228 if (!ribbonPage
->Create (wxDynamicCast(m_parent
, wxRibbonBar
), GetID(),
229 GetText ("label"), GetBitmap ("icon"), GetStyle()))
231 ReportError("could not create ribbon page");
235 const wxClassInfo
* const wasInside
= m_isInside
;
236 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
237 m_isInside
= &wxRibbonPage::ms_classInfo
;
239 CreateChildren (ribbonPage
);
241 ribbonPage
->Realize();
247 wxObject
* wxRibbonXmlHandler::Handle_gallery()
249 XRC_MAKE_INSTANCE (ribbonGallery
, wxRibbonGallery
);
251 if (!ribbonGallery
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
252 GetPosition(), GetSize(), GetStyle()))
254 ReportError("could not create ribbon gallery");
258 const wxClassInfo
* const wasInside
= m_isInside
;
259 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
260 m_isInside
= &wxRibbonGallery::ms_classInfo
;
262 CreateChildren (ribbonGallery
);
264 ribbonGallery
->Realize();
267 return ribbonGallery
;
270 wxObject
* wxRibbonXmlHandler::Handle_galleryitem()
272 wxRibbonGallery
*gallery
= wxStaticCast(m_parent
, wxRibbonGallery
);
273 wxCHECK (gallery
, NULL
);
275 gallery
->Append (GetBitmap(), GetID());
277 return NULL
; // nothing to return
280 wxObject
* wxRibbonXmlHandler::Handle_panel()
282 XRC_MAKE_INSTANCE (ribbonPanel
, wxRibbonPanel
);
284 if (!ribbonPanel
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
285 GetText ("label"), GetBitmap ("icon"), GetPosition(), GetSize(),
286 GetStyle("style", wxRIBBON_PANEL_DEFAULT_STYLE
)))
288 ReportError("could not create ribbon panel");
292 CreateChildren (ribbonPanel
);
294 ribbonPanel
->Realize();
300 wxObject
* wxRibbonXmlHandler::Handle_bar()
302 XRC_MAKE_INSTANCE (ribbonBar
, wxRibbonBar
);
304 Handle_RibbonArtProvider (ribbonBar
);
306 if ( !ribbonBar
->Create(wxDynamicCast(m_parent
, wxWindow
),
310 GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE
)) )
312 ReportError ("could not create ribbonbar");
316 // Currently the art provider style must be explicitly set to the
318 ribbonBar
->GetArtProvider()
319 ->SetFlags(GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE
));
321 const wxClassInfo
* const wasInside
= m_isInside
;
322 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
323 m_isInside
= &wxRibbonBar::ms_classInfo
;
325 CreateChildren (ribbonBar
, true);
327 ribbonBar
->Realize();
333 #endif // wxUSE_XRC && wxUSE_RIBBON