fix mistaken "do not roll" conclusion in TransportFSM::compute_should_roll()
[ardour.git] / gtk2_ardour / export_report.h
1 /*
2  * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <cairo/cairo.h>
20 #include <gtkmm/notebook.h>
21 #include <gtkmm/togglebutton.h>
22
23 #include "gtkmm2ext/cairo_widget.h"
24 #include "gtkmm2ext/gui_thread.h"
25
26 #include "ardour/export_status.h"
27
28 #include "ardour_dialog.h"
29
30 class CimgArea : public CairoWidget
31 {
32 public:
33         CimgArea (Cairo::RefPtr<Cairo::ImageSurface> sf)
34                 : CairoWidget()
35                 , _surface(sf)
36         {
37                 set_size_request (sf->get_width (), sf->get_height ());
38         }
39
40 protected:
41         virtual void background (cairo_t* cr, cairo_rectangle_t* r) {
42                 cairo_set_source_surface (cr, _surface->cobj(), 0, 0);
43                 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
44                 cairo_paint (cr);
45         }
46
47         virtual void overlay (cairo_t* cr, cairo_rectangle_t* r) {}
48
49         virtual void render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_t* r)
50         {
51                 ctx->rectangle (r->x, r->y, r->width, r->height);
52                 ctx->clip ();
53                 background (ctx->cobj(), r);
54                 overlay (ctx->cobj(), r);
55         }
56
57         Cairo::RefPtr<Cairo::ImageSurface> _surface;
58 };
59
60 class CimgPlayheadArea : public CimgArea
61 {
62 public:
63         CimgPlayheadArea (Cairo::RefPtr<Cairo::ImageSurface> sf, float x0, float w, bool h = false)
64         : CimgArea (sf)
65         , _playhead(-1)
66         , _x0 (x0)
67         , _aw (w)
68         , _highlight (h)
69         {
70         }
71
72         void set_playhead (float pos) {
73                 if (rint (_playhead * _aw) == rint (pos * _aw)) {
74                         return;
75                 }
76                 if (_playhead == -1 || pos == -1) {
77                         set_dirty ();
78                 } else {
79                         invalidate (_playhead);
80                         invalidate (pos);
81                 }
82                 _playhead = pos;
83         }
84
85         sigc::signal<void, float> seek_playhead;
86
87 protected:
88
89         virtual void overlay (cairo_t* cr, cairo_rectangle_t* r) {
90                 if (_playhead > 0 && _playhead < 1.0 && _aw > 0) {
91                         if (_highlight) {
92                                 cairo_rectangle (cr, _x0, 0, _aw, _surface->get_height());
93                                 cairo_set_source_rgba (cr, .4, .4, .6, .4);
94                                 cairo_fill (cr);
95                         }
96
97                         const float x = _playhead * _aw;
98                         const float h = _surface->get_height();
99                         cairo_set_source_rgba (cr, 1, 0, 0, 1);
100                         cairo_set_line_width (cr, 1.5);
101                         cairo_move_to (cr, _x0 + x, 0);
102                         cairo_line_to (cr, _x0 + x, h);
103                         cairo_stroke (cr);
104                 }
105         }
106
107         bool on_button_press_event (GdkEventButton *ev) {
108                 CairoWidget::on_button_press_event (ev);
109                 if (ev->button == 1 && _aw > 0 && ev->x >= _x0 && ev->x <= _x0 + _aw) {
110                         seek_playhead (((float) ev->x - _x0) / (float)_aw);
111                 }
112                 return true;
113         }
114
115 private:
116         float _playhead;
117         float _x0, _aw;
118         bool _highlight;
119
120         void invalidate (float pos) {
121                 if (pos < 0 || pos > 1) { return; }
122                 const float x = pos * _aw;
123                 cairo_rectangle_t r;
124                 r.y = 0;
125                 r.x = _x0 + x - 1;
126                 r.width = 3;
127                 r.height = _surface->get_height();
128                 set_dirty (&r);
129         }
130 };
131
132 class CimgWaveArea : public CimgPlayheadArea
133 {
134 public:
135         CimgWaveArea (
136                         Cairo::RefPtr<Cairo::ImageSurface> sf,
137                         Cairo::RefPtr<Cairo::ImageSurface> sf_log,
138                         Cairo::RefPtr<Cairo::ImageSurface> sf_rect,
139                         Cairo::RefPtr<Cairo::ImageSurface> sf_logrec,
140                         float x0, float w)
141         : CimgPlayheadArea (sf, x0, w)
142         , _sf_log (sf_log)
143         , _sf_rect (sf_rect)
144         , _sf_logrec (sf_logrec)
145         , _logscale (false)
146         , _rectified (false)
147         {
148         }
149
150         void set_logscale (bool en) {
151                 _logscale = en;
152                 set_dirty ();
153         }
154
155         void set_rectified (bool en) {
156                 _rectified = en;
157                 set_dirty ();
158         }
159
160 protected:
161
162         virtual void background (cairo_t* cr, cairo_rectangle_t* r) {
163                 if (_logscale && _rectified) {
164                         cairo_set_source_surface (cr, _sf_logrec->cobj(), 0, 0);
165                 } else if (_logscale) {
166                         cairo_set_source_surface (cr, _sf_log->cobj(), 0, 0);
167                 } else if (_rectified) {
168                         cairo_set_source_surface (cr, _sf_rect->cobj(), 0, 0);
169                 } else {
170                         cairo_set_source_surface (cr, _surface->cobj(), 0, 0);
171                 }
172                 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
173                 cairo_paint (cr);
174         }
175
176 private:
177         Cairo::RefPtr<Cairo::ImageSurface> _sf_log;
178         Cairo::RefPtr<Cairo::ImageSurface> _sf_rect;
179         Cairo::RefPtr<Cairo::ImageSurface> _sf_logrec;
180         bool _logscale;
181         bool _rectified;
182 };
183
184 class ExportReport : public ArdourDialog
185 {
186 public:
187         typedef boost::shared_ptr<ARDOUR::ExportStatus> StatusPtr;
188         ExportReport (ARDOUR::Session*, StatusPtr);
189         ExportReport (const std::string & title, const ARDOUR::AnalysisResults & ar);
190         int run ();
191
192         void on_response (int response_id) {
193                 Gtk::Dialog::on_response (response_id);
194         }
195
196 private:
197         void init (const ARDOUR::AnalysisResults &, bool);
198         void draw_waveform (Cairo::RefPtr<Cairo::ImageSurface>& wave,
199                         ARDOUR::ExportAnalysisPtr, uint32_t, int, size_t, int, int, bool, bool);
200
201         void open_folder (std::string);
202         void audition (std::string, unsigned int, int);
203         void stop_audition ();
204         void play_audition ();
205         void audition_active (bool);
206         void audition_seek (int, float);
207         void audition_progress (ARDOUR::samplecnt_t, ARDOUR::samplecnt_t);
208         void on_switch_page (GtkNotebookPage*, guint page_num);
209         void on_logscale_toggled (Gtk::ToggleButton*);
210         void on_rectivied_toggled (Gtk::ToggleButton*);
211
212         Gtk::Notebook    pages;
213         ARDOUR::Session* _session;
214         Gtk::Button*     stop_btn;
215         Gtk::Button*     play_btn;
216         PBD::ScopedConnectionList auditioner_connections;
217
218         struct AuditionInfo {
219                 AuditionInfo (std::string p, unsigned int c) : path (p), channels (c) {}
220                 AuditionInfo () : channels (0) {}
221                 std::string  path;
222                 unsigned int channels;
223         };
224
225         std::map<int, std::list<CimgPlayheadArea*> > timeline;
226         std::map<int, AuditionInfo> files;
227         std::list<CimgWaveArea*> waves;
228
229         int _audition_num;
230         int _page_num;
231 };