home *** CD-ROM | disk | FTP | other *** search
/ Geek 6 / Geek-006.iso / linux / video / xmovie-1.5.3.tar.gz / xmovie-1.5.3.tar / xmovie-1.5.3 / guicast / bcmeter.C < prev    next >
C/C++ Source or Header  |  2000-11-29  |  8KB  |  374 lines

  1. #include "bcbutton.h"
  2. #include "bcmeter.h"
  3. #include "bcpixmap.h"
  4. #include "bcresources.h"
  5. #include "bcwindow.h"
  6. #include "colors.h"
  7. #include "fonts.h"
  8. #include "vframe.h"
  9. #include <string.h>
  10.  
  11. #define METERLEFT_BG 0
  12. #define METERLEFT_GREEN 1
  13. #define METERLEFT_RED 2
  14. #define METERLEFT_YELLOW 3
  15. #define METERMID_BG 4
  16. #define METERMID_GREEN 5
  17. #define METERMID_RED 6
  18. #define METERMID_YELLOW 7
  19. #define METERRIGHT_BG 8
  20. #define METERRIGHT_GREEN 9
  21. #define METERRIGHT_RED 10
  22. #define METERRIGHT_YELLOW 11
  23.  
  24. #define TITLE_W 25
  25.  
  26. BC_Meter::BC_Meter(int x, 
  27.     int y, 
  28.     int orientation, 
  29.     int pixels, 
  30.     float min, 
  31.     int mode, 
  32.     int use_titles,
  33.     long over_delay,
  34.     long peak_delay)
  35.  : BC_SubWindow(x, y, -1, -1)
  36. {
  37.     this->use_titles = use_titles;
  38.     this->over_delay = over_delay;
  39.     this->peak_delay = peak_delay;
  40.     this->min = min;
  41.     this->mode = mode;
  42.     this->orientation = orientation;
  43.     this->pixels = pixels;
  44.     this->meter_titles = labs((int)(min / 5)) + 1;
  45.     title_pixel = new int[meter_titles];
  46.     db_titles = new char*[meter_titles];
  47.     for(int i = 0; i < TOTAL_METER_IMAGES; i++) images[i] = 0;
  48.     for(int i = 0; i < meter_titles; i++) db_titles[i] = 0;
  49. }
  50.  
  51. BC_Meter::~BC_Meter()
  52. {
  53.     if(use_titles)
  54.     {
  55.         for(int i = 0; i < meter_titles; i++) delete db_titles[i];
  56.     }
  57.     delete [] db_titles;
  58.     delete [] title_pixel;
  59.     for(int i = 0; i < TOTAL_METER_IMAGES; i++) delete images[i];
  60. }
  61.  
  62. int BC_Meter::set_delays(int over_delay, int peak_delay)
  63. {
  64.     this->over_delay = over_delay;
  65.     this->peak_delay = peak_delay;
  66.     return 0;
  67. }
  68.  
  69. int BC_Meter::initialize()
  70. {
  71.     peak_timer = 0;
  72.     level_pixel = peak_pixel = 0;
  73.     over_timer = 0;
  74.     over_count = 0;
  75.     peak = level = -100;
  76.  
  77.     if(orientation == METER_VERT)
  78.     {
  79.         VFrame *data[TOTAL_METER_IMAGES];
  80.         for(int i = 0; i < TOTAL_METER_IMAGES; i++)
  81.         {
  82.             data[i] = new VFrame(*get_resources()->meter_images[i]);
  83.             data[i]->rotate270();
  84.         }
  85.         set_images(data);
  86.         for(int i = 0; i < TOTAL_METER_IMAGES; i++)
  87.             delete data[i];
  88.  
  89.         h = pixels;
  90.         w = images[0]->get_w();
  91.         if(use_titles) w += TITLE_W;
  92.     }
  93.     else
  94.     {
  95.         set_images(get_resources()->meter_images);
  96.         h = images[0]->get_h();
  97.         w = pixels;
  98.         if(use_titles) h += TITLE_W;
  99.     }
  100.  
  101. // calibrate the db titles
  102.     get_divisions();
  103.  
  104.     BC_SubWindow::initialize();
  105.     draw_titles();
  106.     draw_face();
  107.     return 0;
  108. }
  109.  
  110. void BC_Meter::set_images(VFrame **data)
  111. {
  112.     for(int i = 0; i < TOTAL_METER_IMAGES; i++) delete images[i];
  113.     for(int i = 0; i < TOTAL_METER_IMAGES; i++) 
  114.         images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA);
  115. }
  116.  
  117. int BC_Meter::reposition_window(int x, int y, int pixels)
  118. {
  119.     this->pixels = pixels;
  120.     if(orientation == METER_VERT)
  121.         BC_SubWindow::reposition_window(x, y, get_w(), pixels);
  122.     else
  123.         BC_SubWindow::reposition_window(x, y, pixels, get_h());
  124.  
  125.     for(int i = 0; i < meter_titles; i++) delete db_titles[i];
  126.     get_divisions();
  127.     draw_titles();
  128.     draw_face();
  129.     return 0;
  130. }
  131.  
  132. int BC_Meter::reset()
  133. {
  134.     level_pixel = peak_pixel = 0;
  135.     peak_timer = 0;
  136.     over_timer = 0;
  137.     over_count = 0;
  138.     draw_face();
  139.     return 0;
  140. }
  141.  
  142. int BC_Meter::reset_over()
  143. {
  144.     over_timer = 0;
  145.     return 0;
  146. }
  147.  
  148. int BC_Meter::change_format(int mode)
  149. {
  150.     this->mode = mode;
  151.     return 0;
  152. }
  153.  
  154. int BC_Meter::level_to_pixel(float level)
  155. {
  156.     if(mode == METER_DB)
  157.         return pixels - 4 - (int)((level / min) * (pixels - 4));
  158.     else
  159.         return (int)(level * (pixels - 4));
  160. }
  161.  
  162.  
  163. void BC_Meter::get_divisions()
  164. {
  165.     int i;
  166.     float j, j_step;
  167.     float division, division_step;
  168.     char string[1024];
  169.  
  170.     division = METER_MARGIN;
  171.     division_step = (float)(pixels - METER_MARGIN * 3) / (meter_titles - 1);
  172.     j = 0;     // number for title
  173.     j_step = min / (meter_titles - 1);
  174.  
  175.     for(i = 0; i < meter_titles; i++)
  176.     {
  177.         sprintf(string, "%.0f", fabs(-j));
  178.         db_titles[i] = new char[strlen(string) + 1];
  179.         strcpy(db_titles[i], string);
  180.  
  181.         title_pixel[i] = (int)(division); 
  182.  
  183.         division += division_step;
  184.         j += j_step;
  185.     }
  186.  
  187.     medium_division = pixels - title_pixel[1];
  188.     low_division = pixels - title_pixel[4];
  189. }
  190.  
  191. void BC_Meter::draw_titles()
  192. {
  193.     if(!use_titles) return;
  194.  
  195.     draw_top_background(parent_window, 0, 0, TITLE_W, h);
  196.     set_font(SMALLFONT_3D);
  197.     
  198.     if(orientation == METER_HORIZ)
  199.     {
  200.         draw_top_background(parent_window, 0, 0, get_w(), TITLE_W);
  201.         for(int i = 0; i < meter_titles; i++)
  202.         {
  203.             draw_text(0, title_pixel[i], db_titles[i]);
  204.         }
  205.     }
  206.     else
  207.     if(orientation == METER_VERT)
  208.     {
  209.         draw_top_background(parent_window, 0, 0, TITLE_W, get_h());
  210.         for(int i = 0; i < meter_titles; i++)
  211.         {
  212. // Tick marks
  213.             if(i < meter_titles - 1)
  214.             {
  215.                 for(int j = 0; j < 6; j++)
  216.                 {
  217.                     int y1;
  218.                     int y2;
  219.                     int y;
  220.                     
  221.                     y1 = title_pixel[i];
  222.                     y2 = title_pixel[i + 1];
  223.                     y = (int)((float)(y2 - y1) * j / 5 + 0.5) + y1;
  224.                     
  225.                     if(j == 0 || j == 5)
  226.                     {
  227.                         set_color(RED);
  228.                         draw_line(TITLE_W - 10 - 1, y, TITLE_W - 1, y);
  229.                         set_color(BLACK);
  230.                         draw_line(TITLE_W - 10, y + 1, TITLE_W, y + 1);
  231.                     }
  232.                     else
  233.                     {
  234.                         set_color(RED);
  235.                         draw_line(TITLE_W - 5 - 1, y, TITLE_W - 1, y);
  236.                         set_color(BLACK);
  237.                         draw_line(TITLE_W - 5, y + 1, TITLE_W, y + 1);
  238.                     }
  239.                 }
  240.             }
  241.             set_color(RED);
  242.             if(i == 0)
  243.                 draw_text(0, title_pixel[i] + get_text_height(SMALLFONT_3D) / 2, db_titles[i]);
  244.             else
  245.                 draw_text(0, title_pixel[i] + get_text_height(SMALLFONT_3D) / 2, db_titles[i]);
  246.         }
  247.     }
  248. }
  249.  
  250. void BC_Meter::draw_face()
  251. {
  252.     VFrame **reference_images = get_resources()->meter_images;
  253.     int level_pixel = level_to_pixel(level);
  254.     int peak_pixel2 = level_to_pixel(peak);
  255.     int peak_pixel1 = peak_pixel2 - 2;
  256.     int left_pixel = reference_images[METERLEFT_BG]->get_w_fixed();
  257.     int right_pixel = pixels - reference_images[METERRIGHT_BG]->get_w_fixed();
  258.     int pixel = 0;
  259.     int image_number = 0;
  260.     int in_span, in_start;
  261.     int x = use_titles ? TITLE_W : 0;
  262.     int w = use_titles ? w - TITLE_W : w;
  263.  
  264.     draw_top_background(parent_window, x, 0, w, h);
  265.  
  266.     while(pixel < pixels)
  267.     {
  268. // Select image to draw
  269.         if(pixel < left_pixel)
  270.         {
  271.             image_number = METERLEFT_BG;
  272.             in_span = left_pixel - pixel;
  273.             in_start = pixel;
  274.         }
  275.         else
  276.         if(pixel < right_pixel)
  277.         {
  278.             image_number = METERMID_BG;
  279.             in_span = right_pixel - pixel;
  280.             in_start = 0;
  281.         }
  282.         else
  283.         {
  284.             image_number = METERRIGHT_BG;
  285.             in_span = pixels - right_pixel;
  286.             in_start = pixel - right_pixel;
  287.         }
  288.  
  289. // Select color of image
  290.         if(pixel < level_pixel ||
  291.             (pixel >= peak_pixel1 && pixel < peak_pixel2))
  292.         {
  293.             if(pixel < low_division)
  294.             {
  295.                 image_number += 1;
  296.                 if(pixel + in_span > low_division) in_span = low_division - pixel;
  297.             }
  298.             else
  299.             if(pixel < medium_division)
  300.             {
  301.                 image_number += 3;
  302.                 if(pixel + in_span > medium_division) in_span = medium_division - pixel;
  303.             }
  304.             else
  305.             {
  306.                 image_number += 2;
  307.             }
  308.         }
  309.  
  310. // Clip length to peaks
  311.         if(pixel < level_pixel && pixel + in_span > level_pixel)
  312.             in_span = level_pixel - pixel;
  313.         else
  314.         if(pixel < peak_pixel1 && pixel + in_span > peak_pixel1)
  315.             in_span = peak_pixel1 - pixel;
  316.         else
  317.         if(pixel < peak_pixel2 && pixel + in_span > peak_pixel2) 
  318.             in_span = peak_pixel2 - pixel;
  319.  
  320. // Clip length to bitmap
  321.         if(in_span + in_start > reference_images[image_number]->get_w_fixed()) 
  322.             in_span = reference_images[image_number]->get_w_fixed() - in_start;
  323.  
  324.         if(orientation == METER_HORIZ)
  325.             draw_pixmap(images[image_number], 
  326.                 pixel, 
  327.                 x, 
  328.                 in_span + 1, 
  329.                 get_h(), 
  330.                 in_start, 
  331.                 0);
  332.         else
  333.             draw_pixmap(images[image_number],
  334.                 x,
  335.                 get_h() - pixel - in_span,
  336.                 get_w(),
  337.                 in_span + 1,
  338.                 0,
  339.                 images[image_number]->get_h_fixed() - in_start - in_span);
  340.  
  341.         pixel += in_span;
  342.     }
  343.  
  344.     flash();
  345. }
  346.  
  347. int BC_Meter::update(float new_value, int over)
  348. {
  349.     peak_timer++;
  350.  
  351.     if(mode == METER_DB)
  352.     {
  353.         if(new_value == 0) 
  354.             level = min;
  355.         else
  356.             level = db.todb(new_value);        // db value
  357.     }
  358.  
  359.     if(level > peak || peak_timer > peak_delay)
  360.     {
  361.         peak = level;
  362.         peak_timer = 0;
  363.     }
  364.  
  365.     if(over) over_timer = over_delay;    
  366. // only draw if window is visible
  367.  
  368.     if(!top_level->get_hidden())
  369.     {
  370.         draw_face();
  371.     }
  372.     return 0;
  373. }
  374.