Update Export Report GUI
[ardour.git] / gtk2_ardour / export_report.cc
1 /*
2  * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (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
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18
19 #include "export_report.h"
20
21 #include <gtkmm/label.h>
22 #include <gtkmm/stock.h>
23
24 #include "canvas/utils.h"
25 #include "canvas/colors.h"
26
27 #include <pangomm/layout.h>
28
29 #include "i18n.h"
30
31 using namespace Gtk;
32 using namespace ARDOUR;
33
34 ExportReport::ExportReport (StatusPtr s)
35         : ArdourDialog (_("Export Report/Analysis"))
36         , status (s)
37 {
38
39         AnalysisResults & ar = status->result_map;
40         //size_t n_results = ar.size();
41
42         for (AnalysisResults::iterator i = ar.begin(); i != ar.end(); ++i) {
43                 Label *l;
44                 VBox *vb = manage (new VBox());
45                 vb->set_spacing (6);
46
47                 l = manage (new Label(string_compose (_("File: %1"), i->first)));
48                 vb->pack_start (*l);
49
50                 ExportAnalysisPtr p = i->second;
51                 if (i->second->have_loudness) {
52                         Cairo::RefPtr<Cairo::ImageSurface> nums = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, 256, 128);
53                         Cairo::RefPtr<Cairo::ImageSurface> hist = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, 540, 128);
54
55                         Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (nums);
56                         cr->rectangle (0, 0, 256, 128);
57                         cr->set_source_rgba (0, 0, 0, 1.0);
58                         cr->fill ();
59
60                         int w, h;
61                         Glib::RefPtr<Pango::Layout> _layout = Pango::Layout::create (get_pango_context());
62                         //_layout->set_font_description (fd);
63                         _layout->set_text (string_compose (_("Loudness: %1%2 LUFS"), std::setprecision(1), p->loudness));
64                         _layout->get_pixel_size (w, h);
65                         _layout->set_alignment(Pango::ALIGN_LEFT);
66                         cr->move_to (6, 6);
67                         cr->set_source_rgba (.7, .7, .7, 1.0);
68                         _layout->show_in_cairo_context (cr);
69
70                         _layout->set_text (string_compose (_("Range: %1%2 LU"), std::setprecision(1), p->loudness_range));
71                         cr->move_to (6, 12 + h);
72                         _layout->show_in_cairo_context (cr);
73                         nums->flush ();
74
75                         /* draw loudness histogram */
76                         // TODO grid-lines.
77                         cr = Cairo::Context::create (hist);
78                         cr->rectangle (0, 0, 540, 128);
79                         cr->set_source_rgba (0, 0, 0, 1.0);
80                         cr->fill ();
81                         cr->set_source_rgba (.7, .7, .7, 1.0);
82                         cr->set_line_width (1.0);
83                         for (size_t x = 0 ; x < 510; ++x) {
84                                 cr->move_to (x - .5, 128.0);
85                                 cr->line_to (x - .5, 128.0 - 128.0 * p->loudness_hist[x] / (float) p->loudness_hist_max);
86                         }
87                         cr->stroke ();
88
89                         hist->flush ();
90                         CimgArea *nu = manage (new CimgArea (nums));
91                         CimgArea *hi = manage (new CimgArea (hist));
92                         HBox *hb = manage (new HBox());
93                         hb->set_spacing (4);
94                         hb->pack_start (*nu);
95                         hb->pack_start (*hi);
96                         vb->pack_start (*hb);
97                 }
98
99                 {
100                         // TODO re-use Canvas::WaveView::draw_image() somehow.
101                         const size_t peaks = sizeof(p->peaks) / sizeof (ARDOUR::PeakData::PeakDatum) / 2;
102                         const float height_2 = 100.0;
103                         Cairo::RefPtr<Cairo::ImageSurface> wave = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, peaks, 2 * height_2);
104                         Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (wave);
105                         cr->rectangle (0, 0, peaks, 2 * height_2);
106                         cr->set_source_rgba (0, 0, 0, 1.0);
107                         cr->fill ();
108                         cr->set_source_rgba (.7, .7, .7, 1.0);
109                         cr->set_line_width (1.0);
110                         for (size_t x = 0 ; x < peaks; ++x) {
111                                 cr->move_to (x - .5, height_2 - height_2 * p->peaks[x].max);
112                                 cr->line_to (x - .5, height_2 - height_2 * p->peaks[x].min);
113                         }
114                         cr->stroke ();
115                         wave->flush ();
116
117                         CimgArea *wv = manage (new CimgArea (wave));
118                         vb->pack_start (*wv);
119                 }
120
121                 {
122                         // TODO: get geometry from ExportAnalysis
123                         const size_t width = 800;
124                         const size_t height = 200;
125                         Cairo::RefPtr<Cairo::ImageSurface> spec = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, width, height);
126                         Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (spec);
127                         cr->rectangle (0, 0, width, height);
128                         cr->set_source_rgba (0, 0, 0, 1.0);
129                         cr->fill ();
130                         for (size_t x = 0 ; x < width; ++x) {
131                                 for (size_t y = 0 ; y < height; ++y) {
132                                         const float pk = p->spectrum[x][y];
133                                         ArdourCanvas::Color c = ArdourCanvas::hsva_to_color (252 - 260 * pk, .9, .3 + pk * .4);
134                                         ArdourCanvas::set_source_rgba (cr, c);
135                                         cr->rectangle (x - .5, y - .5, 1, 1);
136                                         cr->fill ();
137                                 }
138                         }
139                         spec->flush ();
140                         CimgArea *sp = manage (new CimgArea (spec));
141                         vb->pack_start (*sp);
142                 }
143
144                 // TODO ellipsize tab-text
145                 pages.pages().push_back (Notebook_Helpers::TabElem (*vb, Glib::path_get_basename (i->first)));
146         }
147
148         pages.set_show_tabs (true);
149         pages.show_all ();
150         pages.set_name ("ExportReportNotebook");
151         pages.set_current_page (0);
152
153         get_vbox()->set_spacing (12);
154         get_vbox()->pack_start (pages);
155
156         add_button (Stock::CLOSE, RESPONSE_ACCEPT);
157         set_default_response (RESPONSE_ACCEPT);
158         show_all ();
159         //pages.signal_switch_page().connect (sigc::mem_fun (*this, &ExportReport::handle_page_change));
160 }
161
162 int
163 ExportReport::run ()
164 {
165         return ArdourDialog::run ();
166 }