MythTV master
mythpainter_qt.cpp
Go to the documentation of this file.
1
2// QT headers
3#include <QPainter>
4#include <QPixmap>
5
6// MythUI headers
7#include "mythpainter_qt.h"
9#include "mythmainwindow.h"
10
11// MythDB headers
12#include "libmythbase/compat.h"
14
15class MythQtImage : public MythImage
16{
17 public:
18 explicit MythQtImage(MythQtPainter *parent) :
19 MythImage(parent, "MythQtImage") { }
20
21 void SetChanged(bool change = true) override; // MythImage
22 QPixmap *GetPixmap(void) { return m_pixmap; }
23 void SetPixmap(QPixmap *p) { m_pixmap = p; }
24
25 bool NeedsRegen(void) const { return m_bRegenPixmap; }
26 void RegeneratePixmap(void);
27
28 protected:
29 QPixmap *m_pixmap {nullptr};
30 bool m_bRegenPixmap {false};
31};
32
33void MythQtImage::SetChanged(bool change)
34{
35 if (change)
36 m_bRegenPixmap = true;
37
39}
40
42{
43 // We allocate the pixmap here so it is done in the UI
44 // thread since QPixmap uses non-reentrant X calls.
45 if (!m_pixmap)
46 m_pixmap = new QPixmap;
47
48 if (m_pixmap)
49 {
50 *m_pixmap = QPixmap::fromImage(*((QImage *)this));
51 m_bRegenPixmap = false;
52 }
53}
54
56{
57 Teardown();
59}
60
62{
63 QMutexLocker locker(&m_imageDeleteLock);
64 while (!m_imageDeleteList.empty())
65 {
66 QPixmap *pm = m_imageDeleteList.front();
67 m_imageDeleteList.pop_front();
68 delete pm;
69 }
70}
71
72void MythQtPainter::Begin(QPaintDevice *parent)
73{
74 if (!parent)
75 {
76 LOG(VB_GENERAL, LOG_ERR,
77 "FATAL ERROR: No parent widget defined for QT Painter, bailing");
78 return;
79 }
80
81 MythPainter::Begin(parent);
82
83 m_painter = new QPainter(parent);
84 m_clipRegion = QRegion(QRect(0, 0, 0, 0));
85
87}
88
90{
91 m_painter->end();
92 delete m_painter;
93
95}
96
97void MythQtPainter::SetClipRect(const QRect clipRect)
98{
99 m_painter->setClipRect(clipRect);
100 if (!clipRect.isEmpty())
101 {
102 m_painter->setClipping(true);
103 if (m_clipRegion.isEmpty())
104 m_clipRegion = QRegion(clipRect);
105 else
106 m_clipRegion = m_clipRegion.united(clipRect);
107 }
108 else
109 {
110 m_painter->setClipping(false);
111 }
112}
113
114void MythQtPainter::DrawImage(const QRect r, MythImage *im,
115 const QRect src, int alpha)
116{
117 if (!m_painter)
118 {
119 LOG(VB_GENERAL, LOG_ERR,
120 "FATAL ERROR: DrawImage called with no painter");
121 return;
122 }
123
124 auto *qim = reinterpret_cast<MythQtImage *>(im);
125
126 if (qim->NeedsRegen())
127 qim->RegeneratePixmap();
128
129 m_painter->setOpacity(static_cast<qreal>(alpha) / 255.0);
130 m_painter->drawPixmap(r.topLeft(), *(qim->GetPixmap()), src);
131 m_painter->setOpacity(1.0);
132}
133
135{
136 return new MythQtImage(this);
137}
138
140{
141 auto *qim = dynamic_cast<MythQtImage *>(im);
142
143 QMutexLocker locker(&m_imageDeleteLock);
144 if (qim && qim->GetPixmap())
145 {
146 m_imageDeleteList.push_back(qim->GetPixmap());
147 qim->SetPixmap(nullptr);
148 }
149}
virtual void SetChanged(bool change=true)
Definition: mythimage.h:50
virtual void Begin(QPaintDevice *)
Definition: mythpainter.h:54
virtual void End()
Definition: mythpainter.h:55
virtual void Teardown(void)
Definition: mythpainter.cpp:27
MythQtImage(MythQtPainter *parent)
void SetPixmap(QPixmap *p)
void SetChanged(bool change=true) override
void RegeneratePixmap(void)
QPixmap * m_pixmap
QPixmap * GetPixmap(void)
bool NeedsRegen(void) const
QRegion m_clipRegion
~MythQtPainter() override
QMutex m_imageDeleteLock
void SetClipRect(QRect clipRect) override
void Begin(QPaintDevice *parent) override
void DrawImage(QRect r, MythImage *im, QRect src, int alpha) override
MythImage * GetFormatImagePriv(void) override
Creates a reference counted image, call DecrRef() to delete.
std::list< QPixmap * > m_imageDeleteList
void End() override
void DeletePixmaps(void)
QPainter * m_painter
void DeleteFormatImagePriv(MythImage *im) override
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39