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 #ifndef _gtkardour_export_report_h_ 20 #define _gtkardour_export_report_h_ 21 22 #include <cairo/cairo.h> 23 #include <gtkmm/notebook.h> 24 #include <gtkmm/togglebutton.h> 25 26 #include "gtkmm2ext/cairo_widget.h" 27 #include "gtkmm2ext/gui_thread.h" 28 29 #include "ardour/export_status.h" 30 31 #include "ardour_dialog.h" 32 33 class CimgArea : public CairoWidget 34 { 35 public: CimgArea(Cairo::RefPtr<Cairo::ImageSurface> sf)36 CimgArea (Cairo::RefPtr<Cairo::ImageSurface> sf) 37 : CairoWidget() 38 , _surface(sf) 39 { 40 set_size_request (sf->get_width (), sf->get_height ()); 41 } 42 43 protected: background(cairo_t * cr,cairo_rectangle_t * r)44 virtual void background (cairo_t* cr, cairo_rectangle_t* r) { 45 cairo_set_source_surface (cr, _surface->cobj(), 0, 0); 46 cairo_set_operator (cr, CAIRO_OPERATOR_OVER); 47 cairo_paint (cr); 48 } 49 overlay(cairo_t * cr,cairo_rectangle_t * r)50 virtual void overlay (cairo_t* cr, cairo_rectangle_t* r) {} 51 render(Cairo::RefPtr<Cairo::Context> const & ctx,cairo_rectangle_t * r)52 virtual void render (Cairo::RefPtr<Cairo::Context> const& ctx, cairo_rectangle_t* r) 53 { 54 ctx->rectangle (r->x, r->y, r->width, r->height); 55 ctx->clip (); 56 background (ctx->cobj(), r); 57 overlay (ctx->cobj(), r); 58 } 59 60 Cairo::RefPtr<Cairo::ImageSurface> _surface; 61 }; 62 63 class CimgPlayheadArea : public CimgArea 64 { 65 public: 66 CimgPlayheadArea (Cairo::RefPtr<Cairo::ImageSurface> sf, float x0, float w, bool h = false) CimgArea(sf)67 : CimgArea (sf) 68 , _playhead(-1) 69 , _x0 (x0) 70 , _aw (w) 71 , _highlight (h) 72 { 73 } 74 set_playhead(float pos)75 void set_playhead (float pos) { 76 if (rint (_playhead * _aw) == rint (pos * _aw)) { 77 return; 78 } 79 if (_playhead == -1 || pos == -1) { 80 set_dirty (); 81 } else { 82 invalidate (_playhead); 83 invalidate (pos); 84 } 85 _playhead = pos; 86 } 87 88 sigc::signal<void, float> seek_playhead; 89 90 protected: 91 overlay(cairo_t * cr,cairo_rectangle_t * r)92 virtual void overlay (cairo_t* cr, cairo_rectangle_t* r) { 93 if (_playhead > 0 && _playhead < 1.0 && _aw > 0) { 94 if (_highlight) { 95 cairo_rectangle (cr, _x0, 0, _aw, _surface->get_height()); 96 cairo_set_source_rgba (cr, .4, .4, .6, .4); 97 cairo_fill (cr); 98 } 99 100 const float x = _playhead * _aw; 101 const float h = _surface->get_height(); 102 cairo_set_source_rgba (cr, 1, 0, 0, 1); 103 cairo_set_line_width (cr, 1.5); 104 cairo_move_to (cr, _x0 + x, 0); 105 cairo_line_to (cr, _x0 + x, h); 106 cairo_stroke (cr); 107 } 108 } 109 on_button_press_event(GdkEventButton * ev)110 bool on_button_press_event (GdkEventButton *ev) { 111 CairoWidget::on_button_press_event (ev); 112 if (ev->button == 1 && _aw > 0 && ev->x >= _x0 && ev->x <= _x0 + _aw) { 113 seek_playhead (((float) ev->x - _x0) / (float)_aw); 114 } 115 return true; 116 } 117 118 private: 119 float _playhead; 120 float _x0, _aw; 121 bool _highlight; 122 invalidate(float pos)123 void invalidate (float pos) { 124 if (pos < 0 || pos > 1) { return; } 125 const float x = pos * _aw; 126 cairo_rectangle_t r; 127 r.y = 0; 128 r.x = _x0 + x - 1; 129 r.width = 3; 130 r.height = _surface->get_height(); 131 set_dirty (&r); 132 } 133 }; 134 135 class CimgWaveArea : public CimgPlayheadArea 136 { 137 public: CimgWaveArea(Cairo::RefPtr<Cairo::ImageSurface> sf,Cairo::RefPtr<Cairo::ImageSurface> sf_log,Cairo::RefPtr<Cairo::ImageSurface> sf_rect,Cairo::RefPtr<Cairo::ImageSurface> sf_logrec,float x0,float w)138 CimgWaveArea ( 139 Cairo::RefPtr<Cairo::ImageSurface> sf, 140 Cairo::RefPtr<Cairo::ImageSurface> sf_log, 141 Cairo::RefPtr<Cairo::ImageSurface> sf_rect, 142 Cairo::RefPtr<Cairo::ImageSurface> sf_logrec, 143 float x0, float w) 144 : CimgPlayheadArea (sf, x0, w) 145 , _sf_log (sf_log) 146 , _sf_rect (sf_rect) 147 , _sf_logrec (sf_logrec) 148 , _logscale (false) 149 , _rectified (false) 150 { 151 } 152 set_logscale(bool en)153 void set_logscale (bool en) { 154 _logscale = en; 155 set_dirty (); 156 } 157 set_rectified(bool en)158 void set_rectified (bool en) { 159 _rectified = en; 160 set_dirty (); 161 } 162 163 protected: 164 background(cairo_t * cr,cairo_rectangle_t * r)165 virtual void background (cairo_t* cr, cairo_rectangle_t* r) { 166 if (_logscale && _rectified) { 167 cairo_set_source_surface (cr, _sf_logrec->cobj(), 0, 0); 168 } else if (_logscale) { 169 cairo_set_source_surface (cr, _sf_log->cobj(), 0, 0); 170 } else if (_rectified) { 171 cairo_set_source_surface (cr, _sf_rect->cobj(), 0, 0); 172 } else { 173 cairo_set_source_surface (cr, _surface->cobj(), 0, 0); 174 } 175 cairo_set_operator (cr, CAIRO_OPERATOR_OVER); 176 cairo_paint (cr); 177 } 178 179 private: 180 Cairo::RefPtr<Cairo::ImageSurface> _sf_log; 181 Cairo::RefPtr<Cairo::ImageSurface> _sf_rect; 182 Cairo::RefPtr<Cairo::ImageSurface> _sf_logrec; 183 bool _logscale; 184 bool _rectified; 185 }; 186 187 class ExportReport : public ArdourDialog 188 { 189 public: 190 typedef boost::shared_ptr<ARDOUR::ExportStatus> StatusPtr; 191 ExportReport (ARDOUR::Session*, StatusPtr); 192 ExportReport (const std::string & title, const ARDOUR::AnalysisResults & ar); 193 int run (); 194 on_response(int response_id)195 void on_response (int response_id) { 196 Gtk::Dialog::on_response (response_id); 197 } 198 199 private: 200 void init (const ARDOUR::AnalysisResults &, bool); 201 202 void open_folder (std::string); 203 void audition (std::string, unsigned int, int); 204 void stop_audition (); 205 void play_audition (); 206 void audition_active (bool); 207 void audition_seek (int, float); 208 void audition_progress (ARDOUR::samplecnt_t, ARDOUR::samplecnt_t); 209 void on_switch_page (GtkNotebookPage*, guint page_num); 210 void on_logscale_toggled (Gtk::ToggleButton*); 211 void on_rectivied_toggled (Gtk::ToggleButton*); 212 213 Gtk::Notebook pages; 214 ARDOUR::Session* _session; 215 Gtk::Button* stop_btn; 216 Gtk::Button* play_btn; 217 PBD::ScopedConnectionList auditioner_connections; 218 219 struct AuditionInfo { AuditionInfoAuditionInfo220 AuditionInfo (std::string p, unsigned int c) : path (p), channels (c) {} AuditionInfoAuditionInfo221 AuditionInfo () : channels (0) {} 222 std::string path; 223 unsigned int channels; 224 }; 225 226 std::map<int, std::list<CimgPlayheadArea*> > timeline; 227 std::map<int, AuditionInfo> files; 228 std::list<CimgWaveArea*> waves; 229 230 int _audition_num; 231 int _page_num; 232 }; 233 234 #endif 235