1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the demonstration applications of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:BSD$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** BSD License Usage 18 ** Alternatively, you may use this file under the terms of the BSD license 19 ** as follows: 20 ** 21 ** "Redistribution and use in source and binary forms, with or without 22 ** modification, are permitted provided that the following conditions are 23 ** met: 24 ** * Redistributions of source code must retain the above copyright 25 ** notice, this list of conditions and the following disclaimer. 26 ** * Redistributions in binary form must reproduce the above copyright 27 ** notice, this list of conditions and the following disclaimer in 28 ** the documentation and/or other materials provided with the 29 ** distribution. 30 ** * Neither the name of The Qt Company Ltd nor the names of its 31 ** contributors may be used to endorse or promote products derived 32 ** from this software without specific prior written permission. 33 ** 34 ** 35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 46 ** 47 ** $QT_END_LICENSE$ 48 ** 49 ****************************************************************************/ 50 51 #ifndef COMPOSITION_H 52 #define COMPOSITION_H 53 54 #include "arthurwidgets.h" 55 56 #if QT_CONFIG(opengl) 57 #include "fbopaintdevice.h" 58 #include <QOpenGLTextureBlitter> 59 #endif 60 61 #include <QPainter> 62 #include <QEvent> 63 64 #include <memory> 65 66 QT_BEGIN_NAMESPACE 67 class QPushButton; 68 class QRadioButton; 69 QT_END_NAMESPACE 70 71 class CompositionWidget : public QWidget 72 { 73 Q_OBJECT 74 75 public: 76 explicit CompositionWidget(QWidget *parent = nullptr); 77 ~CompositionWidget(); 78 79 public slots: 80 void nextMode(); 81 82 private: 83 bool m_cycle_enabled; 84 85 QRadioButton *rbClear; 86 QRadioButton *rbSource; 87 QRadioButton *rbDest; 88 QRadioButton *rbSourceOver; 89 QRadioButton *rbDestOver; 90 QRadioButton *rbSourceIn; 91 QRadioButton *rbDestIn; 92 QRadioButton *rbSourceOut; 93 QRadioButton *rbDestOut; 94 QRadioButton *rbSourceAtop; 95 QRadioButton *rbDestAtop; 96 QRadioButton *rbXor; 97 98 QRadioButton *rbPlus; 99 QRadioButton *rbMultiply; 100 QRadioButton *rbScreen; 101 QRadioButton *rbOverlay; 102 QRadioButton *rbDarken; 103 QRadioButton *rbLighten; 104 QRadioButton *rbColorDodge; 105 QRadioButton *rbColorBurn; 106 QRadioButton *rbHardLight; 107 QRadioButton *rbSoftLight; 108 QRadioButton *rbDifference; 109 QRadioButton *rbExclusion; 110 }; 111 112 class CompositionRenderer : public ArthurFrame 113 { 114 Q_OBJECT 115 116 enum ObjectType { NoObject, Circle, Rectangle, Image }; 117 118 Q_PROPERTY(int circleColor READ circleColor WRITE setCircleColor) 119 Q_PROPERTY(int circleAlpha READ circleAlpha WRITE setCircleAlpha) 120 Q_PROPERTY(bool animation READ animationEnabled WRITE setAnimationEnabled) 121 122 public: 123 explicit CompositionRenderer(QWidget *parent = nullptr); 124 ~CompositionRenderer(); 125 126 void paint(QPainter *) override; 127 128 void setCirclePos(const QPointF &pos); 129 sizeHint()130 QSize sizeHint() const override { return QSize(500, 400); } 131 animationEnabled()132 bool animationEnabled() const { return m_animation_enabled; } circleColor()133 int circleColor() const { return m_circle_hue; } circleAlpha()134 int circleAlpha() const { return m_circle_alpha; } 135 136 protected: 137 void mousePressEvent(QMouseEvent *) override; 138 void mouseMoveEvent(QMouseEvent *) override; 139 void mouseReleaseEvent(QMouseEvent *) override; 140 void timerEvent(QTimerEvent *) override; 141 142 public slots: setClearMode()143 void setClearMode() { m_composition_mode = QPainter::CompositionMode_Clear; update(); } setSourceMode()144 void setSourceMode() { m_composition_mode = QPainter::CompositionMode_Source; update(); } setDestMode()145 void setDestMode() { m_composition_mode = QPainter::CompositionMode_Destination; update(); } setSourceOverMode()146 void setSourceOverMode() { m_composition_mode = QPainter::CompositionMode_SourceOver; update(); } setDestOverMode()147 void setDestOverMode() { m_composition_mode = QPainter::CompositionMode_DestinationOver; update(); } setSourceInMode()148 void setSourceInMode() { m_composition_mode = QPainter::CompositionMode_SourceIn; update(); } setDestInMode()149 void setDestInMode() { m_composition_mode = QPainter::CompositionMode_DestinationIn; update(); } setSourceOutMode()150 void setSourceOutMode() { m_composition_mode = QPainter::CompositionMode_SourceOut; update(); } setDestOutMode()151 void setDestOutMode() { m_composition_mode = QPainter::CompositionMode_DestinationOut; update(); } setSourceAtopMode()152 void setSourceAtopMode() { m_composition_mode = QPainter::CompositionMode_SourceAtop; update(); } setDestAtopMode()153 void setDestAtopMode() { m_composition_mode = QPainter::CompositionMode_DestinationAtop; update(); } setXorMode()154 void setXorMode() { m_composition_mode = QPainter::CompositionMode_Xor; update(); } 155 setPlusMode()156 void setPlusMode() { m_composition_mode = QPainter::CompositionMode_Plus; update(); } setMultiplyMode()157 void setMultiplyMode() { m_composition_mode = QPainter::CompositionMode_Multiply; update(); } setScreenMode()158 void setScreenMode() { m_composition_mode = QPainter::CompositionMode_Screen; update(); } setOverlayMode()159 void setOverlayMode() { m_composition_mode = QPainter::CompositionMode_Overlay; update(); } setDarkenMode()160 void setDarkenMode() { m_composition_mode = QPainter::CompositionMode_Darken; update(); } setLightenMode()161 void setLightenMode() { m_composition_mode = QPainter::CompositionMode_Lighten; update(); } setColorDodgeMode()162 void setColorDodgeMode() { m_composition_mode = QPainter::CompositionMode_ColorDodge; update(); } setColorBurnMode()163 void setColorBurnMode() { m_composition_mode = QPainter::CompositionMode_ColorBurn; update(); } setHardLightMode()164 void setHardLightMode() { m_composition_mode = QPainter::CompositionMode_HardLight; update(); } setSoftLightMode()165 void setSoftLightMode() { m_composition_mode = QPainter::CompositionMode_SoftLight; update(); } setDifferenceMode()166 void setDifferenceMode() { m_composition_mode = QPainter::CompositionMode_Difference; update(); } setExclusionMode()167 void setExclusionMode() { m_composition_mode = QPainter::CompositionMode_Exclusion; update(); } 168 setCircleAlpha(int alpha)169 void setCircleAlpha(int alpha) { m_circle_alpha = alpha; update(); } setCircleColor(int hue)170 void setCircleColor(int hue) { m_circle_hue = hue; update(); } 171 void setAnimationEnabled(bool enabled); 172 173 private: 174 void updateCirclePos(); 175 void drawBase(QPainter &p); 176 void drawSource(QPainter &p); 177 178 QPainter::CompositionMode m_composition_mode; 179 180 QImage m_image; 181 QImage m_buffer; 182 QImage m_base_buffer; 183 184 int m_circle_alpha; 185 int m_circle_hue; 186 187 QPointF m_circle_pos; 188 QPointF m_offset; 189 190 ObjectType m_current_object; 191 bool m_animation_enabled; 192 int m_animationTimer; 193 194 #if QT_CONFIG(opengl) 195 std::unique_ptr<QFboPaintDevice> m_fbo; 196 int m_pbuffer_size; // width==height==size of pbuffer 197 uint m_base_tex; 198 uint m_compositing_tex; 199 QSize m_previous_size; 200 QOpenGLTextureBlitter m_blitter; 201 #endif 202 }; 203 204 #endif // COMPOSITION_H 205