3 * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "bcsignals.h"
26 #include "scopewindow.h"
34 ScopePackage::ScopePackage()
44 ScopeUnit::ScopeUnit(ScopeGUI *gui,
55 void ScopeUnit::draw_point(unsigned char **rows,
62 unsigned char *pixel = rows[y] + x * 4;
68 #define PROCESS_PIXEL(column) \
70 /* Calculate histogram */ \
73 int v_i = (intensity - FLOAT_MIN) * (TOTAL_BINS / (FLOAT_MAX - FLOAT_MIN)); \
74 CLAMP(v_i, 0, TOTAL_BINS - 1); \
80 int r_i = (r - FLOAT_MIN) * (TOTAL_BINS / (FLOAT_MAX - FLOAT_MIN)); \
81 int g_i = (g - FLOAT_MIN) * (TOTAL_BINS / (FLOAT_MAX - FLOAT_MIN)); \
82 int b_i = (b - FLOAT_MIN) * (TOTAL_BINS / (FLOAT_MAX - FLOAT_MIN)); \
83 CLAMP(r_i, 0, TOTAL_BINS - 1); \
84 CLAMP(g_i, 0, TOTAL_BINS - 1); \
85 CLAMP(b_i, 0, TOTAL_BINS - 1); \
91 /* Calculate waveform */ \
92 if(use_wave || use_wave_parade) \
94 x = (column) * wave_w / w; \
95 if(x >= 0 && x < wave_w) \
100 (int)((r - FLOAT_MIN) / \
101 (FLOAT_MAX - FLOAT_MIN) * \
104 if(y >= 0 && y < wave_h) \
105 draw_point(waveform_rows, x / 3, y, 0xff, 0x0, 0x0); \
108 (int)((g - FLOAT_MIN) / \
109 (FLOAT_MAX - FLOAT_MIN) * \
112 if(y >= 0 && y < wave_h) \
113 draw_point(waveform_rows, x / 3 + wave_w / 3, y, 0x0, 0xff, 0x0); \
116 (int)((b - FLOAT_MIN) / \
117 (FLOAT_MAX - FLOAT_MIN) * \
120 if(y >= 0 && y < wave_h) \
121 draw_point(waveform_rows, x / 3 + wave_w / 3 * 2, y, 0x0, 0x0, 0xff); \
127 (int)((intensity - FLOAT_MIN) / \
128 (FLOAT_MAX - FLOAT_MIN) * \
131 if(y >= 0 && y < wave_h) \
132 draw_point(waveform_rows, \
142 /* Calculate vectorscope */ \
145 float adjacent = cos((h + 90) / 360 * 2 * M_PI); \
146 float opposite = sin((h + 90) / 360 * 2 * M_PI); \
148 x = (int)(vector_w / 2 + \
149 adjacent * (s) / (FLOAT_MAX) * radius); \
151 y = (int)(vector_h / 2 - \
152 opposite * (s) / (FLOAT_MAX) * radius); \
155 CLAMP(x, 0, vector_w - 1); \
156 CLAMP(y, 0, vector_h - 1); \
158 /* Get color with full saturation & value */ \
159 float r_f, g_f, b_f; \
160 HSV::hsv_to_rgb(r_f, \
167 draw_point(vector_rows, \
170 (int)(CLIP(r_f, 0, 1) * 255), \
171 (int)(CLIP(g_f, 0, 1) * 255), \
172 (int)(CLIP(b_f, 0, 1) * 255)); \
176 #define PROCESS_RGB_PIXEL(column, max) \
178 r = (float)*row++ / max; \
179 g = (float)*row++ / max; \
180 b = (float)*row++ / max; \
188 PROCESS_PIXEL(column) \
191 #define PROCESS_YUV_PIXEL(column, \
196 yuv.yuv_to_rgb_f(r, g, b, (float)y_in / 255, (float)(u_in - 0x80) / 255, (float)(v_in - 0x80) / 255); \
204 PROCESS_PIXEL(column) \
208 void ScopeUnit::process_package(LoadPackage *package)
210 ScopePackage *pkg = (ScopePackage*)package;
218 int use_hist = gui->use_hist;
219 int use_hist_parade = gui->use_hist_parade;
220 int use_vector = gui->use_vector;
221 int use_wave = gui->use_wave;
222 int use_wave_parade = gui->use_wave_parade;
223 BC_Bitmap *waveform_bitmap = gui->waveform_bitmap;
224 BC_Bitmap *vector_bitmap = gui->vector_bitmap;
225 int wave_h = waveform_bitmap->get_h();
226 int wave_w = waveform_bitmap->get_w();
227 int vector_h = vector_bitmap->get_h();
228 int vector_w = vector_bitmap->get_w();
230 int w = gui->output_frame->get_w();
231 float radius = MIN(gui->vector_w / 2, gui->vector_h / 2);
236 unsigned char **waveform_rows = waveform_bitmap->get_row_pointers();
237 unsigned char **vector_rows = vector_bitmap->get_row_pointers();
240 switch(gui->output_frame->get_color_model())
243 for(int i = pkg->row1; i < pkg->row2; i++)
245 unsigned char *row = gui->output_frame->get_rows()[i];
246 for(int j = 0; j < w; j++)
248 PROCESS_RGB_PIXEL(j, 255)
254 for(int i = pkg->row1; i < pkg->row2; i++)
256 unsigned char *row = gui->output_frame->get_rows()[i];
257 for(int j = 0; j < w; j++)
259 PROCESS_RGB_PIXEL(j, 255)
266 for(int i = pkg->row1; i < pkg->row2; i++)
268 float *row = (float*)gui->output_frame->get_rows()[i];
269 for(int j = 0; j < w; j++)
271 PROCESS_RGB_PIXEL(j, 1.0)
277 for(int i = pkg->row1; i < pkg->row2; i++)
279 float *row = (float*)gui->output_frame->get_rows()[i];
280 for(int j = 0; j < w; j++)
282 PROCESS_RGB_PIXEL(j, 1.0)
289 for(int i = pkg->row1; i < pkg->row2; i++)
291 unsigned char *row = gui->output_frame->get_rows()[i];
292 for(int j = 0; j < w; j++)
294 PROCESS_YUV_PIXEL(j, row[0], row[1], row[2])
301 for(int i = pkg->row1; i < pkg->row2; i++)
303 unsigned char *row = gui->output_frame->get_rows()[i];
304 for(int j = 0; j < w; j++)
306 PROCESS_YUV_PIXEL(j, row[0], row[1], row[2])
314 for(int i = pkg->row1; i < pkg->row2; i++)
316 unsigned char *y_row = gui->output_frame->get_y() + i * gui->output_frame->get_w();
317 unsigned char *u_row = gui->output_frame->get_u() + (i / 2) * (gui->output_frame->get_w() / 2);
318 unsigned char *v_row = gui->output_frame->get_v() + (i / 2) * (gui->output_frame->get_w() / 2);
319 for(int j = 0; j < w; j += 2)
321 PROCESS_YUV_PIXEL(j, *y_row, *u_row, *v_row);
323 PROCESS_YUV_PIXEL(j + 1, *y_row, *u_row, *v_row);
333 for(int i = pkg->row1; i < pkg->row2; i++)
335 unsigned char *row = gui->output_frame->get_rows()[i];
336 for(int j = 0; j < gui->output_frame->get_w(); j += 2)
338 PROCESS_YUV_PIXEL(j, row[0], row[1], row[3]);
339 PROCESS_YUV_PIXEL(j + 1, row[2], row[1], row[3]);
346 printf("ScopeUnit::process_package %d: color_model=%d unrecognized\n",
348 gui->output_frame->get_color_model());
359 ScopeEngine::ScopeEngine(ScopeGUI *gui, int cpus)
360 : LoadServer(cpus, cpus)
362 //printf("ScopeEngine::ScopeEngine %d cpus=%d\n", __LINE__, cpus);
366 ScopeEngine::~ScopeEngine()
370 void ScopeEngine::init_packages()
372 for(int i = 0; i < LoadServer::get_total_packages(); i++)
374 ScopePackage *pkg = (ScopePackage*)get_package(i);
375 pkg->row1 = gui->output_frame->get_h() * i / LoadServer::get_total_packages();
376 pkg->row2 = gui->output_frame->get_h() * (i + 1) / LoadServer::get_total_packages();
379 for(int i = 0; i < get_total_clients(); i++)
381 ScopeUnit *unit = (ScopeUnit*)get_client(i);
382 for(int j = 0; j < HIST_SECTIONS; j++)
383 bzero(unit->bins[j], sizeof(int) * TOTAL_BINS);
388 LoadClient* ScopeEngine::new_client()
390 return new ScopeUnit(gui, this);
393 LoadPackage* ScopeEngine::new_package()
395 return new ScopePackage;
398 void ScopeEngine::process()
402 for(int i = 0; i < HIST_SECTIONS; i++)
403 bzero(gui->bins[i], sizeof(int) * TOTAL_BINS);
405 for(int i = 0; i < get_total_clients(); i++)
407 ScopeUnit *unit = (ScopeUnit*)get_client(i);
408 for(int j = 0; j < HIST_SECTIONS; j++)
410 for(int k = 0; k < TOTAL_BINS; k++)
412 gui->bins[j][k] += unit->bins[j][k];
420 ScopeGUI::ScopeGUI(Theme *theme,
426 : PluginClientWindow(_(PROGRAM_NAME ": Scopes"),
444 ScopeGUI::ScopeGUI(PluginClient *plugin,
447 : PluginClientWindow(plugin,
458 this->theme = plugin->get_theme();
459 this->cpus = plugin->PluginClient::smp + 1;
463 ScopeGUI::~ScopeGUI()
465 delete waveform_bitmap;
466 delete vector_bitmap;
470 void ScopeGUI::reset()
484 wave_w = wave_h = vector_w = vector_h = 0;
488 void ScopeGUI::create_objects()
490 if(use_hist && use_hist_parade)
495 if(use_wave && use_wave_parade)
500 if(!engine) engine = new ScopeEngine(this,
503 lock_window("ScopeGUI::create_objects");
506 int x = theme->widget_border;
507 int y = theme->widget_border;
510 add_subwindow(hist_on = new ScopeToggle(this,
514 x += hist_on->get_w() + theme->widget_border;
516 add_subwindow(hist_parade_on = new ScopeToggle(this,
520 x += hist_parade_on->get_w() + theme->widget_border;
522 add_subwindow(waveform_on = new ScopeToggle(this,
526 x += waveform_on->get_w() + theme->widget_border;
527 add_subwindow(waveform_parade_on = new ScopeToggle(this,
531 x += waveform_parade_on->get_w() + theme->widget_border;
533 add_subwindow(vector_on = new ScopeToggle(this,
537 x += vector_on->get_w() + theme->widget_border;
539 add_subwindow(value_text = new BC_Title(x, y, ""));
540 x += value_text->get_w() + theme->widget_border;
542 y += vector_on->get_h() + theme->widget_border;
563 void ScopeGUI::create_panels()
565 calculate_sizes(get_w(), get_h());
568 if((use_wave || use_wave_parade))
572 add_subwindow(waveform = new ScopeWaveform(this,
577 waveform->create_objects();
581 waveform->reposition_window(wave_x,
585 waveform->clear_box(0, 0, wave_w, wave_h);
589 if(!(use_wave || use_wave_parade) && waveform)
599 add_subwindow(vectorscope = new ScopeVectorscope(this,
604 vectorscope->create_objects();
608 vectorscope->reposition_window(vector_x,
612 vectorscope->clear_box(0, 0, vector_w, vector_h);
616 if(!use_vector && vectorscope)
622 if((use_hist || use_hist_parade))
626 // printf("ScopeGUI::create_panels %d %d %d %d %d\n", __LINE__, hist_x,
630 add_subwindow(histogram = new ScopeHistogram(this,
635 histogram->create_objects();
639 histogram->reposition_window(hist_x,
643 histogram->clear_box(0, 0, hist_w, hist_h);
647 if(!(use_hist || use_hist_parade))
657 draw_overlays(1, 1, 0);
660 void ScopeGUI::clear_points(int flash)
662 if(histogram) histogram->clear_point();
663 if(waveform) waveform->clear_point();
664 if(vectorscope) vectorscope->clear_point();
665 if(histogram && flash) histogram->flash(0);
666 if(waveform && flash) waveform->flash(0);
667 if(vectorscope && flash) vectorscope->flash(0);
670 void ScopeGUI::toggle_event()
675 void ScopeGUI::calculate_sizes(int w, int h)
677 int margin = theme->widget_border;
678 int text_w = get_text_width(SMALLFONT, "000") + margin * 2;
679 int total_panels = ((use_hist || use_hist_parade) ? 1 : 0) +
680 ((use_wave || use_wave_parade) ? 1 : 0) +
681 (use_vector ? 1 : 0);
684 int panel_w = (w - margin) / (total_panels > 0 ? total_panels : 1);
685 // Vectorscope determines the size of everything else
690 vector_x = w - panel_w + text_w;
691 vector_w = w - margin - vector_x;
692 vector_y = vector_on->get_h() + margin * 2;
693 vector_h = h - vector_y - margin;
695 if(vector_w > vector_h)
698 vector_x = w - theme->widget_border - vector_w;
703 panel_w = (vector_x - text_w - margin) / total_panels;
706 // Histogram is always 1st panel
707 if(use_hist || use_hist_parade)
710 hist_y = vector_on->get_h() + margin * 2;
711 hist_w = panel_w - margin;
712 hist_h = h - hist_y - margin;
718 if(use_wave || use_wave_parade)
721 wave_y = vector_on->get_h() + margin * 2;
722 wave_w = panel_w - margin - text_w;
723 wave_h = h - wave_y - margin;
729 void ScopeGUI::allocate_bitmaps()
731 if(waveform_bitmap) delete waveform_bitmap;
732 if(vector_bitmap) delete vector_bitmap;
736 // printf("ScopeGUI::allocate_bitmaps %d %d %d %d %d\n",
744 waveform_bitmap = new_bitmap(w, h);
745 w = MAX(vector_w, 16);
746 h = MAX(vector_h, 16);
747 vector_bitmap = new_bitmap(w, h);
751 int ScopeGUI::resize_event(int w, int h)
753 clear_box(0, 0, w, h);
756 calculate_sizes(w, h);
760 waveform->reposition_window(wave_x, wave_y, wave_w, wave_h);
761 waveform->clear_box(0, 0, wave_w, wave_h);
766 histogram->reposition_window(hist_x, hist_y, hist_w, hist_h);
767 histogram->clear_box(0, 0, hist_w, hist_h);
772 vectorscope->reposition_window(vector_x, vector_y, vector_w, vector_h);
773 vectorscope->clear_box(0, 0, vector_w, vector_h);
780 draw_overlays(1, 1, 1);
785 int ScopeGUI::translation_event()
790 PluginClientWindow::translation_event();
795 void ScopeGUI::draw_overlays(int overlays, int borders, int flush)
797 BC_Resources *resources = BC_WindowBase::get_resources();
798 int text_color = GREEN;
799 if(resources->bg_color == 0xffffff)
804 if(overlays && borders)
806 clear_box(0, 0, get_w(), get_h());
812 set_color(text_color);
815 if(histogram && (use_hist || use_hist_parade))
817 histogram->draw_line(hist_w * -FLOAT_MIN / (FLOAT_MAX - FLOAT_MIN),
819 hist_w * -FLOAT_MIN / (FLOAT_MAX - FLOAT_MIN),
821 histogram->draw_line(hist_w * (1.0 - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN),
823 hist_w * (1.0 - FLOAT_MIN) / (FLOAT_MAX - FLOAT_MIN),
826 histogram->draw_point();
832 if(waveform && (use_wave || use_wave_parade))
834 set_color(text_color);
835 for(int i = 0; i <= WAVEFORM_DIVISIONS; i++)
837 int y = wave_h * i / WAVEFORM_DIVISIONS;
838 int text_y = y + wave_y + get_text_ascent(SMALLFONT) / 2;
839 CLAMP(text_y, waveform->get_y() + get_text_ascent(SMALLFONT), waveform->get_y() + waveform->get_h() - 1);
840 char string[BCTEXTLEN];
841 sprintf(string, "%d",
843 i * (FLOAT_MAX - FLOAT_MIN) / WAVEFORM_DIVISIONS) * 100));
844 int text_x = wave_x - get_text_width(SMALLFONT, string) - theme->widget_border;
845 draw_text(text_x, text_y, string);
847 int y1 = CLAMP(y, 0, waveform->get_h() - 1);
848 waveform->draw_line(0, y1, wave_w, y1);
849 //waveform->draw_rectangle(0, 0, wave_w, wave_h);
852 waveform->draw_point();
858 // Vectorscope overlay
859 if(vectorscope && use_vector)
861 set_color(text_color);
862 int radius = MIN(vector_w / 2, vector_h / 2);
863 for(int i = 1; i <= VECTORSCOPE_DIVISIONS; i += 2)
865 int x = vector_w / 2 - radius * i / VECTORSCOPE_DIVISIONS;
866 int y = vector_h / 2 - radius * i / VECTORSCOPE_DIVISIONS;
867 int text_y = y + vector_y + get_text_ascent(SMALLFONT) / 2;
868 int w = radius * i / VECTORSCOPE_DIVISIONS * 2;
869 int h = radius * i / VECTORSCOPE_DIVISIONS * 2;
870 char string[BCTEXTLEN];
872 sprintf(string, "%d",
873 (int)((FLOAT_MAX / VECTORSCOPE_DIVISIONS * i) * 100));
874 int text_x = vector_x - get_text_width(SMALLFONT, string) - theme->widget_border;
875 draw_text(text_x, text_y, string);
876 //printf("ScopeGUI::draw_overlays %d %d %d %s\n", __LINE__, text_x, text_y, string);
878 vectorscope->draw_circle(x, y, w, h);
879 //vectorscope->draw_rectangle(0, 0, vector_w, vector_h);
881 // vectorscope->draw_circle(vector_w / 2 - radius,
882 // vector_h / 2 - radius,
887 vectorscope->draw_point();
889 vectorscope->flash(0);
892 set_font(MEDIUMFONT);
898 if(use_hist || use_hist_parade)
900 draw_3d_border(hist_x - 2,
910 if(use_wave || use_wave_parade)
912 draw_3d_border(wave_x - 2,
924 draw_3d_border(vector_x - 2,
936 if(flush) this->flush();
941 void ScopeGUI::process(VFrame *output_frame)
943 lock_window("ScopeGUI::process");
944 this->output_frame = output_frame;
945 frame_w = output_frame->get_w();
946 //float radius = MIN(vector_w / 2, vector_h / 2);
948 bzero(waveform_bitmap->get_data(), waveform_bitmap->get_data_size());
949 bzero(vector_bitmap->get_data(), vector_bitmap->get_data_size());
956 histogram->draw(0, 0);
961 waveform->draw_bitmap(waveform_bitmap,
969 vectorscope->draw_bitmap(vector_bitmap,
975 draw_overlays(1, 0, 1);
980 void ScopeGUI::update_toggles()
982 hist_parade_on->update(use_hist_parade);
983 hist_on->update(use_hist);
984 waveform_parade_on->update(use_wave_parade);
985 waveform_on->update(use_wave);
986 vector_on->update(use_vector);
998 ScopePanel::ScopePanel(ScopeGUI *gui,
1003 : BC_SubWindow(x, y, w, h, BLACK)
1009 void ScopePanel::create_objects()
1011 set_cursor(CROSS_CURSOR, 0, 0);
1012 clear_box(0, 0, get_w(), get_h());
1015 void ScopePanel::update_point(int x, int y)
1019 void ScopePanel::draw_point()
1023 void ScopePanel::clear_point()
1027 int ScopePanel::button_press_event()
1029 if(is_event_win() && cursor_inside())
1031 gui->clear_points(1);
1034 int x = get_cursor_x();
1035 int y = get_cursor_y();
1036 CLAMP(x, 0, get_w() - 1);
1037 CLAMP(y, 0, get_h() - 1);
1045 int ScopePanel::cursor_motion_event()
1049 int x = get_cursor_x();
1050 int y = get_cursor_y();
1051 CLAMP(x, 0, get_w() - 1);
1052 CLAMP(y, 0, get_h() - 1);
1060 int ScopePanel::button_release_event()
1078 ScopeWaveform::ScopeWaveform(ScopeGUI *gui,
1083 : ScopePanel(gui, x, y, w, h)
1089 void ScopeWaveform::update_point(int x, int y)
1094 int frame_x = x * gui->frame_w / get_w();
1096 if(gui->use_wave_parade)
1098 if(x > get_w() / 3 * 2)
1099 frame_x = (x - get_w() / 3 * 2) * gui->frame_w / (get_w() / 3);
1102 frame_x = (x - get_w() / 3) * gui->frame_w / (get_w() / 3);
1104 frame_x = x * gui->frame_w / (get_w() / 3);
1107 float value = ((float)get_h() - y) / get_h() * (FLOAT_MAX - FLOAT_MIN) + FLOAT_MIN;
1109 char string[BCTEXTLEN];
1110 sprintf(string, "X: %d Value: %.3f", frame_x, value);
1111 gui->value_text->update(string, 0);
1117 void ScopeWaveform::draw_point()
1122 set_color(0xffffff);
1124 draw_line(0, drag_y, get_w(), drag_y);
1125 draw_line(drag_x, 0, drag_x, get_h());
1131 void ScopeWaveform::clear_point()
1144 ScopeVectorscope::ScopeVectorscope(ScopeGUI *gui,
1149 : ScopePanel(gui, x, y, w, h)
1155 void ScopeVectorscope::clear_point()
1163 void ScopeVectorscope::update_point(int x, int y)
1168 int radius = MIN(get_w() / 2, get_h() / 2);
1169 drag_radius = sqrt(SQR(x - get_w() / 2) + SQR(y - get_h() / 2));
1170 drag_angle = atan2(y - get_h() / 2, x - get_w() / 2);
1172 drag_radius = MIN(drag_radius, radius);
1174 float saturation = (float)drag_radius / radius * FLOAT_MAX;
1175 float hue = -drag_angle * 360 / 2 / M_PI - 90;
1176 if(hue < 0) hue += 360;
1178 char string[BCTEXTLEN];
1179 sprintf(string, "Hue: %.3f Sat: %.3f", hue, saturation);
1180 gui->value_text->update(string, 0);
1187 void ScopeVectorscope::draw_point()
1191 int radius = MIN(get_w() / 2, get_h() / 2);
1193 set_color(0xff0000);
1195 draw_circle(get_w() / 2 - drag_radius,
1196 get_h() / 2 - drag_radius,
1200 draw_line(get_w() / 2,
1202 get_w() / 2 + radius * cos(drag_angle),
1203 get_h() / 2 + radius * sin(drag_angle));
1211 ScopeHistogram::ScopeHistogram(ScopeGUI *gui,
1216 : ScopePanel(gui, x, y, w, h)
1221 void ScopeHistogram::clear_point()
1228 void ScopeHistogram::draw_point()
1233 set_color(0xffffff);
1235 draw_line(drag_x, 0, drag_x, get_h());
1241 void ScopeHistogram::update_point(int x, int y)
1245 float value = (float)x / get_w() * (FLOAT_MAX - FLOAT_MIN) + FLOAT_MIN;
1247 char string[BCTEXTLEN];
1248 sprintf(string, "Value: %.3f", value);
1249 gui->value_text->update(string, 0);
1257 void ScopeHistogram::draw_mode(int mode, int color, int y, int h)
1259 // Highest of all bins
1261 for(int i = 0; i < TOTAL_BINS; i++)
1263 if(gui->bins[mode][i] > normalize) normalize = gui->bins[mode][i];
1269 for(int i = 0; i < get_w(); i++)
1271 int accum_start = (int)(i * TOTAL_BINS / get_w());
1272 int accum_end = (int)((i + 1) * TOTAL_BINS / get_w());
1273 CLAMP(accum_start, 0, TOTAL_BINS);
1274 CLAMP(accum_end, 0, TOTAL_BINS);
1277 for(int k = accum_start; k < accum_end; k++)
1279 max = MAX(gui->bins[mode][k], max);
1282 // max = max * h / normalize;
1283 max = (int)(log(max) / log(normalize) * h);
1285 draw_line(i, y + h - max, i, y + h);
1289 void ScopeHistogram::draw(int flash, int flush)
1291 clear_box(0, 0, get_w(), get_h());
1293 if(gui->use_hist_parade)
1295 draw_mode(0, 0xff0000, 0, get_h() / 3);
1296 draw_mode(1, 0x00ff00, get_h() / 3, get_h() / 3);
1297 draw_mode(2, 0x0000ff, get_h() / 3 * 2, get_h() / 3);
1301 draw_mode(3, LTGREY, 0, get_h());
1304 if(flash) this->flash(0);
1305 if(flush) this->flush();
1313 ScopeToggle::ScopeToggle(ScopeGUI *gui,
1319 get_image_set(gui, value),
1323 this->value = value;
1324 if(value == &gui->use_hist_parade)
1326 set_tooltip(_("Histogram Parade"));
1329 if(value == &gui->use_hist)
1331 set_tooltip(_("Histogram"));
1334 if(value == &gui->use_wave_parade)
1336 set_tooltip(_("Waveform Parade"));
1339 if(value == &gui->use_wave)
1341 set_tooltip(_("Waveform"));
1345 set_tooltip(_("Vectorscope"));
1349 VFrame** ScopeToggle::get_image_set(ScopeGUI *gui, int *value)
1351 if(value == &gui->use_hist_parade)
1353 return gui->theme->get_image_set("histogram_rgb_toggle");
1356 if(value == &gui->use_hist)
1358 return gui->theme->get_image_set("histogram_toggle");
1361 if(value == &gui->use_wave_parade)
1363 return gui->theme->get_image_set("waveform_rgb_toggle");
1366 if(value == &gui->use_wave)
1368 return gui->theme->get_image_set("waveform_toggle");
1372 return gui->theme->get_image_set("scope_toggle");
1376 int ScopeToggle::handle_event()
1378 *value = get_value();
1379 if(value == &gui->use_hist_parade)
1381 if(get_value()) gui->use_hist = 0;
1384 if(value == &gui->use_hist)
1386 if(get_value()) gui->use_hist_parade = 0;
1389 if(value == &gui->use_wave_parade)
1391 if(get_value()) gui->use_wave = 0;
1394 if(value == &gui->use_wave)
1396 if(get_value()) gui->use_wave_parade = 0;
1400 gui->toggle_event();
1401 gui->update_toggles();
1402 gui->create_panels();