#pragma once #include "../core_include/api.h" #include "../core_include/wnd.h" #include "../core_include/display.h" #include "../core_include/resource.h" #include "../core_include/word.h" #include "../widgets_include/wave_buffer.h" #include #include #define CORRECT(x, high_limit, low_limit) {\ x = (x > high_limit) ? high_limit : x;\ x = (x < low_limit) ? low_limit : x;\ }while(0) #define WAVE_CURSOR_WIDTH 8 #define WAVE_LINE_WIDTH 1 #define WAVE_MARGIN 5 typedef enum { FILL_MODE, SCAN_MODE }E_WAVE_DRAW_MODE; class c_wave_buffer; class c_wave_ctrl : public c_wnd { public: c_wave_ctrl() { m_wave = 0; m_bg_fb = 0; m_wave_name_font = m_wave_unit_font = 0; m_wave_name = m_wave_unit = 0; m_max_data = 500; m_min_data = 0; m_wave_speed = 1; m_wave_data_rate = 0; m_wave_refresh_rate = 1000; m_frame_len_map_index = 0; m_wave_name_color = m_wave_unit_color = m_wave_color = GL_RGB(255, 0, 0); m_back_color = GL_RGB(0, 0, 0); } virtual void on_init_children()//should be pre_create { c_rect rect; get_screen_rect(rect); m_wave_left = rect.m_left + WAVE_MARGIN; m_wave_right = rect.m_right - WAVE_MARGIN; m_wave_top = rect.m_top + WAVE_MARGIN; m_wave_bottom = rect.m_bottom - WAVE_MARGIN; m_wave_cursor = m_wave_left; m_bg_fb = (unsigned int*)calloc(rect.width() * rect.height(), 4); } virtual void on_paint() { c_rect rect; get_screen_rect(rect); m_surface->fill_rect(rect, m_back_color, m_z_order); //show name c_word::draw_string(m_surface, m_z_order, m_wave_name, m_wave_left + 10, rect.m_top, m_wave_name_font, m_wave_name_color, GL_ARGB(0, 0, 0, 0)); //show unit c_word::draw_string(m_surface, m_z_order, m_wave_unit, m_wave_left + 60, rect.m_top, m_wave_unit_font, m_wave_unit_color, GL_ARGB(0, 0, 0, 0)); save_background(); } void set_wave_name(char* wave_name){ m_wave_name = wave_name;} void set_wave_unit(char* wave_unit){ m_wave_unit = wave_unit;} void set_wave_name_font(const LATTICE_FONT_INFO* wave_name_font_type){ m_wave_name_font = wave_name_font_type;} void set_wave_unit_font(const LATTICE_FONT_INFO* wave_unit_font_type){ m_wave_unit_font = wave_unit_font_type;} void set_wave_name_color(unsigned int wave_name_color){ m_wave_name_color = wave_name_color;} void set_wave_unit_color(unsigned int wave_unit_color){ m_wave_unit_color = wave_unit_color;} void set_wave_color(unsigned int color){ m_wave_color = color;} void set_wave_in_out_rate(unsigned int data_rate, unsigned int refresh_rate) { m_wave_data_rate = data_rate; m_wave_refresh_rate = refresh_rate; int read_times_per_second = m_wave_speed * 1000 / m_wave_refresh_rate; memset(m_frame_len_map, 0, sizeof(m_frame_len_map)); for (unsigned int i = 1; i < sizeof(m_frame_len_map) + 1; i++) { m_frame_len_map[i - 1] = data_rate * i / read_times_per_second - data_rate * (i - 1) / read_times_per_second; } m_frame_len_map_index = 0; } void set_wave_speed(unsigned int speed) { m_wave_speed = speed; set_wave_in_out_rate(m_wave_data_rate, m_wave_refresh_rate); } void set_max_min(short max_data, short min_data) { m_max_data = max_data; m_min_data = min_data; } void set_wave(c_wave_buffer* wave){m_wave = wave;} c_wave_buffer* get_wave(){return m_wave;} void clear_data() { if (m_wave == 0) { ASSERT(false); return; } m_wave->clear_data(); } bool is_data_enough() { if (m_wave == 0) { ASSERT(false); return false; } return (m_wave->get_cnt() - m_frame_len_map[m_frame_len_map_index] * m_wave_speed); } void refresh_wave(unsigned char frame) { if (m_wave == 0) { ASSERT(false); return; } short max, min, mid; for (short offset = 0; offset < m_wave_speed; offset++) { //get wave value mid = m_wave->read_wave_data_by_frame(max, min, m_frame_len_map[m_frame_len_map_index++], frame, offset); m_frame_len_map_index %= sizeof(m_frame_len_map); //map to wave ctrl int y_min, y_max; if (m_max_data == m_min_data) { ASSERT(false); } y_max = m_wave_bottom + WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (min - m_min_data) / (m_max_data - m_min_data); y_min = m_wave_bottom - WAVE_LINE_WIDTH - (m_wave_bottom - m_wave_top) * (max - m_min_data) / (m_max_data - m_min_data); mid = m_wave_bottom - (m_wave_bottom - m_wave_top) * (mid - m_min_data) / (m_max_data - m_min_data); CORRECT(y_min, m_wave_bottom, m_wave_top); CORRECT(y_max, m_wave_bottom, m_wave_top); CORRECT(mid, m_wave_bottom, m_wave_top); if (m_wave_cursor > m_wave_right) { m_wave_cursor = m_wave_left; } draw_smooth_vline(y_min, y_max, mid, m_wave_color); restore_background(); m_wave_cursor++; } } void clear_wave() { m_surface->fill_rect(m_wave_left, m_wave_top, m_wave_right, m_wave_bottom, m_back_color, m_z_order); m_wave_cursor = m_wave_left; } protected: void draw_smooth_vline(int y_min, int y_max, int mid, unsigned int rgb) { int dy = y_max - y_min; short r = GL_RGB_R(rgb); short g = GL_RGB_G(rgb); short b = GL_RGB_B(rgb); int index = (dy >> 1) + 2; int y; m_surface->draw_pixel(m_wave_cursor, mid, rgb, m_z_order); if (dy < 1) { return; } unsigned char cur_r, cur_g, cur_b; unsigned int cur_rgb; for (int i = 1; i <= (dy >> 1) + 1; ++i) { if ((mid + i) <= y_max) { y = mid + i; cur_r = r * (index - i) / index; cur_g = g * (index - i) / index; cur_b = b * (index - i) / index; cur_rgb = GL_RGB(cur_r, cur_g, cur_b); m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); } if ((mid - i) >= y_min) { y = mid - i; cur_r = r * (index - i) / index; cur_g = g * (index - i) / index; cur_b = b * (index - i) / index; cur_rgb = GL_RGB(cur_r, cur_g, cur_b); m_surface->draw_pixel(m_wave_cursor, y, cur_rgb, m_z_order); } } } void restore_background() { int x = m_wave_cursor + WAVE_CURSOR_WIDTH; if (x > m_wave_right) { x -= (m_wave_right - m_wave_left + 1); } c_rect rect; get_screen_rect(rect); register int width = rect.width(); register int top = rect.m_top; register int left = rect.m_left; for (int y_pos = (m_wave_top - 1); y_pos <= (m_wave_bottom + 1); y_pos++) { (m_bg_fb) ? m_surface->draw_pixel(x, y_pos, m_bg_fb[(y_pos - top) * width + (x - left)], m_z_order) : m_surface->draw_pixel(x, y_pos, 0, m_z_order); } } void save_background() { if (!m_bg_fb) { return; } c_rect rect; get_screen_rect(rect); register unsigned int* p_des = m_bg_fb; for (int y = rect.m_top; y <= rect.m_bottom; y++) { for (int x = rect.m_left; x <= rect.m_right; x++) { *p_des++ = m_surface->get_pixel(x, y, m_z_order); } } } char* m_wave_name; char* m_wave_unit; const LATTICE_FONT_INFO* m_wave_name_font; const LATTICE_FONT_INFO* m_wave_unit_font; unsigned int m_wave_name_color; unsigned int m_wave_unit_color; unsigned int m_wave_color; unsigned int m_back_color; int m_wave_left; int m_wave_right; int m_wave_top; int m_wave_bottom; short m_max_data; short m_min_data; private: c_wave_buffer* m_wave; unsigned int* m_bg_fb; //background frame buffer, could be used to draw scale line. int m_wave_cursor; int m_wave_speed; //pixels per refresh unsigned int m_wave_data_rate; //data sample rate unsigned int m_wave_refresh_rate;//refresh cycle in millisecond unsigned char m_frame_len_map[64]; unsigned char m_frame_len_map_index; };