TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicspectrumwidget.cpp
Go to the documentation of this file.
1 #include "musicspectrumwidget.h"
2 #include "ui_musicspectrumwidget.h"
3 #include "musicqmmputils.h"
4 #include "musicformats.h"
5 #include "musictoastlabel.h"
6 #include "musicwidgetheaders.h"
7 #include "musictopareawidget.h"
8 #include "musicfileutils.h"
9 
10 #include <QPluginLoader>
11 
12 #include <qmmp/florid.h>
13 #include <qmmp/visualfactory.h>
14 #include <qmmp/lightfactory.h>
15 #include <qmmp/soundcore.h>
16 
17 static constexpr const char *LIGHT_WAVEFORM_MODULE = "lightwaveform";
18 static constexpr const char *LIGHT_SPECTROGRAM_MODULE = "lightspectrogram";
19 
22  m_ui(new Ui::MusicSpectrumWidget),
23  m_spectrumLayout(nullptr)
24 {
25  m_ui->setupUi(this);
26  setMinimumSize(750, 650);
27  setAttribute(Qt::WA_DeleteOnClose);
28  setBackgroundLabel(m_ui->background);
29 
30  setStyleSheet(TTK::UI::MenuStyle02);
31 
32  m_ui->topTitleCloseButton->setIcon(QIcon(":/functions/btn_close_hover"));
33  m_ui->topTitleCloseButton->setStyleSheet(TTK::UI::ToolButtonStyle04);
34  m_ui->topTitleCloseButton->setCursor(QCursor(Qt::PointingHandCursor));
35  m_ui->topTitleCloseButton->setToolTip(tr("Close"));
36  connect(m_ui->topTitleCloseButton, SIGNAL(clicked()), SLOT(close()));
37 
38  m_ui->mainViewWidget->setStyleSheet(TTK::UI::TabWidgetStyle01);
39 
40  m_ui->localFileButton->setStyleSheet(TTK::UI::PushButtonStyle04);
41  m_ui->localFileButton->setCursor(QCursor(Qt::PointingHandCursor));
42  m_ui->openFileButton->setStyleSheet(TTK::UI::PushButtonStyle04);
43  m_ui->openFileButton->setCursor(QCursor(Qt::PointingHandCursor));
44 
45  m_ui->spectrumNormalLayoutButton->setStyleSheet(TTK::UI::ToolButtonStyle05);
46  m_ui->spectrumPlusLayoutButton->setStyleSheet(TTK::UI::ToolButtonStyle05);
47  m_ui->spectrumWaveLayoutButton->setStyleSheet(TTK::UI::ToolButtonStyle05);
48  m_ui->spectrumFlowLayoutButton->setStyleSheet(TTK::UI::ToolButtonStyle05);
49  m_ui->spectrumFloridLayoutButton->setStyleSheet(TTK::UI::ToolButtonStyle05);
50 
51 #ifdef Q_OS_UNIX
52  m_ui->spectrumNormalLayoutButton->setFocusPolicy(Qt::NoFocus);
53  m_ui->spectrumPlusLayoutButton->setFocusPolicy(Qt::NoFocus);
54  m_ui->spectrumWaveLayoutButton->setFocusPolicy(Qt::NoFocus);
55  m_ui->spectrumFlowLayoutButton->setFocusPolicy(Qt::NoFocus);
56  m_ui->spectrumFloridLayoutButton->setFocusPolicy(Qt::NoFocus);
57  m_ui->localFileButton->setFocusPolicy(Qt::NoFocus);
58  m_ui->openFileButton->setFocusPolicy(Qt::NoFocus);
59 #endif
60  setObjectsTracking({m_ui->background});
62 
63  connect(m_ui->localFileButton, SIGNAL(clicked()), SLOT(localFileButtonClicked()));
64  connect(m_ui->openFileButton, SIGNAL(clicked()), SLOT(openFileButtonClicked()));
65  connect(m_ui->spectrumNormalLayoutButton, SIGNAL(stateChanged(bool&,QString)), SLOT(spectrumNormalTypeChanged(bool&,QString)));
66  connect(m_ui->spectrumPlusLayoutButton, SIGNAL(stateChanged(bool&,QString)), SLOT(spectrumPlusTypeChanged(bool&,QString)));
67  connect(m_ui->spectrumWaveLayoutButton, SIGNAL(stateChanged(bool&,QString)), SLOT(spectrumWaveTypeChanged(bool&,QString)));
68  connect(m_ui->spectrumFlowLayoutButton, SIGNAL(stateChanged(bool&,QString)), SLOT(spectrumFlowTypeChanged(bool&,QString)));
69  connect(m_ui->spectrumFloridLayoutButton, SIGNAL(stateChanged(bool&,QString)), SLOT(spectrumFloridTypeChanged(bool&,QString)));
70 }
71 
73 {
74  TTKRemoveSingleWidget(className());
75  for(const MusicSpectrum &type : qAsConst(m_types))
76  {
77  TTK::TTKQmmp::enabledVisualPlugin(type.m_module, false);
78  }
79  delete m_ui;
80 }
81 
83 {
84  createSpectrumWidget(MusicSpectrum::Module::Normal, state, name, m_ui->spectrumNormalAreaLayout);
85 }
86 
88 {
89  createSpectrumWidget(MusicSpectrum::Module::Plus, state, name, m_ui->spectrumPlusAreaLayout);
90 }
91 
93 {
94  if(name == LIGHT_WAVEFORM_MODULE)
95  {
96  createLightWidget(MusicSpectrum::Module::Light, state, name, m_ui->spectrumWaveAreaLayout);
97  }
98  else
99  {
100  createSpectrumWidget(MusicSpectrum::Module::Wave, state, name, m_ui->spectrumWaveAreaLayout);
101  }
102 }
103 
105 {
106  createFlowWidget(MusicSpectrum::Module::Flow, state, name, m_ui->spectrumFlowAreaLayout);
107 }
108 
110 {
111  createFloridWidget(MusicSpectrum::Module::Florid, state, name, m_ui->spectrumFloridAreaLayout);
112 }
113 
115 {
116  bool state = true;
118 }
119 
121 {
123  if(!path.isEmpty())
124  {
125  bool state = true;
126  createLightWidget(MusicSpectrum::Module::Light, state, LIGHT_SPECTROGRAM_MODULE, m_ui->spectrumLightAreaLayout, path);
127  }
128 }
129 
130 void MusicSpectrumWidget::fullscreenByUser(QWidget *widget, bool state)
131 {
132  if(state)
133  {
134  QWidget *parent = TTKObjectCast(QWidget*, widget->parent());
135  if(parent)
136  {
137  m_spectrumLayout = parent->layout();
138  widget->setParent(nullptr);
139  widget->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
140  widget->showFullScreen();
141  }
142  }
143  else
144  {
145  if(m_spectrumLayout)
146  {
147 #ifdef Q_OS_WIN
148  widget->showNormal();
149  widget->setWindowFlags(Qt::Window);
150  m_spectrumLayout->addWidget(widget);
151 #else
152  MusicSpectrum type;
153  for(int i = 0; i < m_types.count(); ++i)
154  {
155  if(m_types[i].m_object == widget)
156  {
157  type = m_types.takeAt(i);
158  break;
159  }
160  }
161 
162  if(type.m_module.isEmpty())
163  {
164  return;
165  }
166 
168 
169  bool state = true;
170  switch(type.m_type)
171  {
178  default: break;
179  }
180 #endif
181  }
182  }
183 }
184 
186 {
187  MusicAbstractMoveResizePlainWidget::mouseDoubleClickEvent(event);
188  if(event->buttons() == Qt::LeftButton)
189  {
190  isMaximized() ? showNormal() : showMaximized();
191  }
192 }
193 
194 void MusicSpectrumWidget::createSpectrumWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
195 {
196  if(state)
197  {
198  const int before = Visual::visuals()->count();
200  const QList<Visual*> *vs = Visual::visuals();
201  if(before == vs->count())
202  {
204  state = false;
205  return;
206  }
207 
208  if(!vs->isEmpty())
209  {
210  MusicSpectrum type;
211  type.m_module = name;
212  type.m_object = vs->back();
213  type.m_type = spectrum;
214  m_types << type;
215  layout->addWidget(type.m_object);
216  type.m_object->setStyleSheet(TTK::UI::MenuStyle02);
217 
218  connect(type.m_object, SIGNAL(fullscreenByUser(QWidget*,bool)), SLOT(fullscreenByUser(QWidget*,bool)));
219  }
220  else
221  {
223  state = false;
224  }
225  }
226  else
227  {
228  const int index = findSpectrumWidget(name);
229  if(index != -1)
230  {
231  const MusicSpectrum &type = m_types.takeAt(index);
232  layout->removeWidget(type.m_object);
234  }
235  }
236 }
237 
238 void MusicSpectrumWidget::createFlowWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
239 {
240  createModuleWidget(spectrum, state, name, layout, false);
241 }
242 
243 void MusicSpectrumWidget::createFloridWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
244 {
245  createModuleWidget(spectrum, state, name, layout, true);
246 }
247 
248 void MusicSpectrumWidget::createModuleWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout, bool florid)
249 {
250  QString *module = florid ? &m_lastFloridName : &m_lastFlowName;
251  if(*module == name)
252  {
253  state = true;
254  return;
255  }
256 
257  const int index = findSpectrumWidget(*module);
258  if(index != -1)
259  {
260  const MusicSpectrum &type = m_types.takeAt(index);
261  layout->removeWidget(type.m_object);
262  TTK::TTKQmmp::enabledVisualPlugin(*module, false);
263  }
264 
265  if(!state)
266  {
267  module->clear();
268  return;
269  }
270 
271  const int before = Visual::visuals()->count();
273  const QList<Visual*> *vs = Visual::visuals();
274  if(before == vs->count())
275  {
277  state = false;
278  return;
279  }
280 
281  if(!vs->isEmpty())
282  {
283  *module = name;
284  MusicSpectrum type;
285  type.m_module = name;
286  type.m_object = vs->back();
287  type.m_type = spectrum;
288  m_types << type;
289  layout->addWidget(type.m_object);
290  type.m_object->setStyleSheet(TTK::UI::MenuStyle02);
291 
292  if(florid)
293  {
294  TTKObjectCast(Florid*, type.m_object)->setImage(MusicTopAreaWidget::instance()->originImage());
295  connect(MusicTopAreaWidget::instance(), SIGNAL(originImageChanged(QImage)), type.m_object, SLOT(setImage(QImage)));
296  }
297  connect(type.m_object, SIGNAL(fullscreenByUser(QWidget*,bool)), SLOT(fullscreenByUser(QWidget*,bool)));
298  }
299  else
300  {
302  state = false;
303  }
304 }
305 
306 void MusicSpectrumWidget::createLightWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout, const QString &url)
307 {
308  if(state)
309  {
310  if(findSpectrumWidget(name) == -1)
311  {
312  QPluginLoader loader;
313  loader.setFileName(TTK::TTKQmmp::pluginPath("Light", name));
314  const QObject *obj = loader.instance();
315  LightFactory *factory = nullptr;
316  if(obj && (factory = TTKObjectCast(LightFactory*, obj)))
317  {
318  Light *lightWidget = factory->create(this);
319  MusicSpectrum type;
320  type.m_module = name;
321  type.m_object = lightWidget;
322  type.m_type = spectrum;
323  m_types << type;
324  layout->addWidget(lightWidget);
325  }
326  }
327 
328  const int index = findSpectrumWidget(name);
329  if(index == -1)
330  {
331  return;
332  }
333 
334  Light *light = TTKObjectCast(Light*, m_types[index].m_object);
335  if(!light)
336  {
337  return;
338  }
339 
340  const QString &path = url.isEmpty() ? SoundCore::instance()->path() : url;
341  if(LIGHT_WAVEFORM_MODULE == name)
342  {
343  light->open(path);
344  }
345  else if(LIGHT_SPECTROGRAM_MODULE == name)
346  {
347  const QString &suffix = TTK_FILE_SUFFIX(QFileInfo(path));
348  for(QString &filter : MusicFormats::supportSpekInputFilterFormats())
349  {
350  if(filter.remove(0, 2) == suffix) // remove *.
351  {
352  light->open(path);
353  return;
354  }
355  }
356 
357  MusicToastLabel::popup(tr("Unsupported file format"));
358  }
359  }
360  else
361  {
362  const int index = findSpectrumWidget(name);
363  if(index != -1)
364  {
365  const MusicSpectrum &type = m_types.takeAt(index);
366  layout->removeWidget(type.m_object);
367  delete type.m_object;
368  }
369  }
370 }
371 
373 {
374  if(name.isEmpty())
375  {
376  return -1;
377  }
378 
379  for(int i = 0; i < m_types.count(); ++i)
380  {
381  if(m_types[i].m_module.contains(name))
382  {
383  return i;
384  }
385  }
386 
387  return -1;
388 }
389 
391 {
392  MusicToastLabel::popup(tr("Spectrum init error"));
393 }
void spectrumPlusTypeChanged(bool &state, const QString &name)
void setBackgroundLabel(QLabel *label)
MusicSpectrumWidget(QWidget *parent=nullptr)
static const QString ToolButtonStyle05
The class of the moving resize widget with plain.
void spectrumNormalTypeChanged(bool &state, const QString &name)
static SoundCore * instance()
int findSpectrumWidget(const QString &name)
Light plugin interface (Light factory).
Definition: lightfactory.h:76
TTK_MODULE_EXPORT void enabledVisualPlugin(const QString &name, bool enabled)
Helper class to light widget.
Definition: lightfactory.h:28
void setObjectsTracking(const QWidgetList &objects)
void fullscreenByUser(QWidget *widget, bool state)
TTK_MODULE_EXPORT QString getOpenFileName(QWidget *parent, const QString &filter="Image Files (*.png *.bmp *.jpg)")
void createFlowWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
static constexpr const char * LIGHT_SPECTROGRAM_MODULE
virtual void open(const QString &path)=0
virtual Light * create(QWidget *parent)=0
static void popup(const QString &text)
void spectrumWaveTypeChanged(bool &state, const QString &name)
The class of the music spectrum widget all.
#define qAsConst
Definition: ttkqtglobal.h:53
QString path() const
const char * name
Definition: http_parser.c:458
TTK_MODULE_EXPORT QString suffix(const QString &name)
#define TTKRemoveSingleWidget(name)
static const QString PushButtonStyle04
Ui::MusicSpectrumWidget * m_ui
virtual void mouseDoubleClickEvent(QMouseEvent *event) overridefinal
void createModuleWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout, bool florid)
void createFloridWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
void createSpectrumWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
static const QString MenuStyle02
TTK_MODULE_EXPORT QString pluginPath(const QString &module, const QString &format)
void spectrumFloridTypeChanged(bool &state, const QString &name)
static const QString TabWidgetStyle01
TabWidget.
static const QString ToolButtonStyle04
#define TTK_FILE_SUFFIX(fin)
Definition: ttkqtglobal.h:173
static QList< Visual * > * visuals()
MusicSpectrumList m_types
Helper class to florid widget.
Definition: florid.h:77
static QStringList supportSpekInputFilterFormats()
static QString supportSpekInputFormats()
void createLightWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout, const QString &url={})
static MusicTopAreaWidget * instance()
state
Definition: http_parser.c:279
void spectrumFlowTypeChanged(bool &state, const QString &name)
#define TTKObjectCast(x, y)
Definition: ttkqtglobal.h:60
static constexpr const char * LIGHT_WAVEFORM_MODULE