- wxPropertyGrid: added wxPG_NO_INTERNAL_BORDER, wxPG_EX_NO_TOOLBAR_DIVIDER
and wxPG_EX_TOOLBAR_SEPARATOR styles for finer control over borders.
Borders around property grid are now native for consistency.
+- Added wxXmlResource::LoadObjectRecursively().
GTK:
// Load an object from the resource specifying both the resource name and
// the classname. This lets you load nonstandard container windows.
wxObject *LoadObject(wxWindow *parent, const wxString& name,
- const wxString& classname);
+ const wxString& classname)
+ {
+ return DoLoadObject(parent, name, classname, false /* !recursive */);
+ }
// Load an object from the resource specifying both the resource name and
// the classname. This form lets you finish the creation of an existing
// instance.
- bool LoadObject(wxObject *instance, wxWindow *parent, const wxString& name,
- const wxString& classname);
+ bool LoadObject(wxObject *instance,
+ wxWindow *parent,
+ const wxString& name,
+ const wxString& classname)
+ {
+ return DoLoadObject(instance, parent, name, classname, false);
+ }
+
+ // These versions of LoadObject() look for the object with the given name
+ // recursively (breadth first) and can be used to instantiate an individual
+ // control defined anywhere in an XRC file. No check is done that the name
+ // is unique, it's up to the caller to ensure this.
+ wxObject *LoadObjectRecursively(wxWindow *parent,
+ const wxString& name,
+ const wxString& classname)
+ {
+ return DoLoadObject(parent, name, classname, true /* recursive */);
+ }
+
+ bool LoadObjectRecursively(wxObject *instance,
+ wxWindow *parent,
+ const wxString& name,
+ const wxString& classname)
+ {
+ return DoLoadObject(instance, parent, name, classname, true);
+ }
// Loads a bitmap resource from a file.
wxBitmap LoadBitmap(const wxString& name);
// (Uses only 'handlerToUse' if != NULL)
wxObject *CreateResFromNode(wxXmlNode *node, wxObject *parent,
wxObject *instance = NULL,
- wxXmlResourceHandler *handlerToUse = NULL);
+ wxXmlResourceHandler *handlerToUse = NULL)
+ {
+ return node ? DoCreateResFromNode(*node, parent, instance, handlerToUse)
+ : NULL;
+ }
// Helper of Load() and Unload(): returns the URL corresponding to the
// given file if it's indeed a file, otherwise returns the original string
wxXmlResourceDataRecords& Data() { return *m_data; }
const wxXmlResourceDataRecords& Data() const { return *m_data; }
+ // the real implementation of CreateResFromNode(): this should be only
+ // called if node is non-NULL
+ wxObject *DoCreateResFromNode(wxXmlNode& node,
+ wxObject *parent,
+ wxObject *instance,
+ wxXmlResourceHandler *handlerToUse = NULL);
+
+ // common part of LoadObject() and LoadObjectRecursively()
+ wxObject *DoLoadObject(wxWindow *parent,
+ const wxString& name,
+ const wxString& classname,
+ bool recursive);
+ bool DoLoadObject(wxObject *instance,
+ wxWindow *parent,
+ const wxString& name,
+ const wxString& classname,
+ bool recursive);
+
private:
long m_version;
The first overload lets you load nonstandard container windows and returns
@NULL on failure. The second one lets you finish the creation of an existing
instance and returns @false on failure.
+
+ In either case, only the resources defined at the top level of XRC
+ files can be loaded by this function, use LoadObjectRecursively() if
+ you need to load an object defined deeper in the hierarchy.
*/
wxObject* LoadObject(wxWindow* parent, const wxString& name,
const wxString& classname);
const wxString& classname);
//@}
+ //@{
+ /**
+ Load an object from anywhere in the resource tree.
+
+ These methods are similar to LoadObject() but may be used to load an
+ object from anywhere in the resource tree and not only the top level.
+ Note that you will very rarely need to do this as in normal use the
+ entire container window (defined at the top level) is loaded and not
+ its individual children but this method can be useful in some
+ particular situations.
+
+ @since 2.9.1
+ */
+ wxObject* LoadObjectRecursively(wxWindow* parent,
+ const wxString& name,
+ const wxString& classname);
+ bool LoadObjectRecursively(wxObject* instance, wxWindow* parent,
+ const wxString& name,
+ const wxString& classname);
+ //@}
+
/**
Loads a panel. @a parent points to the parent window.
*/
EVT_MENU(XRCID("platform_property_tool_or_menuitem"), MyFrame::OnPlatformPropertyToolOrMenuCommand)
EVT_MENU(XRCID("art_provider_tool_or_menuitem"), MyFrame::OnArtProviderToolOrMenuCommand)
EVT_MENU(XRCID("variable_expansion_tool_or_menuitem"), MyFrame::OnVariableExpansionToolOrMenuCommand)
+ EVT_MENU(XRCID("recursive_load"), MyFrame::OnRecursiveLoad)
EVT_MENU(wxID_ABOUT, MyFrame::OnAboutToolOrMenuCommand)
END_EVENT_TABLE()
dlg.ShowModal();
}
+void MyFrame::OnRecursiveLoad(wxCommandEvent& WXUNUSED(event))
+{
+ // this dialog is created manually to show how you can inject a single
+ // control from XRC into an existing dialog
+ //
+ // this is a slightly contrived example, please keep in mind that it's done
+ // only to demonstrate LoadObjectRecursively() in action and is not the
+ // recommended to do this
+ wxDialog dlg(NULL, wxID_ANY, "Recursive Load Example",
+ wxDefaultPosition, wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
+ wxSizer * const sizer = new wxBoxSizer(wxVERTICAL);
+ sizer->Add
+ (
+ new wxStaticText
+ (
+ &dlg,
+ wxID_ANY,
+ "The entire tree book control below is loaded from XRC"
+ ),
+ wxSizerFlags().Expand().Border()
+ );
+
+ sizer->Add
+ (
+ static_cast<wxWindow *>
+ (
+ // notice that controls_treebook is defined inside a notebook page
+ // inside a dialog defined in controls.xrc and so LoadObject()
+ // wouldn't find it -- but LoadObjectRecursively() does
+ wxXmlResource::Get()->
+ LoadObjectRecursively(&dlg, "controls_treebook", "wxTreebook")
+ ),
+ wxSizerFlags(1).Expand().Border()
+ );
+
+ dlg.SetSizer(sizer);
+ dlg.SetClientSize(400, 200);
+
+ dlg.ShowModal();
+}
void MyFrame::OnAboutToolOrMenuCommand(wxCommandEvent& WXUNUSED(event))
{
void OnPlatformPropertyToolOrMenuCommand(wxCommandEvent& event);
void OnArtProviderToolOrMenuCommand(wxCommandEvent& event);
void OnVariableExpansionToolOrMenuCommand(wxCommandEvent& event);
+ void OnRecursiveLoad(wxCommandEvent& event);
void OnAnimationCtrlPlay(wxCommandEvent& event);
// Any class wishing to process wxWidgets events must use this macro
<bitmap>variable.xpm</bitmap>
<help>Replace variables in the XRC file at runtime</help>
</object>
+ <object class="wxMenuItem" name="recursive_load">
+ <label>_Recursive Load</label>
+ <help>Show how an individual control can be loaded</help>
+ </object>
</object>
<object class="wxMenu" name="help_menu">
<label>_Help</label>
}
-wxObject *wxXmlResource::LoadObject(wxWindow *parent, const wxString& name, const wxString& classname)
+wxObject *
+wxXmlResource::DoLoadObject(wxWindow *parent,
+ const wxString& name,
+ const wxString& classname,
+ bool recursive)
{
- return CreateResFromNode(FindResource(name, classname), parent, NULL);
+ wxXmlNode * const node = FindResource(name, classname, recursive);
+
+ return node ? DoCreateResFromNode(*node, parent, NULL) : NULL;
}
-bool wxXmlResource::LoadObject(wxObject *instance, wxWindow *parent, const wxString& name, const wxString& classname)
+bool
+wxXmlResource::DoLoadObject(wxObject *instance,
+ wxWindow *parent,
+ const wxString& name,
+ const wxString& classname,
+ bool recursive)
{
- return CreateResFromNode(FindResource(name, classname), parent, instance) != NULL;
+ wxXmlNode * const node = FindResource(name, classname, recursive);
+
+ return node && DoCreateResFromNode(*node, parent, instance) != NULL;
}
dest.SetContent(overwriteWith.GetContent());
}
-wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent,
- wxObject *instance,
- wxXmlResourceHandler *handlerToUse)
+wxObject *
+wxXmlResource::DoCreateResFromNode(wxXmlNode& node,
+ wxObject *parent,
+ wxObject *instance,
+ wxXmlResourceHandler *handlerToUse)
{
- if (node == NULL) return NULL;
-
// handling of referenced resource
- if ( node->GetName() == wxT("object_ref") )
+ if ( node.GetName() == wxT("object_ref") )
{
- wxString refName = node->GetAttribute(wxT("ref"), wxEmptyString);
+ wxString refName = node.GetAttribute(wxT("ref"), wxEmptyString);
wxXmlNode* refNode = FindResource(refName, wxEmptyString, true);
if ( !refNode )
{
ReportError
(
- node,
+ &node,
wxString::Format
(
"referenced object node with ref=\"%s\" not found",
return NULL;
}
- if ( !node->GetChildren() )
+ if ( !node.GetChildren() )
{
// In the typical, simple case, <object_ref> is used to link
// to another node and doesn't have any content of its own that
// would overwrite linked object's properties. In this case,
// we can simply create the resource from linked node.
- return CreateResFromNode(refNode, parent, instance);
+ return DoCreateResFromNode(*refNode, parent, instance);
}
else
{
// load the resource from result of the merge.
wxXmlNode copy(*refNode);
- MergeNodesOver(copy, *node, GetFileNameFromNode(node, Data()));
+ MergeNodesOver(copy, node, GetFileNameFromNode(&node, Data()));
// remember referenced object's file, see GetFileNameFromNode()
copy.AddAttribute(ATTR_INPUT_FILENAME,
GetFileNameFromNode(refNode, Data()));
- return CreateResFromNode(©, parent, instance);
+ return DoCreateResFromNode(copy, parent, instance);
}
}
if (handlerToUse)
{
- if (handlerToUse->CanHandle(node))
+ if (handlerToUse->CanHandle(&node))
{
- return handlerToUse->CreateResource(node, parent, instance);
+ return handlerToUse->CreateResource(&node, parent, instance);
}
}
- else if (node->GetName() == wxT("object"))
+ else if (node.GetName() == wxT("object"))
{
for ( wxVector<wxXmlResourceHandler*>::iterator h = m_handlers.begin();
h != m_handlers.end(); ++h )
{
wxXmlResourceHandler *handler = *h;
- if (handler->CanHandle(node))
- return handler->CreateResource(node, parent, instance);
+ if (handler->CanHandle(&node))
+ return handler->CreateResource(&node, parent, instance);
}
}
ReportError
(
- node,
+ &node,
wxString::Format
(
"no handler found for XML node \"%s\" (class \"%s\")",
- node->GetName(),
- node->GetAttribute("class", wxEmptyString)
+ node.GetName(),
+ node.GetAttribute("class", wxEmptyString)
)
);
return NULL;
{
if ( IsObjectNode(n) )
{
- m_resource->CreateResFromNode(n, parent, NULL,
- this_hnd_only ? this : NULL);
+ m_resource->DoCreateResFromNode(*n, parent, NULL,
+ this_hnd_only ? this : NULL);
}
}
}