summaryrefslogtreecommitdiffstats
path: root/src/widget/wsingletoncontainer.h
blob: 87812d4f9451b0e80b7746b97398be9780759f55 (plain)
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
// WSingletonContainer defines widgets that should only be instantiated once
// but may appear in multiple places in a skin definition.  This is useful
// for complex widgets like the library, which are memory intensive. The
// container mostly looks similar to a WidgetGroup, but is very lightweight
// and only supports the ObjectName and Children tags, and only one child
// can be specified.  More complicated layout should be done inside the
// defined child itself or the SingletonContainer.
//
// Usage:
// First, the Singleton container is defined, meaning it is described to the
// skin system by name, and what the singleton consists of.  This definition
// must occur before the SingletonContainer elements which define where the
// singleton will appear.  Note that the singleton does not actually appear
// where it is defined.
//
// Example definition:
// <SingletonDefinition>
//   <ObjectName>LibrarySingleton</ObjectName>
//   <Children>
//     <Template src="skin:library.xml"/>
//   </Children>
// </SingletonDefinition>
//
// The ObjectName is used to identify this singleton elsewhere in the skin
// files.  The SingletonContainer does obey standard widget properties like
// SizePolicy and TooltipId.
//
// Example usage:
// <WidgetGroup>
//    <ObjectName>SomeUiElement</ObjectName>
//    <Layout>vertical</Layout>
//    <SizePolicy>min,i</SizePolicy>
//    <Children>
//      <SingletonContainer>
//        <SizePolicy>me,me</SizePolicy>
//        <ObjectName>LibrarySingleton</ObjectName>
//      </SingletonContainer
//      ...
//    </Children>
// </WidgetGroup>
//
// The skin system sees the Singleton tag, and any time the containing
// group gets a show event, the Singleton widget is reparented to this location
// in the skin.  Note that if a Singleton is visible twice at the same time,
// behavior is undefined and could be crashy.

#ifndef WSINGLETONCONTAINER_H
#define WSINGLETONCONTAINER_H

#include <QPointer>

#include "widget/wwidgetgroup.h"

class WSingletonContainer : public WWidgetGroup {
    Q_OBJECT
  public:
    // Prepares the container and remembers the widget, but does not add the
    // widget to the container.
    explicit WSingletonContainer(QWidget* pParent=nullptr);

    void setup(const QDomNode& node, const SkinContext& context) override;

  public slots:
    void showEvent(QShowEvent* event) override;

  private:
    QPointer<QWidget> m_pWidget;
    QLayout* m_pLayout;
};

class SingletonMap {
  public:
    // Takes a constructed QWidget and inserts it in the map of available
    // singletons.  Checks that an object of that name hasn't already been
    // defined.
    void insertSingleton(QString objectName, QWidget* widget);

    // We don't want to end up with badly-constructed containers, so only
    // provide a factory function.  Returns NULL if the objectName is not in
    // the map.
    QWidget* getSingletonWidget(QString objectName) const;

  private:
    QMap<QString, QWidget*> m_singletons;
};


#endif  // WSINGLETONCONTAINER_H