TTKMusicPlayer  4.1.3.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  // Objects Mouse tracking
61  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  {
173  {
175  break;
176  }
178  {
180  break;
181  }
183  {
185  break;
186  }
188  {
189  m_lastFlowName.clear();
191  break;
192  }
194  {
195  m_lastFloridName.clear();
197  break;
198  }
200  {
202  break;
203  }
204  default: break;
205  }
206 #endif
207  }
208  }
209 }
210 
212 {
213  MusicAbstractMoveResizePlainWidget::mouseDoubleClickEvent(event);
214  if(event->buttons() == Qt::LeftButton)
215  {
216  isMaximized() ? showNormal() : showMaximized();
217  }
218 }
219 
220 void MusicSpectrumWidget::createSpectrumWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
221 {
222  if(state)
223  {
224  const int before = Visual::visuals()->count();
226  const QList<Visual*> *vs = Visual::visuals();
227  if(before == vs->count())
228  {
230  state = false;
231  return;
232  }
233 
234  if(!vs->isEmpty())
235  {
236  MusicSpectrum type;
237  type.m_module = name;
238  type.m_object = vs->back();
239  type.m_type = spectrum;
240  m_types << type;
241  layout->addWidget(type.m_object);
242  type.m_object->setStyleSheet(TTK::UI::MenuStyle02);
243 
244  connect(type.m_object, SIGNAL(fullscreenByUser(QWidget*,bool)), SLOT(fullscreenByUser(QWidget*,bool)));
245  }
246  else
247  {
249  state = false;
250  }
251  }
252  else
253  {
254  const int index = findSpectrumWidget(name);
255  if(index != -1)
256  {
257  const MusicSpectrum &type = m_types.takeAt(index);
258  layout->removeWidget(type.m_object);
260  }
261  }
262 }
263 
264 void MusicSpectrumWidget::createFlowWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
265 {
266  createModuleWidget(spectrum, state, name, layout, false);
267 }
268 
269 void MusicSpectrumWidget::createFloridWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout)
270 {
271  createModuleWidget(spectrum, state, name, layout, true);
272 }
273 
274 void MusicSpectrumWidget::createModuleWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout, bool florid)
275 {
276  QString *module = florid ? &m_lastFloridName : &m_lastFlowName;
277  if(*module == name)
278  {
279  state = true;
280  return;
281  }
282 
283  const int index = findSpectrumWidget(*module);
284  if(index != -1)
285  {
286  const MusicSpectrum &type = m_types.takeAt(index);
287  layout->removeWidget(type.m_object);
288  TTK::TTKQmmp::enabledVisualPlugin(*module, false);
289  }
290 
291  if(!state)
292  {
293  module->clear();
294  return;
295  }
296 
297  const int before = Visual::visuals()->count();
299  const QList<Visual*> *vs = Visual::visuals();
300  if(before == vs->count())
301  {
303  state = false;
304  return;
305  }
306 
307  if(!vs->isEmpty())
308  {
309  *module = name;
310  MusicSpectrum type;
311  type.m_module = name;
312  type.m_object = vs->back();
313  type.m_type = spectrum;
314  m_types << type;
315  layout->addWidget(type.m_object);
316  type.m_object->setStyleSheet(TTK::UI::MenuStyle02);
317 
318  if(florid)
319  {
320  TTKObjectCast(Florid*, type.m_object)->setImage(MusicTopAreaWidget::instance()->originImage());
321  connect(MusicTopAreaWidget::instance(), SIGNAL(originImageChanged(QImage)), type.m_object, SLOT(setImage(QImage)));
322  }
323  connect(type.m_object, SIGNAL(fullscreenByUser(QWidget*,bool)), SLOT(fullscreenByUser(QWidget*,bool)));
324  }
325  else
326  {
328  state = false;
329  }
330 }
331 
332 void MusicSpectrumWidget::createLightWidget(MusicSpectrum::Module spectrum, bool &state, const QString &name, QLayout *layout, const QString &url)
333 {
334  if(state)
335  {
336  if(findSpectrumWidget(name) == -1)
337  {
338  QPluginLoader loader;
339  loader.setFileName(TTK::TTKQmmp::pluginPath("Light", name));
340  const QObject *obj = loader.instance();
341  LightFactory *factory = nullptr;
342  if(obj && (factory = TTKObjectCast(LightFactory*, obj)))
343  {
344  Light *lightWidget = factory->create(this);
345  MusicSpectrum type;
346  type.m_module = name;
347  type.m_object = lightWidget;
348  type.m_type = spectrum;
349  m_types << type;
350  layout->addWidget(lightWidget);
351  }
352  }
353 
354  const int index = findSpectrumWidget(name);
355  if(index == -1)
356  {
357  return;
358  }
359 
360  Light *light = TTKObjectCast(Light*, m_types[index].m_object);
361  if(!light)
362  {
363  return;
364  }
365 
366  const QString &path = url.isEmpty() ? SoundCore::instance()->path() : url;
367  if(LIGHT_WAVEFORM_MODULE == name)
368  {
369  light->open(path);
370  }
371  else if(LIGHT_SPECTROGRAM_MODULE == name)
372  {
373  const QString &suffix = TTK_FILE_SUFFIX(QFileInfo(path));
374  for(QString &filter : MusicFormats::supportSpekInputFilterFormats())
375  {
376  if(filter.remove(0, 2) == suffix) // remove *.
377  {
378  light->open(path);
379  return;
380  }
381  }
382 
383  MusicToastLabel::popup(tr("Unsupported file format"));
384  }
385  }
386  else
387  {
388  const int index = findSpectrumWidget(name);
389  if(index != -1)
390  {
391  const MusicSpectrum &type = m_types.takeAt(index);
392  layout->removeWidget(type.m_object);
393  delete type.m_object;
394  }
395  }
396 }
397 
399 {
400  if(name.isEmpty())
401  {
402  return -1;
403  }
404 
405  for(int i = 0; i < m_types.count(); ++i)
406  {
407  if(m_types[i].m_module.contains(name))
408  {
409  return i;
410  }
411  }
412 
413  return -1;
414 }
415 
417 {
418  MusicToastLabel::popup(tr("Spectrum init error"));
419 }
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:51
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:189
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:76
static constexpr const char * LIGHT_WAVEFORM_MODULE