4 * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "edlsession.h"
26 #include "meterpanel.h"
28 #include "preferences.h"
34 MeterPanel::MeterPanel(MWindow *mwindow, BC_WindowBase *subwindow,
35 int x, int y, int w, int h, int meter_count,
36 int visible, int use_headroom, int use_titles)
38 this->subwindow = subwindow;
39 this->mwindow = mwindow;
44 this->meter_count = meter_count;
45 this->visible = visible;
46 this->use_headroom = use_headroom;
47 this->use_titles = use_titles;
51 MeterPanel::~MeterPanel()
53 meters.remove_all_objects();
54 meter_titles.remove_all_objects();
57 void MeterPanel::create_objects()
59 set_meters(meter_count, visible);
62 int MeterPanel::set_meters(int meter_count, int visible)
64 if(meter_count != meters.total || visible != this->visible)
67 if(meter_count != meters.total)
69 meters.remove_all_objects();
70 meter_titles.remove_all_objects();
71 meter_peaks.remove_all();
74 this->meter_count = meter_count;
75 this->visible = visible;
76 // if(!visible) this->meter_count = 0;
78 if(meter_count && !meters.size())
82 int h1 = get_meter_h();
83 int border = mwindow->theme->widget_border;
84 for(int i = 0; i < meter_count; i++)
86 //printf("MeterPanel::set_meters %d %d %d %d\n", __LINE__, i, x1, get_meter_w(i));
92 subwindow->add_subwindow(new_title = new BC_Title(
97 y1 += new_title->get_h() + border;
98 meter_titles.append(new_title);
101 MeterMeter *new_meter;
102 subwindow->add_subwindow(new_meter = new MeterMeter(mwindow,
106 this->w > 0 ? get_meter_w(i) : -1,
109 meters.append(new_meter);
110 x1 += get_meter_w(i) + border;
112 meter_peaks.append(0);
120 void MeterPanel::reposition_window(int x, int y, int w, int h)
127 //printf("MeterPanel::reposition_window 0 %d\n", meter_count);
129 int border = mwindow->theme->widget_border;
131 for(int i = 0; i < meter_count; i++)
135 meter_titles.get(i)->reposition_window(
136 get_title_x(i, meter_titles.get(i)->get_text()),
137 meter_titles.get(i)->get_y());
139 //printf("MeterPanel::reposition_window %d %d %d %d\n", __LINE__, i, x1, get_meter_w(i));
140 meters.get(i)->reposition_window(x1,
141 meters.get(i)->get_y(),
144 x1 += get_meter_w(i) + border;
148 int MeterPanel::change_status_event(int new_status)
150 //printf("MeterPanel::change_status_event\n");
154 int MeterPanel::get_reset_x()
157 get_meters_width(mwindow->theme, meter_count, visible) -
158 mwindow->theme->over_button[0]->get_w();
161 int MeterPanel::get_reset_y()
163 return y + h - mwindow->theme->over_button[0]->get_h();
166 int MeterPanel::get_title_x(int number, const char *text)
168 int border = mwindow->theme->widget_border;
171 for(int i = 0; i < meter_count; i++)
175 int text_w = subwindow->get_text_width(SMALLFONT, text);
177 int meter_w = (i == 0) ?
178 get_meter_w(i) - BC_Meter::get_title_w() :
180 title_x += (i == 0) ? BC_Meter::get_title_w() : 0;
181 title_x += meter_w / 2 -
183 title_x = MAX(title_x, x1);
184 if(i == 0) title_x = MAX(title_x, x1 + BC_Meter::get_title_w());
189 x1 += get_meter_w(i) + border;
194 int MeterPanel::get_meters_width(Theme *theme, int meter_count, int visible)
196 //printf("MeterPanel::get_meters_width %d %d\n", BC_Meter::get_title_w(), BC_Meter::get_meter_w());
198 (BC_Meter::get_title_w() +
199 theme->widget_border +
200 BC_Meter::get_meter_w() * meter_count +
201 theme->widget_border * (meter_count - 1)) :
206 int MeterPanel::get_meter_w(int number)
208 int border = mwindow->theme->widget_border;
211 meter_w = (w - BC_Meter::get_title_w() -
212 (meter_count - 1) * border) / meter_count;
213 if( meter_w < 3 ) meter_w = 3;
216 meter_w = BC_Meter::get_meter_w();
218 meter_w += BC_Meter::get_title_w();
222 int MeterPanel::get_meter_h()
224 int border = mwindow->theme->widget_border;
227 return h - border - subwindow->get_text_height(SMALLFONT);
235 void MeterPanel::update(double *levels)
237 if( !visible || subwindow->get_hidden()) return;
240 for(int i = 0; i < meter_count; i++)
242 meters.values[i]->update(levels[i], levels[i] > 1.0);
245 levels[i] > meter_peaks.get(i))
247 update_peak(i, levels[i]);
252 void MeterPanel::init_meters(int dmix)
254 for(int i = 0; i < meter_count; i++)
256 meters.values[i]->reset(dmix);
260 void MeterPanel::update_peak(int number, float value)
262 if(use_titles && number < meter_count)
264 meter_peaks.set(number, value);
266 float db_value = DB::todb(value);
267 char string[BCTEXTLEN] = { 0 };
268 if(db_value <= mwindow->edl->session->min_meter_db)
270 sprintf(string, "oo");
275 sprintf(string, "+%.1f",
280 sprintf(string, "%.1f",
284 meter_titles.get(number)->update(string);
285 meter_titles.get(number)->reposition_window(get_title_x(number, string),
286 meter_titles.get(number)->get_y());
290 void MeterPanel::stop_meters()
292 for(int i = 0; i < meter_count; i++)
294 meters.values[i]->reset();
295 // Reset peak without drawing
296 meter_peaks.set(i, 0);
301 void MeterPanel::reset_meters()
303 for(int i = 0; i < meters.size(); i++)
304 meters.values[i]->reset_over();
306 for(int i = 0; i < meter_titles.size(); i++)
313 void MeterPanel::change_format(int mode, int min, int max)
315 for(int i = 0; i < meters.total; i++)
318 meters.values[i]->change_format(mode, min, 0);
320 meters.values[i]->change_format(mode, min, max);
332 MeterReset::MeterReset(MWindow *mwindow, MeterPanel *panel, int x, int y)
333 : BC_Button(x, y, mwindow->theme->over_button)
335 this->mwindow = mwindow;
339 MeterReset::~MeterReset()
343 int MeterReset::handle_event()
345 for(int i = 0; i < panel->meters.total; i++)
346 panel->meters.values[i]->reset_over();
354 MeterMeter::MeterMeter(MWindow *mwindow,
355 MeterPanel *panel, int x, int y, int w, int h, int titles)
356 : BC_Meter(x, y, METER_VERT, h, mwindow->edl->session->min_meter_db,
357 panel->use_headroom ? 0 : mwindow->edl->session->max_meter_db,
358 mwindow->edl->session->meter_format, titles, w)
360 this->mwindow = mwindow;
362 set_delays(TRACKING_RATE * 10, TRACKING_RATE);
365 MeterMeter::~MeterMeter()
370 int MeterMeter::button_press_event()
372 if(is_event_win() && BC_WindowBase::cursor_inside())
374 panel->reset_meters();
375 mwindow->reset_meters();
386 MeterShow::MeterShow(MWindow *mwindow, MeterPanel *panel, int x, int y)
389 mwindow->theme->get_image_set("meters"),
392 this->mwindow = mwindow;
394 set_tooltip(_("Show meters"));
398 MeterShow::~MeterShow()
403 int MeterShow::handle_event()
405 //printf("MeterShow::MeterShow 1 %d\n",panel->visible );
406 // need to detect a change in visible, outside here
407 // panel->visible = get_value();
408 panel->change_status_event(get_value());