1 /***************************************************************************
2         LogoWidget.cpp  -  widget with the animated Kwave logo
3                              -------------------
4     begin                : Sun Oct 29 2000
5     copyright            : (C) 2000 by Thomas Eschenbacher
6     email                : Thomas.Eschenbacher@gmx.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "config.h"
19 
20 #include <math.h>
21 #include <new>
22 
23 #include <QBrush>
24 #include <QColor>
25 #include <QImage>
26 #include <QObject>
27 #include <QPainter>
28 #include <QPalette>
29 #include <QPolygon>
30 #include <QTimer>
31 
32 #include "libkwave/Utils.h"
33 
34 #include "LogoWidget.h"
35 #include "logo.xpm"
36 
37 /** increment value of the "h" channel of the color of the sine waves */
38 #define COLOR_INCREMENT (static_cast<double>(0.001))
39 
40 //***************************************************************************
LogoWidget(QWidget * parent)41 Kwave::LogoWidget::LogoWidget(QWidget *parent)
42     :QWidget(parent), m_width(-1), m_height(-1), m_repaint(false),
43      m_image(Q_NULLPTR), m_logo(xpm_aboutlogo), m_timer(Q_NULLPTR),
44      m_color_h(0.0)
45 {
46     for (int i = 0; i < MAXSIN; m_deg[i++] = 0) {}
47 
48     m_timer = new(std::nothrow) QTimer(this);
49     Q_ASSERT(m_timer);
50     if (!m_timer) return;
51     connect(m_timer, SIGNAL(timeout()), this, SLOT(doAnim()));
52 
53     // gives 40ms refresh ;-)...
54     m_timer->setInterval(40);
55     m_timer->start();
56 
57     QPalette pal = palette();
58     pal.setColor(QPalette::Window, Qt::black);
59     setPalette(pal);
60 }
61 
62 //***************************************************************************
doAnim()63 void Kwave::LogoWidget::doAnim()
64 {
65     double mul = 0.04131211 + m_deg[MAXSIN-1] / 75;
66 
67     for (int i = 0; i < MAXSIN; i++) {
68 	m_deg[i] += mul;
69 	if (m_deg[i] > 2 * M_PI) m_deg[i] = 0;
70 	mul  = ((mul * 521)/437);
71 	mul -= floor(mul);  // gives again a number between 0 and 1
72 	mul /= 17;
73 	mul += m_deg[i] / 100; //so that chaos may be ...
74     }
75 
76     m_repaint = true;
77     repaint();
78 }
79 
80 //***************************************************************************
~LogoWidget()81 Kwave::LogoWidget::~LogoWidget()
82 {
83     if (m_timer) delete m_timer;
84     if (m_image) delete m_image;
85 }
86 
87 //***************************************************************************
paintEvent(QPaintEvent *)88 void Kwave::LogoWidget::paintEvent(QPaintEvent *)
89 {
90     // if image has to be resized ...
91     if ((rect().height() != m_height) || (rect().width() != m_width)) {
92 	m_height = rect().height();
93 	m_width  = rect().width();
94 
95 	if (m_image) delete m_image;
96 	m_image = new(std::nothrow)
97 	    QImage(size(), QImage::Format_ARGB32_Premultiplied);
98 	m_repaint = true;
99     }
100 
101     if (!m_image) return;
102 
103     if (m_repaint) {
104 	QPainter p;
105 	QPolygon si(20 + 3);
106 
107 	p.begin(m_image);
108 
109 	// erase everything to black
110 	p.setPen(Qt::black);
111 	p.setBrush(Qt::black);
112 	p.drawRect(0, 0, m_width, m_height);
113 
114 	// blit logo bitmap
115 	int ampx = (m_logo.width()  - m_width ) / 2;
116 	int ampy = (m_logo.height() - m_height) / 2;
117 	p.setCompositionMode(QPainter::CompositionMode_Source);
118 	p.drawPixmap(
119 	    -ampx + Kwave::toInt(sin(m_deg[0]) * ampx),
120 	    -ampy + Kwave::toInt(sin(m_deg[1]) * ampy),
121 	    m_logo);
122 
123 	// draw the sine waves with XOR
124 	p.setCompositionMode(QPainter::CompositionMode_Exclusion);
125 	p.setBrush(QColor::fromHsvF(m_color_h, 1.0, 1.0));
126 	m_color_h += COLOR_INCREMENT; // this gives the nice color change :-)
127 	if (m_color_h > 1.0) m_color_h -= 1.0;
128 
129 	double amp = sin(m_deg[MAXSIN - 1] * 3);
130 	for (int j = 0; j < MAXSIN; j++) {
131 	    for (int i = 0; i < 21; i++) {
132 		si.setPoint(i, (j * m_width / MAXSIN) +
133 		    Kwave::toInt(amp * sin(M_PI * i / 10 + m_deg[j])
134 			* m_width / 2),
135 		    m_height * i / 20);
136 	    }
137 	    si.setPoint(21, m_width / 2, m_height);
138 	    si.setPoint(22, m_width / 2, 0);
139 
140 	    p.drawPolygon(si);
141 	    amp = sin(m_deg[j] * 3);
142 	}
143 
144 	p.end();
145 	m_repaint = false;
146     }
147 
148     // blit the result to the display
149     QPainter p(this);
150     p.drawImage(0, 0, *m_image);
151     p.end();
152 }
153 
154 //***************************************************************************
155 //***************************************************************************
156