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 // FIXME: If re-enabling, don't forget to update the docs and RELAG NG schema!
156 // check whether we have dropdown tag inside
157 wxMenu
*menu
= NULL
; // menu for drop down items
158 wxXmlNode
* const nodeDropdown
= GetParamNode("dropdown");
161 if (kind
== wxRIBBON_BUTTON_NORMAL
)
162 kind
= wxRIBBON_BUTTON_DROPDOWN
;
164 // also check for the menu specified inside dropdown (it is
165 // optional and may be absent for e.g. dynamically-created
167 wxXmlNode
* const nodeMenu
= nodeDropdown
->GetChildren();
170 wxObject
*res
= CreateResFromNode(nodeMenu
, NULL
);
171 menu
= wxDynamicCast(res
, wxMenu
);
177 "drop-down tool contents can only be a wxMenu"
181 if ( nodeMenu
->GetNext() )
186 "unexpected extra contents under drop-down tool"
191 #endif // wxUSE_MENUS
193 if (!buttonBar
->AddButton(GetID(),
195 GetBitmap ("bitmap"),
196 GetBitmap ("small-bitmap"),
197 GetBitmap ("disabled-bitmap"),
198 GetBitmap ("small-disabled-bitmap"),
202 ReportError ("could not create button");
205 if ( GetBool(wxT("disabled")) )
206 buttonBar
->EnableButton(GetID(), false);
208 return NULL
; // nothing to return
211 wxObject
* wxRibbonXmlHandler::Handle_control()
213 wxRibbonControl
*control
= wxDynamicCast (m_instance
, wxRibbonControl
);
216 ReportError("wxRibbonControl must be subclassed");
218 ReportError("controls must derive from wxRibbonControl");
220 control
->Create(wxDynamicCast(m_parent
, wxWindow
), GetID(),
221 GetPosition(), GetSize(), GetStyle());
226 wxObject
* wxRibbonXmlHandler::Handle_page()
228 XRC_MAKE_INSTANCE (ribbonPage
, wxRibbonPage
);
230 if (!ribbonPage
->Create (wxDynamicCast(m_parent
, wxRibbonBar
), GetID(),
231 GetText ("label"), GetBitmap ("icon"), GetStyle()))
233 ReportError("could not create ribbon page");
237 const wxClassInfo
* const wasInside
= m_isInside
;
238 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
239 m_isInside
= &wxRibbonPage::ms_classInfo
;
241 CreateChildren (ribbonPage
);
243 ribbonPage
->Realize();
249 wxObject
* wxRibbonXmlHandler::Handle_gallery()
251 XRC_MAKE_INSTANCE (ribbonGallery
, wxRibbonGallery
);
253 if (!ribbonGallery
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
254 GetPosition(), GetSize(), GetStyle()))
256 ReportError("could not create ribbon gallery");
260 const wxClassInfo
* const wasInside
= m_isInside
;
261 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
262 m_isInside
= &wxRibbonGallery::ms_classInfo
;
264 CreateChildren (ribbonGallery
);
266 ribbonGallery
->Realize();
269 return ribbonGallery
;
272 wxObject
* wxRibbonXmlHandler::Handle_galleryitem()
274 wxRibbonGallery
*gallery
= wxStaticCast(m_parent
, wxRibbonGallery
);
275 wxCHECK (gallery
, NULL
);
277 gallery
->Append (GetBitmap(), GetID());
279 return NULL
; // nothing to return
282 wxObject
* wxRibbonXmlHandler::Handle_panel()
284 XRC_MAKE_INSTANCE (ribbonPanel
, wxRibbonPanel
);
286 if (!ribbonPanel
->Create (wxDynamicCast(m_parent
, wxWindow
), GetID(),
287 GetText ("label"), GetBitmap ("icon"), GetPosition(), GetSize(),
288 GetStyle("style", wxRIBBON_PANEL_DEFAULT_STYLE
)))
290 ReportError("could not create ribbon panel");
294 CreateChildren (ribbonPanel
);
296 ribbonPanel
->Realize();
302 wxObject
* wxRibbonXmlHandler::Handle_bar()
304 XRC_MAKE_INSTANCE (ribbonBar
, wxRibbonBar
);
306 Handle_RibbonArtProvider (ribbonBar
);
308 if ( !ribbonBar
->Create(wxDynamicCast(m_parent
, wxWindow
),
312 GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE
)) )
314 ReportError ("could not create ribbonbar");
318 // Currently the art provider style must be explicitly set to the
320 ribbonBar
->GetArtProvider()
321 ->SetFlags(GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE
));
323 const wxClassInfo
* const wasInside
= m_isInside
;
324 wxON_BLOCK_EXIT_SET(m_isInside
, wasInside
);
325 m_isInside
= &wxRibbonBar::ms_classInfo
;
327 CreateChildren (ribbonBar
, true);
329 ribbonBar
->Realize();
335 #endif // wxUSE_XRC && wxUSE_RIBBON