diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 60a21e4..eb10736 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -35,6 +35,7 @@ tde_add_executable( ${PROJECT_NAME} AUTOMOC playDialog.cpp listView.cpp adjustSizeButton.cpp + audioView.cpp fullScreenAction.cpp insertAspectRatioMenuItems.cpp playlistFile.cpp diff --git a/src/app/analyzer.cpp b/src/app/analyzer.cpp index 7a80872..97b9aa3 100644 --- a/src/app/analyzer.cpp +++ b/src/app/analyzer.cpp @@ -585,7 +585,12 @@ void Analyzer::Block::determineStep() // I calculated the value 30 based on some trial and error const double fallTime = 30 * m_rows; - m_step = double(m_rows * 80) / fallTime; // 80 = ~milliseconds between signals with audio data + + // The number of milliseconds between signals with audio data is about 80, + // however, basing the step off of that value causes some undersireable + // effects in the analyzer (high-end blocks constantly appearing/disappearing). + // 44 seems to be a good mid-point. + m_step = double(m_rows * 44) / fallTime; } void Analyzer::Block::drawBackground() diff --git a/src/app/audioView.cpp b/src/app/audioView.cpp new file mode 100644 index 0000000..27a25db --- /dev/null +++ b/src/app/audioView.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2025 mio +// +// SPDX-License-Identifier: GPL-2.0-or-later. + +#include "audioView.h" + +#include + +#include "analyzer.h" + +namespace Codeine +{ + +AudioView::AudioView(TQWidget *parent, const char *name) + : TQFrame(parent, name) +{ + auto *layout = new TQHBoxLayout(this); + m_analyzer = new Analyzer::Block(this); + + // We subtract one from the below to remove excess padding. + // 36 blocks for the max/min height is arbitrary, but looks okay. + m_analyzer->setMaximumSize((Analyzer::Block::MAX_COLUMNS / 2) * (Analyzer::Block::WIDTH + 1) - 1, + 36 * (Analyzer::Block::HEIGHT + 1) - 1); + + m_analyzer->setMinimumSize(Analyzer::Block::WIDTH * Analyzer::Block::MIN_COLUMNS, + 36 * (Analyzer::Block::HEIGHT + 1) - 1); + + layout->addWidget(m_analyzer); +} + +} diff --git a/src/app/audioView.h b/src/app/audioView.h new file mode 100644 index 0000000..592e38f --- /dev/null +++ b/src/app/audioView.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2025 mio +// +// SPDX-License-Identifier: GPL-2.0-or-later. + +#ifndef CODEINE_AUDIOVIEW_H +#define CODEINE_AUDIOVIEW_H + +#include + +namespace Codeine +{ + +class AudioView : public TQFrame +{ + public: + AudioView(TQWidget *parent, const char *name = nullptr); + + private: + TQWidget *m_analyzer; +}; + +} + +#endif /* CODEINE_AUDIOVIEW_H */ diff --git a/src/app/mainWindow.cpp b/src/app/mainWindow.cpp index 9409d85..5861427 100644 --- a/src/app/mainWindow.cpp +++ b/src/app/mainWindow.cpp @@ -22,11 +22,13 @@ #include //ctor #include //because XMLGUI is poorly designed #include +#include #include "../debug.h" #include "../mxcl.library.h" #include "actions.h" #include "analyzer.h" +#include "audioView.h" #include "codeineConfig.h" #include "extern.h" //dialog creation function definitions #include "fullScreenAction.h" @@ -70,8 +72,19 @@ MainWindow::MainWindow() kapp->setMainWidget( this ); + m_widgetStack = new TQWidgetStack(this, "m_widgetStack"); + new VideoWindow( this ); - setCentralWidget( videoWindow() ); + + m_audioView = new AudioView(this, "m_audioView"); + + // videoWindow() will be the initial widget. + // m_audioView is raised when no video track is present. + m_widgetStack->addWidget(videoWindow()); + m_widgetStack->addWidget(m_audioView); + + setCentralWidget(m_widgetStack); + setFocusProxy( videoWindow() ); // essential! See VideoWindow::event(), TQEvent::FocusOut // these have no affect beccause "KDE Knows Best" FFS @@ -523,7 +536,6 @@ show_toolbar: //we aren't managed by mainWindow when at FullScreen videoWindow()->move( 0, 0 ); videoWindow()->resize( ((TQWidget*)o)->size() ); - videoWindow()->lower(); } if (o == m_toolbar) @@ -580,14 +592,12 @@ MainWindow::fullScreenToggled( bool isFullScreen ) statusBar()->setHidden( isFullScreen ); setMouseTracking( isFullScreen ); /// @see mouseMoveEvent() + m_widgetStack->setMouseTracking(isFullScreen); if (isFullScreen) s_handler = new FullScreenToolBarHandler( this ); else delete s_handler; - - // prevent videoWindow() moving around when mouse moves - setCentralWidget( isFullScreen ? nullptr : videoWindow() ); } void diff --git a/src/app/mainWindow.h b/src/app/mainWindow.h index 634d444..3dae1e8 100644 --- a/src/app/mainWindow.h +++ b/src/app/mainWindow.h @@ -11,11 +11,14 @@ class KURL; class TQLabel; class TQPopupMenu; class TQSlider; +class TQWidgetStack; class VolumeAction; namespace Codeine { + class AudioView; + class MainWindow : public TDEMainWindow { TQ_OBJECT @@ -66,6 +69,8 @@ namespace Codeine TQLabel *m_timeLabel; TQLabel *m_titleLabel; TQWidget *m_analyzer; + AudioView *m_audioView; + TQWidgetStack *m_widgetStack; VolumeAction *m_volumeAction; //undefined diff --git a/src/app/stateChange.cpp b/src/app/stateChange.cpp index 49adc55..73f77d0 100644 --- a/src/app/stateChange.cpp +++ b/src/app/stateChange.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include "audioView.h" #include "theStream.h" #include "videoSettings.h" //FIXME unfortunate #include "xineEngine.h" @@ -104,8 +106,18 @@ MainWindow::engineStateChanged( Engine::State state ) /// update statusBar { using namespace Engine; - m_analyzer->setShown( state & (Playing | Paused) && TheStream::hasAudio() ); - m_timeLabel->setShown( state & (Playing | Paused) ); + m_analyzer->setShown(state & (Playing | Paused) && (TheStream::hasVideo() && TheStream::hasAudio())); + m_timeLabel->setShown(state & (Playing | Paused)); + } + + // Update the current widget shown. + if (TheStream::hasVideo() || (state & (Engine::Empty))) + { + m_widgetStack->raiseWidget(videoWindow()); + } + else if (TheStream::hasAudio()) + { + m_widgetStack->raiseWidget(m_audioView); }