]> git.saurik.com Git - wxWidgets.git/blame - src/xrc/xh_ribbon.cpp
Workaround for #15404: wxRichTextCtrl: caret does not disappear when focus is lost...
[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
74a59798
VZ
6// Copyright: (c) 2010 Armel Asselin
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
17#if wxUSE_XRC && wxUSE_RIBBON
18
19#include "wx/xrc/xh_ribbon.h"
20
21#include "wx/ribbon/bar.h"
22#include "wx/ribbon/buttonbar.h"
23#include "wx/ribbon/gallery.h"
24
25#include "wx/scopeguard.h"
26
65e9e9c3
VZ
27#ifndef WX_PRECOMP
28 #include "wx/menu.h"
29#endif
30
74a59798
VZ
31// Ribbon bars can contain only pages which are usually panels but may contain
32// any wxWindow.
33//
34// Panels are usually for wxRibbonControls but may as well contain any
35// wxWindow.
36//
37// Galleries are wxRibbonControl and simply contain bitmaps with IDs.
38//
39// Button bars are wxRibbonControl and contain buttons (normal/dropdown/mixed),
40// with id/bitmap/label/short help.
41
42wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonXmlHandler, wxXmlResourceHandler);
43
44wxRibbonXmlHandler::wxRibbonXmlHandler()
45 : wxXmlResourceHandler(),
46 m_isInside(NULL)
47{
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);
57}
58
59wxObject *wxRibbonXmlHandler::DoCreateResource()
60{
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"))
72 return Handle_page();
73 else if (m_class == wxT("wxRibbonBar"))
74 return Handle_bar();
75 else
76 return Handle_control ();
77}
78
79bool wxRibbonXmlHandler::CanHandle(wxXmlNode *node)
80{
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")));
90}
91
92bool wxRibbonXmlHandler::IsRibbonControl (wxXmlNode *node)
93{
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"));
100}
101
102void wxRibbonXmlHandler::Handle_RibbonArtProvider(wxRibbonControl *control)
103{
104 wxString provider = GetText("art-provider", false);
105
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);
112 else
113 ReportError("invalid ribbon art provider");
114}
115
116wxObject* wxRibbonXmlHandler::Handle_buttonbar()
117{
118 XRC_MAKE_INSTANCE (buttonBar, wxRibbonButtonBar);
119
120 if (!buttonBar->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
121 GetPosition(), GetSize(), GetStyle()))
122 {
123 ReportError("could not create ribbon panel");
124 }
125 else
126 {
127 const wxClassInfo* const wasInside = m_isInside;
128 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
129 m_isInside = &wxRibbonButtonBar::ms_classInfo;
130
131 CreateChildren (buttonBar, true);
132
133 buttonBar->Realize();
134 }
135
136 return buttonBar;
137}
138
139wxObject* wxRibbonXmlHandler::Handle_button()
140{
141 wxRibbonButtonBar *buttonBar = wxStaticCast(m_parent, wxRibbonButtonBar);
142
143 wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL;
144
145 if (GetBool(wxT("hybrid")))
146 kind = wxRIBBON_BUTTON_HYBRID;
147
3142ae07
VZ
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.
153#if 0 // wxUSE_MENUS
74a59798
VZ
154 // check whether we have dropdown tag inside
155 wxMenu *menu = NULL; // menu for drop down items
156 wxXmlNode * const nodeDropdown = GetParamNode("dropdown");
157 if ( nodeDropdown )
158 {
159 if (kind == wxRIBBON_BUTTON_NORMAL)
160 kind = wxRIBBON_BUTTON_DROPDOWN;
161
162 // also check for the menu specified inside dropdown (it is
163 // optional and may be absent for e.g. dynamically-created
164 // menus)
165 wxXmlNode * const nodeMenu = nodeDropdown->GetChildren();
166 if ( nodeMenu )
167 {
168 wxObject *res = CreateResFromNode(nodeMenu, NULL);
169 menu = wxDynamicCast(res, wxMenu);
170 if ( !menu )
171 {
172 ReportError
173 (
174 nodeMenu,
175 "drop-down tool contents can only be a wxMenu"
176 );
177 }
178
179 if ( nodeMenu->GetNext() )
180 {
181 ReportError
182 (
183 nodeMenu->GetNext(),
184 "unexpected extra contents under drop-down tool"
185 );
186 }
187 }
188 }
189#endif // wxUSE_MENUS
190
191 if (!buttonBar->AddButton(GetID(),
192 GetText("label"),
193 GetBitmap ("bitmap"),
194 GetBitmap ("small-bitmap"),
195 GetBitmap ("disabled-bitmap"),
196 GetBitmap ("small-disabled-bitmap"),
197 kind,
198 GetText("help")))
199 {
200 ReportError ("could not create button");
201 }
202
203 if ( GetBool(wxT("disabled")) )
204 buttonBar->EnableButton(GetID(), false);
205
206 return NULL; // nothing to return
207}
208
209wxObject* wxRibbonXmlHandler::Handle_control()
210{
211 wxRibbonControl *control = wxDynamicCast (m_instance, wxRibbonControl);
212
213 if (!m_instance)
214 ReportError("wxRibbonControl must be subclassed");
215 else if (!control)
216 ReportError("controls must derive from wxRibbonControl");
217
218 control->Create(wxDynamicCast(m_parent, wxWindow), GetID(),
219 GetPosition(), GetSize(), GetStyle());
220
221 return m_instance;
222}
223
224wxObject* wxRibbonXmlHandler::Handle_page()
225{
226 XRC_MAKE_INSTANCE (ribbonPage, wxRibbonPage);
227
228 if (!ribbonPage->Create (wxDynamicCast(m_parent, wxRibbonBar), GetID(),
229 GetText ("label"), GetBitmap ("icon"), GetStyle()))
230 {
231 ReportError("could not create ribbon page");
232 }
233 else
234 {
235 const wxClassInfo* const wasInside = m_isInside;
236 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
237 m_isInside = &wxRibbonPage::ms_classInfo;
238
239 CreateChildren (ribbonPage);
240
241 ribbonPage->Realize();
242 }
243
244 return ribbonPage;
245}
246
247wxObject* wxRibbonXmlHandler::Handle_gallery()
248{
249 XRC_MAKE_INSTANCE (ribbonGallery, wxRibbonGallery);
250
251 if (!ribbonGallery->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
252 GetPosition(), GetSize(), GetStyle()))
253 {
254 ReportError("could not create ribbon gallery");
255 }
256 else
257 {
258 const wxClassInfo* const wasInside = m_isInside;
259 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
260 m_isInside = &wxRibbonGallery::ms_classInfo;
261
262 CreateChildren (ribbonGallery);
263
264 ribbonGallery->Realize();
265 }
266
267 return ribbonGallery;
268}
269
270wxObject* wxRibbonXmlHandler::Handle_galleryitem()
271{
272 wxRibbonGallery *gallery = wxStaticCast(m_parent, wxRibbonGallery);
273 wxCHECK (gallery, NULL);
274
275 gallery->Append (GetBitmap(), GetID());
276
277 return NULL; // nothing to return
278}
279
280wxObject* wxRibbonXmlHandler::Handle_panel()
281{
282 XRC_MAKE_INSTANCE (ribbonPanel, wxRibbonPanel);
283
284 if (!ribbonPanel->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
285 GetText ("label"), GetBitmap ("icon"), GetPosition(), GetSize(),
286 GetStyle("style", wxRIBBON_PANEL_DEFAULT_STYLE)))
287 {
288 ReportError("could not create ribbon panel");
289 }
290 else
291 {
292 CreateChildren (ribbonPanel);
293
294 ribbonPanel->Realize();
295 }
296
297 return ribbonPanel;
298}
299
300wxObject* wxRibbonXmlHandler::Handle_bar()
301{
302 XRC_MAKE_INSTANCE (ribbonBar, wxRibbonBar);
303
304 Handle_RibbonArtProvider (ribbonBar);
305
306 if ( !ribbonBar->Create(wxDynamicCast(m_parent, wxWindow),
307 GetID(),
308 GetPosition(),
309 GetSize(),
310 GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE)) )
311 {
312 ReportError ("could not create ribbonbar");
313 }
314 else
315 {
316 // Currently the art provider style must be explicitly set to the
317 // ribbon style too.
318 ribbonBar->GetArtProvider()
319 ->SetFlags(GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE));
320
321 const wxClassInfo* const wasInside = m_isInside;
322 wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
323 m_isInside = &wxRibbonBar::ms_classInfo;
324
325 CreateChildren (ribbonBar, true);
326
327 ribbonBar->Realize();
328 }
329
330 return ribbonBar;
331}
332
333#endif // wxUSE_XRC && wxUSE_RIBBON