Files
wxWidgets/src/xrc/xh_ribbon.cpp
Václav Slavík f6ac9c6240 XRC spec: document wxRibbon* XRC handler.
Format documentation was nonexistent (the few words present were
incorrect). Document my best guess about the intended usage.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74925 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-10-03 11:08:48 +00:00

336 lines
10 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/xrc/xh_ribbon.cpp
// Purpose: XML resource handler for wxRibbon related classes
// Author: Armel Asselin
// Created: 2010-04-23
// Copyright: (c) 2010 Armel Asselin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_XRC && wxUSE_RIBBON
#include "wx/xrc/xh_ribbon.h"
#include "wx/ribbon/bar.h"
#include "wx/ribbon/buttonbar.h"
#include "wx/ribbon/gallery.h"
#include "wx/scopeguard.h"
#ifndef WX_PRECOMP
#include "wx/menu.h"
#endif
// Ribbon bars can contain only pages which are usually panels but may contain
// any wxWindow.
//
// Panels are usually for wxRibbonControls but may as well contain any
// wxWindow.
//
// Galleries are wxRibbonControl and simply contain bitmaps with IDs.
//
// Button bars are wxRibbonControl and contain buttons (normal/dropdown/mixed),
// with id/bitmap/label/short help.
wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonXmlHandler, wxXmlResourceHandler);
wxRibbonXmlHandler::wxRibbonXmlHandler()
: wxXmlResourceHandler(),
m_isInside(NULL)
{
XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PAGE_LABELS);
XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PAGE_ICONS);
XRC_ADD_STYLE(wxRIBBON_BAR_FLOW_HORIZONTAL);
XRC_ADD_STYLE(wxRIBBON_BAR_FLOW_VERTICAL);
XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PANEL_EXT_BUTTONS);
XRC_ADD_STYLE(wxRIBBON_BAR_SHOW_PANEL_MINIMISE_BUTTONS);
XRC_ADD_STYLE(wxRIBBON_BAR_ALWAYS_SHOW_TABS);
XRC_ADD_STYLE(wxRIBBON_BAR_DEFAULT_STYLE);
XRC_ADD_STYLE(wxRIBBON_BAR_FOLDBAR_STYLE);
}
wxObject *wxRibbonXmlHandler::DoCreateResource()
{
if (m_class == wxT("button"))
return Handle_button();
if (m_class == wxT("wxRibbonButtonBar"))
return Handle_buttonbar();
else if (m_class == wxT("item"))
return Handle_galleryitem();
else if (m_class == wxT("wxRibbonGallery"))
return Handle_gallery();
else if (m_class == wxT("wxRibbonPanel") || m_class == wxT("panel"))
return Handle_panel();
else if (m_class == wxT("wxRibbonPage") || m_class == wxT("page"))
return Handle_page();
else if (m_class == wxT("wxRibbonBar"))
return Handle_bar();
else
return Handle_control ();
}
bool wxRibbonXmlHandler::CanHandle(wxXmlNode *node)
{
return IsRibbonControl(node) ||
(m_isInside == &wxRibbonButtonBar::ms_classInfo &&
IsOfClass(node, wxT("button"))) ||
(m_isInside == &wxRibbonBar::ms_classInfo &&
IsOfClass(node, wxT("page"))) ||
(m_isInside == &wxRibbonPage::ms_classInfo &&
IsOfClass(node, wxT("panel"))) ||
(m_isInside == &wxRibbonGallery::ms_classInfo &&
IsOfClass(node, wxT("item")));
}
bool wxRibbonXmlHandler::IsRibbonControl (wxXmlNode *node)
{
return IsOfClass(node, wxT("wxRibbonBar")) ||
IsOfClass(node, wxT("wxRibbonButtonBar")) ||
IsOfClass(node, wxT("wxRibbonPage")) ||
IsOfClass(node, wxT("wxRibbonPanel")) ||
IsOfClass(node, wxT("wxRibbonGallery")) ||
IsOfClass(node, wxT("wxRibbonControl"));
}
void wxRibbonXmlHandler::Handle_RibbonArtProvider(wxRibbonControl *control)
{
wxString provider = GetText("art-provider", false);
if (provider == "default" || provider.IsEmpty())
control->SetArtProvider(new wxRibbonDefaultArtProvider);
else if (provider.CmpNoCase("aui") == 0)
control->SetArtProvider(new wxRibbonAUIArtProvider);
else if (provider.CmpNoCase("msw") == 0)
control->SetArtProvider(new wxRibbonMSWArtProvider);
else
ReportError("invalid ribbon art provider");
}
wxObject* wxRibbonXmlHandler::Handle_buttonbar()
{
XRC_MAKE_INSTANCE (buttonBar, wxRibbonButtonBar);
if (!buttonBar->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
GetPosition(), GetSize(), GetStyle()))
{
ReportError("could not create ribbon panel");
}
else
{
const wxClassInfo* const wasInside = m_isInside;
wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
m_isInside = &wxRibbonButtonBar::ms_classInfo;
CreateChildren (buttonBar, true);
buttonBar->Realize();
}
return buttonBar;
}
wxObject* wxRibbonXmlHandler::Handle_button()
{
wxRibbonButtonBar *buttonBar = wxStaticCast(m_parent, wxRibbonButtonBar);
wxRibbonButtonKind kind = wxRIBBON_BUTTON_NORMAL;
if (GetBool(wxT("hybrid")))
kind = wxRIBBON_BUTTON_HYBRID;
// FIXME: The code below uses wxXmlNode directly but this can't be done
// in the ribbon library code as it would force it to always link
// with the xml library. Disable it for now but the real solution
// would be to virtualize GetChildren() and GetNext() methods via
// wxXmlResourceHandler, just as we already do for many others.
//
// FIXME: If re-enabling, don't forget to update the docs and RELAG NG schema!
#if 0 // wxUSE_MENUS
// check whether we have dropdown tag inside
wxMenu *menu = NULL; // menu for drop down items
wxXmlNode * const nodeDropdown = GetParamNode("dropdown");
if ( nodeDropdown )
{
if (kind == wxRIBBON_BUTTON_NORMAL)
kind = wxRIBBON_BUTTON_DROPDOWN;
// also check for the menu specified inside dropdown (it is
// optional and may be absent for e.g. dynamically-created
// menus)
wxXmlNode * const nodeMenu = nodeDropdown->GetChildren();
if ( nodeMenu )
{
wxObject *res = CreateResFromNode(nodeMenu, NULL);
menu = wxDynamicCast(res, wxMenu);
if ( !menu )
{
ReportError
(
nodeMenu,
"drop-down tool contents can only be a wxMenu"
);
}
if ( nodeMenu->GetNext() )
{
ReportError
(
nodeMenu->GetNext(),
"unexpected extra contents under drop-down tool"
);
}
}
}
#endif // wxUSE_MENUS
if (!buttonBar->AddButton(GetID(),
GetText("label"),
GetBitmap ("bitmap"),
GetBitmap ("small-bitmap"),
GetBitmap ("disabled-bitmap"),
GetBitmap ("small-disabled-bitmap"),
kind,
GetText("help")))
{
ReportError ("could not create button");
}
if ( GetBool(wxT("disabled")) )
buttonBar->EnableButton(GetID(), false);
return NULL; // nothing to return
}
wxObject* wxRibbonXmlHandler::Handle_control()
{
wxRibbonControl *control = wxDynamicCast (m_instance, wxRibbonControl);
if (!m_instance)
ReportError("wxRibbonControl must be subclassed");
else if (!control)
ReportError("controls must derive from wxRibbonControl");
control->Create(wxDynamicCast(m_parent, wxWindow), GetID(),
GetPosition(), GetSize(), GetStyle());
return m_instance;
}
wxObject* wxRibbonXmlHandler::Handle_page()
{
XRC_MAKE_INSTANCE (ribbonPage, wxRibbonPage);
if (!ribbonPage->Create (wxDynamicCast(m_parent, wxRibbonBar), GetID(),
GetText ("label"), GetBitmap ("icon"), GetStyle()))
{
ReportError("could not create ribbon page");
}
else
{
const wxClassInfo* const wasInside = m_isInside;
wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
m_isInside = &wxRibbonPage::ms_classInfo;
CreateChildren (ribbonPage);
ribbonPage->Realize();
}
return ribbonPage;
}
wxObject* wxRibbonXmlHandler::Handle_gallery()
{
XRC_MAKE_INSTANCE (ribbonGallery, wxRibbonGallery);
if (!ribbonGallery->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
GetPosition(), GetSize(), GetStyle()))
{
ReportError("could not create ribbon gallery");
}
else
{
const wxClassInfo* const wasInside = m_isInside;
wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
m_isInside = &wxRibbonGallery::ms_classInfo;
CreateChildren (ribbonGallery);
ribbonGallery->Realize();
}
return ribbonGallery;
}
wxObject* wxRibbonXmlHandler::Handle_galleryitem()
{
wxRibbonGallery *gallery = wxStaticCast(m_parent, wxRibbonGallery);
wxCHECK (gallery, NULL);
gallery->Append (GetBitmap(), GetID());
return NULL; // nothing to return
}
wxObject* wxRibbonXmlHandler::Handle_panel()
{
XRC_MAKE_INSTANCE (ribbonPanel, wxRibbonPanel);
if (!ribbonPanel->Create (wxDynamicCast(m_parent, wxWindow), GetID(),
GetText ("label"), GetBitmap ("icon"), GetPosition(), GetSize(),
GetStyle("style", wxRIBBON_PANEL_DEFAULT_STYLE)))
{
ReportError("could not create ribbon panel");
}
else
{
CreateChildren (ribbonPanel);
ribbonPanel->Realize();
}
return ribbonPanel;
}
wxObject* wxRibbonXmlHandler::Handle_bar()
{
XRC_MAKE_INSTANCE (ribbonBar, wxRibbonBar);
Handle_RibbonArtProvider (ribbonBar);
if ( !ribbonBar->Create(wxDynamicCast(m_parent, wxWindow),
GetID(),
GetPosition(),
GetSize(),
GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE)) )
{
ReportError ("could not create ribbonbar");
}
else
{
// Currently the art provider style must be explicitly set to the
// ribbon style too.
ribbonBar->GetArtProvider()
->SetFlags(GetStyle("style", wxRIBBON_BAR_DEFAULT_STYLE));
const wxClassInfo* const wasInside = m_isInside;
wxON_BLOCK_EXIT_SET(m_isInside, wasInside);
m_isInside = &wxRibbonBar::ms_classInfo;
CreateChildren (ribbonBar, true);
ribbonBar->Realize();
}
return ribbonBar;
}
#endif // wxUSE_XRC && wxUSE_RIBBON