1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 #ifndef RG_TRANSPORTDIALOG_H
19 #define RG_TRANSPORTDIALOG_H
20 
21 #include <QHash>
22 #include <QColor>
23 #include <QPixmap>
24 #include <QtCore>
25 #include <QDialog>
26 #include <QSharedPointer>
27 
28 #include "base/Composition.h" // for tempoT
29 
30 #include "ui_RosegardenTransportUi.h"
31 
32 /* NOTE: In a stylesheet world, we can no longer flash the LCD background through
33  * the palette, so we have to use spot stylesheets instead.  I've changed this
34  * from passing around QColor to a QString, and use named colors.  This is
35  * simplistic, but this part of the transport has always been hard coded black
36  * since time immemorial, and it's quicker to pass around "black," "red," and
37  * "cyan" than to convert a QColor into a a string.
38  *
39  * dmm
40  */
41 
42 class QWidget;
43 class QTimer;
44 class QPushButton;
45 class QCloseEvent;
46 class QShortcut;
47 class QDialog;
48 
49 namespace Rosegarden
50 {
51 
52 class TimeSignature;
53 class RealTime;
54 class MappedEvent;
55 
56 
57 class TransportDialog : public QDialog
58 {
59     Q_OBJECT
60 public:
61     TransportDialog(QWidget *parent = nullptr);
62     ~TransportDialog() override;
63 
64     enum TimeDisplayMode { RealMode, SMPTEMode, BarMode, BarMetronomeMode, FrameMode };
65 
66     std::string getCurrentModeAsString();
getCurrentMode()67     TimeDisplayMode getCurrentMode() { return m_currentMode; }
68     void setNewMode(const std::string& newModeAsString);
69     void setNewMode(const TimeDisplayMode& newMode);
70     bool isShowingTimeToEnd();
71     bool isExpanded();
72 
73     void displayRealTime(const RealTime &rt);
74     void displaySMPTETime(const RealTime &rt);
75     void displayFrameTime(const RealTime &rt);
76     void displayBarTime(int bar, int beat, int unit);
77 
78     void setTimeSignature(const TimeSignature &timeSig);
79 
80     void setSMPTEResolution(int framesPerSecond, int bitsPerFrame);
81     void getSMPTEResolution(int &framesPerSecond, int &bitsPerFrame);
82 
83     // Return the shortcut object
84     //
getShortcuts()85     QShortcut* getShortcuts() { return m_shortcuts; }
86 
87     // RosegardenTransport member accessors
MetronomeButton()88     QPushButton* MetronomeButton()   { return ui->MetronomeButton; }
SoloButton()89     QPushButton* SoloButton()        { return ui->SoloButton; }
LoopButton()90     QPushButton* LoopButton()        { return ui->LoopButton; }
PlayButton()91     QPushButton* PlayButton()        { return ui->PlayButton; }
StopButton()92     QPushButton* StopButton()        { return ui->StopButton; }
FfwdButton()93     QPushButton* FfwdButton()        { return ui->FfwdButton; }
RewindButton()94     QPushButton* RewindButton()      { return ui->RewindButton; }
RecordButton()95     QPushButton* RecordButton()      { return ui->RecordButton; }
RewindEndButton()96     QPushButton* RewindEndButton()   { return ui->RewindEndButton; }
FfwdEndButton()97     QPushButton* FfwdEndButton()     { return ui->FfwdEndButton; }
TimeDisplayButton()98     QPushButton* TimeDisplayButton() { return ui->TimeDisplayButton; }
ToEndButton()99     QPushButton* ToEndButton()       { return ui->ToEndButton; }
100 
101     /// Save geometry to .conf.
102     /**
103      * Making these public in an attempt to fix a bug where the window will
104      * crawl upward each time it is hidden and re-shown.  It's moving up by
105      * exactly the height of the titlebar.  It's as if the child window
106      * position is being used for the parent window.  Or perhaps an assumption
107      * is being made that the geometry stored by hide() needs to be adjusted
108      * by the titlebar height.
109      *
110      * At any rate, using these when hiding and showing almost fixes the
111      * problem.  The last failing test case is when you hide the transport,
112      * close rg, launch rg, and show the transport.  It will move up.
113      * Examining the geometry at each point might provide a clue.
114      */
115     void saveGeo();
116     /// Load geometry from .conf.
117     void loadGeo();
118 
119 protected:
120     // QDialog override.
121     void closeEvent(QCloseEvent * e) override;
122 
123     void computeSampleRate();
124     void cycleThroughModes();
125     void displayTime();
126 
127 public slots:
128 
129     // These two slots are activated by QTimers
130     //
131     void slotClearMidiInLabel();
132     void slotClearMidiOutLabel();
133 
134     // These just change the little labels that say what
135     // mode we're in, nothing else
136     //
137     void slotChangeTimeDisplay();
138     void slotChangeToEnd();
139 
140     void slotLoopButtonClicked();
141 
142     void slotPanelOpenButtonClicked();
143     void slotPanelCloseButtonClicked();
144 
145     void slotEditTempo();
146     void slotEditTimeSignature();
147     void slotEditTime();
148 
149     void setBackgroundColor(QColor color);
150     void slotResetBackground();
151 
152     void slotSetStartLoopingPointAtMarkerPos();
153     void slotSetStopLoopingPointAtMarkerPos();
154 
155     // Connected to SequenceManager
156     void slotTempoChanged(tempoT);
157     void slotMidiInLabel(const MappedEvent *event); // show incoming MIDI events on the Transport
158     void slotMidiOutLabel(const MappedEvent *event); // show outgoing  MIDI events on the Transport
159     void slotPlaying(bool checked);
160     void slotRecording(bool checked);
161     void slotMetronomeActivated(bool checked);
162 
163 signals:
164     void closed();
165 
166     // Set and unset the loop at the RosegardenMainWindow
167     //
168     void setLoop();
169     void unsetLoop();
170     void setLoopStartTime();
171     void setLoopStopTime();
172 
173     void editTempo(QWidget *);
174     void editTimeSignature(QWidget *);
175     void editTransportTime(QWidget *);
176     //void scrollTempo(int);
177     void panic();
178 
179 private:
180     void loadPixmaps();
181     void resetFonts();
182     void resetFont(QWidget *);
183     void initModeMap();
184 
185     //--------------- Data members ---------------------------------
186 
187     QSharedPointer<Ui_RosegardenTransport> ui;
188 
189     QHash<int, QPixmap> m_lcdList;
190     QHash<int, QPixmap> m_lcdListDefault;
191     QPixmap m_lcdNegative;
192 
193     int m_lastTenHours;
194     int m_lastUnitHours;
195     int m_lastTenMinutes;
196     int m_lastUnitMinutes;
197     int m_lastTenSeconds;
198     int m_lastUnitSeconds;
199     int m_lastTenths;
200     int m_lastHundreths;
201     int m_lastThousandths;
202     int m_lastTenThousandths;
203 
204     bool m_lastNegative;
205     TimeDisplayMode m_lastMode;
206     TimeDisplayMode m_currentMode;
207 
208     int m_tenHours;
209     int m_unitHours;
210     int m_tenMinutes;
211     int m_unitMinutes;
212     int m_tenSeconds;
213     int m_unitSeconds;
214     int m_tenths;
215     int m_hundreths;
216     int m_thousandths;
217     int m_tenThousandths;
218 
219     int m_numerator;
220     int m_denominator;
221 
222     int m_framesPerSecond;
223     int m_bitsPerFrame;
224 
225     QTimer *m_midiInTimer;
226     QTimer *m_midiOutTimer;
227     QTimer *m_clearMetronomeTimer;
228 
229     bool m_enableMIDILabels;
230 
231     QPixmap m_panelOpen;
232     QPixmap m_panelClosed;
233 
234     void updateTimeDisplay();
235 
236     QShortcut *m_shortcuts;
237     bool    m_isExpanded;
238 
239     bool m_isBackgroundSet;
240 
241     int m_sampleRate;
242 
243     std::map<std::string, TimeDisplayMode> m_modeMap;
244 };
245 
246 
247 
248 
249 
250 }
251 
252 #endif
253