File: XmlResourceBasedWidget.h

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (140 lines) | stat: -rw-r--r-- 4,105 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#pragma once

#include <wx/xrc/xmlres.h>
#include <wx/toolbar.h>
#include <wx/panel.h>
#include <wx/stattext.h>
#include <wx/spinctrl.h>
#include <wx/sizer.h>

namespace wxutil
{

/**
 * Base class for wxWindows that load all (or parts of their) controls
 * from an XRC file in the application's ui/ directory.
 */
class XmlResourceBasedWidget
{
protected:
	// Loads a named Panel from the XRC resources
	wxPanel* loadNamedPanel(wxWindow* parent, const std::string& name)
	{
		wxPanel* panel = wxXmlResource::Get()->LoadPanel(parent, name);

		assert(panel != NULL);

		return panel;
	}

	static const wxToolBarToolBase* getToolBarToolByLabel(wxToolBarBase* toolbar, const std::string& name)
	{
		wxString wxName(name);

		for (unsigned int i = 0; i < toolbar->GetToolsCount(); i++)
		{
			const wxToolBarToolBase* candidate = toolbar->GetToolByPos(i);

			if (candidate->GetLabel() == wxName)
			{
				return candidate;
			}
		}

		return nullptr;
	}

    // Tries to find the toolbar item hosting the named control
    static const wxToolBarToolBase* getToolBarControlByName(wxToolBarBase* toolbar, const std::string& name)
    {
        wxString wxName(name);

        for (unsigned int i = 0; i < toolbar->GetToolsCount(); i++)
        {
            const wxToolBarToolBase* candidate = toolbar->GetToolByPos(i);

            if (candidate->IsControl() && candidate->GetControl()->GetName() == name)
            {
                return candidate;
            }
        }

        return nullptr;
    }

    /// Look up a toolbar tool by label and return its ID
    static int getToolID(wxToolBarBase* toolbar, const std::string& label)
    {
        auto tool = getToolBarToolByLabel(toolbar, label);
        if (tool)
            return tool->GetId();
        else
            return wxID_NONE;
    }

	// Find a named panel among the parent's children
	wxPanel* findNamedPanel(wxWindow* parent, const std::string& name)
	{
		return findNamedObject<wxPanel>(parent, name);
	}

	// Find a named object among the parent's children
    template <typename ObjectClass>
    ObjectClass* findNamedObject(const wxWindow* parent, const std::string& name) const
    {
        auto* named = dynamic_cast<ObjectClass*>(parent->FindWindow(wxString(name)));
        wxASSERT_MSG(named, "findNamedObject() failed (child not found)");

        return named;
    }

    // Find a named panel among the parent's children, doesn't throw when the item is not found
	template<typename ObjectClass>
	ObjectClass* tryGetNamedObject(wxWindow* parent, const std::string& name)
	{
		wxString wxName(name);

		ObjectClass* named = dynamic_cast<ObjectClass*>(parent->FindWindow(name));

		return named;
	}

	void makeLabelBold(wxWindow* parent, const std::string& widgetName)
	{
		wxStaticText* text = findNamedObject<wxStaticText>(parent, widgetName);
		text->SetFont(text->GetFont().Bold());
	}

    void replaceControl(wxWindow* oldCtrl, wxWindow* newCtrl)
    {
        bool wasEnabled = oldCtrl->IsEnabled();
        auto name = oldCtrl->GetName();
        auto minSize = oldCtrl->GetMinSize();
        oldCtrl->GetContainingSizer()->Replace(oldCtrl, newCtrl);
        oldCtrl->Destroy();

        newCtrl->SetName(name);
        newCtrl->Enable(wasEnabled);
        newCtrl->SetMinSize(minSize);
        newCtrl->GetContainingSizer()->Layout();
    }

    // Swaps out the wxSpinCtrl with wxSpinCtrlDouble
    // This is a workaround for http://trac.wxwidgets.org/ticket/15425 - wxGTK < 3.1.1 don't ship an XRC handler for wxSpinCtrlDouble
    wxSpinCtrlDouble* convertToSpinCtrlDouble(wxWindow* parent, const std::string& nameOfControlToReplace, double min, double max, double increment, int digits)
    {
        auto oldCtrl = findNamedObject<wxSpinCtrl>(parent, nameOfControlToReplace);

        auto spinCtrlDouble = new wxSpinCtrlDouble(oldCtrl->GetParent(), wxID_ANY);

        spinCtrlDouble->SetRange(min, max);
        spinCtrlDouble->SetDigits(digits);
        spinCtrlDouble->SetIncrement(increment);

        replaceControl(oldCtrl, spinCtrlDouble);

        return spinCtrlDouble;
    }
};

} // namespace