hydrogen 1.2.6
Director.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2025 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY, without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
23
53
54
55#include "Director.h"
56#include "HydrogenApp.h"
57#include "Skin.h"
59
61#include <core/Hydrogen.h>
64#include <core/Timeline.h>
66
67using namespace H2Core;
68
69Director::Director ( QWidget* pParent )
70 : QDialog ( pParent )
71 , Object ()
72{
73
75 setupUi ( this );
76
77 setWindowTitle ( tr ( "Director" ) );
78
82
83 m_nBar = pPos->getBar();
84 m_nBeat = pPos->getBeat();
85 m_Color = pPref->getColorTheme()->m_accentColor;
86 m_Color.setAlpha( 0 );
87 m_nFlashingArea = width() * 5/100;
88
89 m_pTimer = new QTimer( this );
90 connect( m_pTimer, SIGNAL( timeout() ), this, SLOT( updateMetronomBackground() ) );
91
93}
94
95
99
100void Director::keyPressEvent( QKeyEvent* ev )
101{
102 if(ev->key() == Qt::Key_Escape) {
104 }
105}
106
107void Director::closeEvent( QCloseEvent* ev )
108{
110}
111
115
116void Director::updateSongEvent( int nValue ) {
117
118 auto pHydrogen = Hydrogen::get_instance();
119 auto pSong = pHydrogen->getSong();
120 if ( pSong == nullptr ) {
121 return;
122 }
123
124 if ( nValue == 0 || // new song loaded
125 nValue == 1 ) { // current one saved
126
127 // Update song name
128 QStringList list = pSong->getFilename().split("/");
129
130 if ( !list.isEmpty() ){
131 m_sSongName = list.last().replace( Filesystem::songs_ext, "" );
132
133 // if songname is not set, default on an empty song, we call them "Untitled Song".
134 if( m_sSongName.isEmpty() ){
135 m_sSongName = QString("Untitled Song");
136 }
137 }
138
139 updateTags();
141 update();
142 }
143}
144
146 if ( updateTags() ) {
147 update();
148 }
149}
150
152 auto pHydrogen = Hydrogen::get_instance();
153 auto pTimeline = pHydrogen->getTimeline();
154 auto pSong = pHydrogen->getSong();
155
156 if ( pSong == nullptr ) {
157 return false;
158 }
159
160 const int nColumns = pSong->getPatternGroupVector()->size();
161
162 bool bRequiresUpdate = false;
163 // Note that bar = column + 1
164 if ( m_nBar == nColumns ) {
165 if ( pSong->getLoopMode() == Song::LoopMode::Enabled &&
166 m_sTagNext != pTimeline->getTagAtColumn( 0 ) ) {
167 // We are in the last column and transport will be looped back
168 // to the beginning. Show the tag in the first column as the
169 // next one.
170 m_sTagNext = pTimeline->getTagAtColumn( 0 );
172 bRequiresUpdate = true;
173 }
174 }
175 else if ( m_sTagNext != pTimeline->getTagAtColumn( m_nBar ) ) {
176 m_sTagNext = pTimeline->getTagAtColumn( m_nBar );
178 bRequiresUpdate = true;
179 }
180 if ( m_sTagCurrent != pTimeline->getTagAtColumn( m_nBar - 1 ) ) {
181 m_sTagCurrent = pTimeline->getTagAtColumn( m_nBar - 1 );
183 bRequiresUpdate = true;
184 }
185
186 return bRequiresUpdate;
187}
188
190{
193
194 // 1000 ms / bpm / 60s
195 m_pTimer->start( static_cast<int>( 1000 / ( pPos->getBpm() / 60 )) / 2 );
196 m_nFlashingArea = width() * 5/100;
197
198 m_nBar = pPos->getBar();
199 m_nBeat = pPos->getBeat();
200
201 if ( m_nBeat == 1 ) { //foregroundcolor "rect" for first blink
202 m_Color = pPref->getColorTheme()->m_buttonRedColor;
203 }
204 else { //foregroundcolor "rect" for all other blinks
205 if ( m_nBeat %2 == 0 ) {
206 m_nFlashingArea = width() * 52.5/100;
207 }
208 m_Color = pPref->getColorTheme()->m_accentColor;
209 }
210
211 updateTags();
212 update();
213}
214
215
217{
218 m_Color.setAlpha( 0 );
219 m_pTimer->stop();
220 update();
221}
222
225 const QString sFontFamily = pPref->getApplicationFontFamily();
226
227 // Reduce the pixelsize of the font till it fits the width of its
228 // enclosing rectangle.
229 auto shrinkTillItFits = [&]( QFont* pFont, const QRect& rect, const QString& sLabel ) {
230 if ( sLabel.isEmpty() ) {
231 return;
232 }
233
234 while ( ( QFontMetrics( *pFont ).size( Qt::TextSingleLine, sLabel ).width() >
235 rect.width() ) &&
236 pFont->pointSize() > 1 ) {
237 pFont->setPointSize( pFont->pointSize() - 1 );
238 }
239 };
240
241 if ( update & FontUpdate::SongName ) {
242 // Reset to default value
243 m_fontSongName = QFont( sFontFamily, height() * 14/100 );
244 shrinkTillItFits( &m_fontSongName, m_rectSongName, m_sSongName );
245 }
246
247 if ( update & FontUpdate::TagCurrent ) {
248 m_fontTagCurrent = QFont( sFontFamily, height() * 8/100 );
249 shrinkTillItFits( &m_fontTagCurrent, m_rectTagCurrent, m_sTagCurrent );
250 }
251
252 if ( update & FontUpdate::TagNext ) {
253 m_fontTagNext = QFont( sFontFamily, height() * 6/100 );
254 shrinkTillItFits( &m_fontTagNext, m_rectTagNext, m_sTagNext );
255 }
256}
257
259 m_rectSongName = QRect( QPoint( width() * 5/100 , height () * 2/100 ),
260 QSize( width() * 90/100, height() * 21/100) );
261 m_rectTagCurrent = QRect( QPoint( width() * 5/100 , height() * 65/100 ),
262 QSize( width() * 90/100, height() * 14/100) );
263 m_rectTagNext = QRect( QPoint( width() * 5/100 , height() * 83/100 ),
264 QSize( width() * 90/100, height() * 11/100) );
265
269}
270
271void Director::resizeEvent( QResizeEvent* ev ) {
273
274 QDialog::resizeEvent( ev );
275 update();
276}
277
278void Director::paintEvent( QPaintEvent* ev )
279{
280 QPainter painter(this);
281
283 const QString sFontFamily = pPref->getApplicationFontFamily();
284
285 //draw the songname
286 painter.setFont( m_fontSongName );
287 painter.drawText( m_rectSongName, Qt::AlignCenter, m_sSongName );
288
289
290 //draw the metronome
291 painter.setPen( QPen( pPref->getColorTheme()->m_highlightColor, 1 , Qt::SolidLine ) );
292 painter.setBrush( m_Color );
293 painter.drawRect( m_nFlashingArea, height() * 25/100, width() * 42.5/100,
294 height() * 35/100);
295
296
297 //draw bars
298 QColor textColor = pPref->getColorTheme()->m_windowTextColor;
299 painter.setPen( textColor );
300 painter.setFont(QFont( sFontFamily, height() * 25/100 ));
301 QRect r1(QPoint( width() * 5/100 , height() * 25/100 ), QSize( width() * 42.5/100, height() * 35/100));
302 painter.drawText( r1, Qt::AlignCenter, QString("%1").arg( m_nBar) );
303
304 //draw beats
305 QRect r2(QPoint( width() * 52.5/100 , height() * 25/100 ), QSize( width() * 42.5/100, height() * 35/100));
306 painter.drawText( r2, Qt::AlignCenter, QString("%1").arg( m_nBeat) );
307
308 if( m_sTagNext == m_sTagCurrent ){
309 m_sTagNext = "";
310 }
311
312 //draw current bar tag
313 painter.setFont( m_fontTagCurrent );
314 painter.drawText( m_rectTagCurrent, Qt::AlignCenter, m_sTagCurrent );
315
316 //draw next bar tag
317 painter.setPen( Skin::makeTextColorInactive( textColor ) );
318 painter.setFont( m_fontTagNext );
319 painter.drawText( m_rectTagNext, Qt::AlignCenter, QString( m_sTagNext ) );
320}
321
virtual void timelineUpdateEvent(int nValue) override
Definition Director.cpp:145
QRect m_rectSongName
Definition Director.h:87
QFont m_fontTagNext
Definition Director.h:92
virtual void paintEvent(QPaintEvent *) override
Definition Director.cpp:278
QString m_sTagCurrent
Definition Director.h:84
QRect m_rectTagCurrent
Definition Director.h:88
QFont m_fontSongName
Definition Director.h:90
QTimer * m_pTimer
Definition Director.h:78
void updateMetronomBackground()
Definition Director.cpp:216
@ TagNext
Definition Director.h:70
@ SongName
Definition Director.h:68
@ TagCurrent
Definition Director.h:69
Director(QWidget *pParent)
Definition Director.cpp:69
void onPreferencesChanged(H2Core::Preferences::Changes changes)
Definition Director.cpp:322
virtual void closeEvent(QCloseEvent *ev) override
Definition Director.cpp:107
virtual void updateSongEvent(int nValue) override
Definition Director.cpp:116
int m_nBeat
Definition Director.h:81
QString m_sTagNext
Definition Director.h:85
virtual void keyPressEvent(QKeyEvent *ev) override
Definition Director.cpp:100
QFont m_fontTagCurrent
Definition Director.h:91
int m_nFlashingArea
Definition Director.h:83
QRect m_rectTagNext
Definition Director.h:89
virtual void tempoChangedEvent(int nValue) override
Definition Director.cpp:112
void resizeEvent(QResizeEvent *event) override
Definition Director.cpp:271
int m_nBar
Definition Director.h:82
void updateLabelContainers()
Definition Director.cpp:258
void updateFontSize(FontUpdate update)
Definition Director.cpp:223
QColor m_Color
Definition Director.h:79
QString m_sSongName
Definition Director.h:86
bool updateTags()
Definition Director.cpp:151
virtual void bbtChangedEvent() override
Definition Director.cpp:189
const std::shared_ptr< TransportPosition > getTransportPosition() const
static const QString songs_ext
Definition Filesystem.h:117
static Hydrogen * get_instance()
Returns the current Hydrogen instance __instance.
Definition Hydrogen.h:84
AudioEngine * getAudioEngine() const
Definition Hydrogen.h:663
static Preferences * get_instance()
Returns a pointer to the current Preferences singleton stored in __instance.
Changes
Bitwise or-able options showing which part of the Preferences were altered using the PreferencesDialo...
@ Font
Either the font size or font family have changed.
@ Colors
At least one of the colors has changed.
void addEventListener(EventListener *pListener)
static HydrogenApp * get_instance()
Returns the instance of HydrogenApp class.
void showDirector()
static QColor makeTextColorInactive(QColor color)
If a widget is marked inactive the value of its text color are reduced by this factor.
Definition Skin.cpp:176