播放器浮动控制窗绘制正常了。
							parent
							
								
									f17c1cf59a
								
							
						
					
					
						commit
						00c79c47e2
					
				|  | @ -1,57 +1,551 @@ | |||
| #include "bar.h" | ||||
| 
 | ||||
| #include <QPainter> | ||||
| #include <QDebug> | ||||
| 
 | ||||
| 
 | ||||
| #define FONT_SIZE_DEFAULT           12 | ||||
| #define TIME_STR_PIXEL_SIZE         16 | ||||
| #define TEXT_COLOR                  QColor(255,255,255,153) | ||||
| 
 | ||||
| typedef struct RES_MAP { | ||||
|     RES_ID id; | ||||
|     const char* name; | ||||
| }RES_MAP; | ||||
| 
 | ||||
| static RES_MAP img_res[res__max] = { | ||||
|     {res_bg_left, "bg-left"}, | ||||
|     {res_bg_mid, "bg-mid"}, | ||||
|     {res_bg_right, "bg-right"}, | ||||
|     {res_bs_left, "btn-left"}, | ||||
|     {res_bs_mid, "btn-mid"}, | ||||
|     {res_bs_right, "btn-right"}, | ||||
|     {res_bsh_left, "btnsel-left"}, | ||||
|     {res_bsh_mid, "btnsel-mid"}, | ||||
|     {res_bsh_right, "btnsel-right"}, | ||||
|     {res_pbh_left, "prgbarh-left"}, | ||||
|     {res_pbh_mid, "prgbarh-mid"}, | ||||
|     {res_pb_mid, "prgbar-mid"}, | ||||
|     {res_pb_right, "prgbar-right"}, | ||||
| //    {res_pp, "prgpt"},
 | ||||
| //    {res_pph, "prgpt-hover"},
 | ||||
|     {res_cb, "select"}, | ||||
|     {res_cbh, "selected"}, | ||||
| //    {res_play, "play"},
 | ||||
| //    {res_play_hover, "play-hover"},
 | ||||
| //    {res_pause, "pause"},
 | ||||
| //    {res_pause_hover, "pause-hover"}
 | ||||
| }; | ||||
| 
 | ||||
| typedef struct SPEED_MAP { | ||||
|     int id; | ||||
|     const char* title; | ||||
| }SPEED_MAP; | ||||
| 
 | ||||
| static SPEED_MAP speed[speed_count] = { | ||||
|     {speed_1x, "1x"}, | ||||
|     {speed_2x, "2x"}, | ||||
|     {speed_4x, "4x"}, | ||||
|     {speed_8x, "8x"}, | ||||
|     {speed_16x, "16x"} | ||||
| }; | ||||
| 
 | ||||
| static inline int min(int a, int b){ | ||||
|     return a < b ? a : b; | ||||
| } | ||||
| 
 | ||||
| static inline int max(int a, int b){ | ||||
|     return a > b ? a : b; | ||||
| } | ||||
| 
 | ||||
| Bar::Bar() { | ||||
|     m_img_ready = false; | ||||
|     m_width = 0; | ||||
|     m_height = 0; | ||||
|     m_str_total_time = "00:00"; | ||||
|     m_str_passed_time = "00:00"; | ||||
|     m_str_passed_time_last_draw = "--:--"; | ||||
| 
 | ||||
|     m_percent = 0; | ||||
|     m_percent_last_draw = -1; | ||||
| 
 | ||||
|     m_play_hover = false; | ||||
|     m_playing = true; // 0=play, 2=pause
 | ||||
|     m_speed_selected = speed_1x; | ||||
|     m_speed_hover = speed_count;    // speed_count=no-hover
 | ||||
|     m_skip_selected = true; | ||||
| } | ||||
| 
 | ||||
| Bar::~Bar() { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| bool Bar::init(QWidget* owner, int width) { | ||||
| bool Bar::init(QWidget* owner) { | ||||
|     m_owner = owner; | ||||
| 
 | ||||
|     // 加载所需的图像资源
 | ||||
|     if(!m_bg_left.load(":/tp-player/res/bar/bg-left.png") | ||||
|             || !m_bg_mid.load(":/tp-player/res/bar/bg-mid.png") | ||||
|             || !m_bg_right.load(":/tp-player/res/bar/bg-right.png") | ||||
|             || !m_btn_left.load(":/tp-player/res/bar/btn-left.png") | ||||
|             || !m_btn_mid.load(":/tp-player/res/bar/btn-mid.png") | ||||
|             || !m_btn_right.load(":/tp-player/res/bar/btn-right.png") | ||||
|             || !m_btnsel_left.load(":/tp-player/res/bar/btnsel-left.png") | ||||
|             || !m_btnsel_mid.load(":/tp-player/res/bar/btnsel-mid.png") | ||||
|             || !m_btnsel_right.load(":/tp-player/res/bar/btnsel-right.png") | ||||
|             || !m_prgbarh_left.load(":/tp-player/res/bar/prgbarh-left.png") | ||||
|             || !m_prgbarh_mid.load(":/tp-player/res/bar/prgbarh-mid.png") | ||||
|             || !m_prgbar_left.load(":/tp-player/res/bar/prgbar-left.png") | ||||
|             || !m_prgbar_mid.load(":/tp-player/res/bar/prgbar-mid.png") | ||||
|             || !m_prgbar_right.load(":/tp-player/res/bar/prgbar-right.png") | ||||
|             || !m_prgpt.load(":/tp-player/res/bar/prgpt.png") | ||||
|             || !m_prgpt_hover.load(":/tp-player/res/bar/prgpt-hover.png") | ||||
|             || !m_select.load(":/tp-player/res/bar/select.png") | ||||
|             || !m_selected.load(":/tp-player/res/bar/selected.png") | ||||
|             || !m_play.load(":/tp-player/res/bar/play.png") | ||||
|             || !m_play_hover.load(":/tp-player/res/bar/play-hover.png") | ||||
|     ) | ||||
|     int i = 0; | ||||
|     for(i = 0; i < res__max; ++i) { | ||||
|         QString name; | ||||
|         name.sprintf(":/tp-player/res/bar/%s.png", img_res[i].name); | ||||
|         if(!m_res[i].load(name)) | ||||
|             return false; | ||||
|     } | ||||
| 
 | ||||
|     // 无需合成的图像
 | ||||
|     if(!m_img_btn_play[play_running][widget_normal].load(":/tp-player/res/bar/play.png") | ||||
|             || !m_img_btn_play[play_running][widget_hover].load(":/tp-player/res/bar/play-hover.png") | ||||
|             || !m_img_btn_play[play_paused][widget_normal].load(":/tp-player/res/bar/pause.png") | ||||
|             || !m_img_btn_play[play_paused][widget_hover].load(":/tp-player/res/bar/pause-hover.png") | ||||
|             || !m_img_progress_pointer[widget_normal].load(":/tp-player/res/bar/prgpt.png") | ||||
|             || !m_img_progress_pointer[widget_hover].load(":/tp-player/res/bar/prgpt-hover.png") | ||||
|             ) { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // 创建背景图像
 | ||||
|     m_bg = QPixmap(width, m_bg_left.height()); | ||||
|     m_bg.fill(Qt::transparent);//用透明色填充
 | ||||
|     QPainter pp(&m_bg); | ||||
|     pp.drawPixmap(0, 0, m_bg_left, 0, 0, m_bg_left.width(), m_bg_left.height()); | ||||
|     pp.drawPixmap(m_bg_left.width(), 0, m_bg.width() - m_bg_left.width() - m_bg_right.width(), m_bg_left.height(), m_bg_mid); | ||||
|     pp.drawPixmap(m_bg.width()-m_bg_right.width(), 0, m_bg_right, 0, 0, m_bg_right.width(), m_bg_right.height()); | ||||
| 
 | ||||
|     //pp.drawPixmap(10, 10, m_prgpt, 0, 0, m_prgpt.width(), m_prgpt.height());
 | ||||
|     pp.drawPixmap(10, 10, m_play.width(), m_play.height(), m_play); | ||||
| 
 | ||||
|     m_height = m_res[res_bg_left].height(); | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void Bar::draw(QPainter& painter, const QRect& rc){ | ||||
|     painter.drawPixmap(10, 150, m_bg, 0, 0, m_bg.width(), m_bg.height()); | ||||
| void Bar::start(uint32_t total_ms, int width) { | ||||
|     bool is_first_start = (m_width == 0); | ||||
|     m_width = width; | ||||
| 
 | ||||
|     m_total_ms = total_ms; | ||||
|     _ms_to_str(total_ms, m_str_total_time); | ||||
| 
 | ||||
| 
 | ||||
|     // 首次播放时,调整位置左右居中,距窗口顶部10点处。
 | ||||
|     if(is_first_start) { | ||||
|         _init_imgages(); | ||||
|         QRect rc = m_owner->rect(); | ||||
|         m_rc = QRect(0, 0, m_width, m_height); | ||||
|         m_rc.moveTo((rc.width() - m_width)/2, 10); | ||||
|         //m_rc.moveTo(10, 600);
 | ||||
|         qDebug("m_rc (%d,%d)-(%d,%d)", m_rc.left(), m_rc.top(), m_rc.right(), m_rc.bottom()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Bar::end() { | ||||
|     if(m_passed_ms != m_total_ms) | ||||
|         update_passed_time(m_total_ms); | ||||
| } | ||||
| 
 | ||||
| void Bar::_init_imgages() { | ||||
|     m_img_bg = QPixmap(m_width, m_height); | ||||
|     m_img_bg.fill(Qt::transparent);//用透明色填充
 | ||||
|     QPainter pp(&m_img_bg); | ||||
|     QFont font = pp.font(); | ||||
| 
 | ||||
|     // 合成背景图像
 | ||||
|     { | ||||
| 
 | ||||
|         pp.drawPixmap(0, 0, m_res[res_bg_left].width(), m_res[res_bg_left].height(), m_res[res_bg_left]); | ||||
|         pp.drawPixmap(m_res[res_bg_left].width(), 0, m_width - m_res[res_bg_left].width() - m_res[res_bg_right].width(), m_height, m_res[res_bg_mid]); | ||||
|         pp.drawPixmap(m_width-m_res[res_bg_right].width(), 0, m_res[res_bg_right].width(), m_height, m_res[res_bg_right]); | ||||
|     } | ||||
| 
 | ||||
|     { | ||||
|         m_rc_btn_play = QRect(15, (m_height - m_img_btn_play[play_running][widget_normal].height())/2 , m_img_btn_play[play_running][widget_normal].width(), m_img_btn_play[play_running][widget_normal].height()); | ||||
|     } | ||||
| 
 | ||||
|     // 合成速度按钮
 | ||||
|     { | ||||
|         int w = 42, h = m_res[res_bs_left].height(); | ||||
|         QRect rc(0, 0, w, h); | ||||
|         QPixmap btn[widget__max]; | ||||
| 
 | ||||
|         // 未选中状态
 | ||||
|         btn[widget_normal] = QPixmap(w, h); | ||||
|         btn[widget_normal].fill(Qt::transparent);//用透明色填充
 | ||||
|         QPainter pn(&btn[widget_normal]); | ||||
|         pn.drawPixmap(0, 0, m_res[res_bs_left].width(), m_res[res_bs_left].height(), m_res[res_bs_left]); | ||||
|         pn.drawPixmap(m_res[res_bs_left].width(), 0, w - m_res[res_bs_left].width() - m_res[res_bs_right].width(), h, m_res[res_bs_mid]); | ||||
|         pn.drawPixmap(w-m_res[res_bs_right].width(), 0, m_res[res_bs_right].width(), h, m_res[res_bs_right]); | ||||
|         // 选中状态
 | ||||
|         btn[widget_hover] = QPixmap(w, h); | ||||
|         btn[widget_hover].fill(Qt::transparent);//用透明色填充
 | ||||
|         QPainter ph(&btn[widget_hover]); | ||||
|         ph.drawPixmap(0, 0, m_res[res_bsh_left].width(), m_res[res_bsh_left].height(), m_res[res_bsh_left]); | ||||
|         ph.drawPixmap(m_res[res_bsh_left].width(), 0, w - m_res[res_bsh_left].width() - m_res[res_bsh_right].width(), h, m_res[res_bsh_mid]); | ||||
|         ph.drawPixmap(w-m_res[res_bsh_right].width(), 0, m_res[res_bsh_right].width(), h, m_res[res_bsh_right]); | ||||
| 
 | ||||
|         for(int i = 0; i < widget__max; ++i) { | ||||
|             for(int j = 0; j < speed_count; ++j) { | ||||
|                 m_img_btn_speed[j][i] = QPixmap(w, h); | ||||
|                 m_img_btn_speed[j][i].fill(Qt::transparent); | ||||
|                 QPainter ps(&m_img_btn_speed[j][i]); | ||||
|                 ps.setPen(TEXT_COLOR); | ||||
|                 QFont font = ps.font(); | ||||
|                 font.setFamily("consolas"); | ||||
|                 font.setPixelSize(FONT_SIZE_DEFAULT); | ||||
|                 ps.setFont(font); | ||||
|                 ps.drawPixmap(0, 0, w, h, btn[i]); | ||||
|                 ps.drawText(rc, Qt::AlignCenter, speed[j].title); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 合成跳过无操作选项
 | ||||
|     { | ||||
|         // 计算显示跳过无操作选项字符串的宽高
 | ||||
|         font.setFamily("微软雅黑"); | ||||
|         font.setBold(false); | ||||
|         font.setPixelSize(FONT_SIZE_DEFAULT); | ||||
|         pp.setFont(font); | ||||
|         QFontMetrics fm = pp.fontMetrics(); | ||||
| 
 | ||||
|         { | ||||
|             int h = fm.height(); | ||||
|             if(h < m_res[res_cb].height()) | ||||
|                 h = m_res[res_cb].height(); | ||||
|             m_rc_skip = QRect(0, 0, fm.width("无操作则跳过")+8+m_res[res_cb].width(), h); | ||||
|         } | ||||
| 
 | ||||
|         int w = m_rc_skip.width(); | ||||
|         int h = m_rc_skip.height(); | ||||
|         int chkbox_top = (m_rc_skip.height() - m_res[res_cb].height()) / 2; | ||||
|         int text_left = m_res[res_cb].width() + 8; | ||||
|         int text_top = (m_rc_skip.height() - fm.height()) / 2; | ||||
| 
 | ||||
|         { | ||||
|             m_img_skip[widget_normal] = QPixmap(w,h); | ||||
|             m_img_skip[widget_normal].fill(Qt::transparent); | ||||
|             QPainter ps(&m_img_skip[widget_normal]); | ||||
|             ps.setPen(TEXT_COLOR); | ||||
|             QFont font = ps.font(); | ||||
|             font.setFamily("微软雅黑"); | ||||
|             font.setPixelSize(FONT_SIZE_DEFAULT); | ||||
|             ps.setFont(font); | ||||
|             ps.drawPixmap(0, chkbox_top, m_res[res_cb].width(), m_res[res_cb].height(), m_res[res_cb]); | ||||
|             ps.drawText(QRect(text_left, text_top, w-text_left, h-text_top), Qt::AlignCenter, "无操作则跳过"); | ||||
|         } | ||||
| 
 | ||||
|         { | ||||
|             m_img_skip[widget_hover] = QPixmap(w,h); | ||||
|             m_img_skip[widget_hover].fill(Qt::transparent); | ||||
|             QPainter ps(&m_img_skip[widget_hover]); | ||||
|             ps.setPen(TEXT_COLOR); | ||||
|             QFont font = ps.font(); | ||||
|             font.setFamily("微软雅黑"); | ||||
|             font.setPixelSize(FONT_SIZE_DEFAULT); | ||||
|             ps.setFont(font); | ||||
|             ps.drawPixmap(0, chkbox_top, m_res[res_cbh].width(), m_res[res_cbh].height(), m_res[res_cbh]); | ||||
|             ps.drawText(QRect(text_left, text_top, w-text_left, h-text_top), Qt::AlignCenter, "无操作则跳过"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     { | ||||
|         // 计算显示时间所需的宽高
 | ||||
|         font.setFamily("consolas"); | ||||
|         font.setBold(true); | ||||
|         font.setPixelSize(TIME_STR_PIXEL_SIZE); | ||||
|         pp.setFont(font); | ||||
|         { | ||||
|             QFontMetrics fm = pp.fontMetrics(); | ||||
|             m_rc_time_passed = QRect(0, 0, fm.width("00:00:00"), fm.height()); | ||||
|             m_rc_time_total = m_rc_time_passed; | ||||
|         } | ||||
| 
 | ||||
|         m_img_time_total = QPixmap(m_rc_time_total.width(), m_rc_time_total.height()); | ||||
|         m_img_time_total.fill(Qt::transparent); | ||||
|         QPainter pp(&m_img_time_total); | ||||
|         pp.setPen(TEXT_COLOR); | ||||
|         QFont font = pp.font(); | ||||
|         font.setFamily("consolas"); | ||||
|         font.setBold(true); | ||||
|         font.setPixelSize(TIME_STR_PIXEL_SIZE); | ||||
|         pp.setFont(font); | ||||
|         pp.drawText(m_rc_time_total, Qt::AlignLeft, m_str_total_time); | ||||
| 
 | ||||
|         // 定位时间字符串的位置
 | ||||
|         m_rc_time_passed.moveTo(15+m_img_btn_play[play_running][widget_normal].width()+10, 18); | ||||
|         m_rc_time_total.moveTo(m_width - 15 - m_rc_time_total.width(), 18); | ||||
| 
 | ||||
|         int prog_width = m_rc_time_total.left() - 10 - 10 - m_rc_time_passed.right();// - m_img_progress_pointer[widget_normal].width();
 | ||||
|         int prog_height = max(m_res[res_pbh_left].height(), m_img_progress_pointer->height()); | ||||
|         m_rc_progress = QRect(0, 0, prog_width, prog_height); | ||||
|         m_rc_progress.moveTo(m_rc_time_passed.right() + 10, m_rc_time_passed.height() + (m_rc_time_passed.height() - prog_height)/2); | ||||
| 
 | ||||
|         qDebug("prog: %d,%d  w:%d,h:%d", m_rc_progress.left(), m_rc_progress.top(), prog_width, prog_height); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // 定位速度按钮
 | ||||
|     { | ||||
|         int left = m_rc_time_passed.right() + 10; | ||||
|         int top = m_rc_time_passed.bottom() + 8; | ||||
|         for(int i = 0; i < speed_count; i++) { | ||||
|             m_rc_btn_speed[i] = QRect(left, top, m_img_btn_speed[i][widget_normal].width(), m_img_btn_speed[i][widget_normal].height()); | ||||
|             left += m_img_btn_speed[i][widget_normal].width() + 8; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 定位跳过选项
 | ||||
|     { | ||||
|         int left = m_rc_time_total.left() - m_rc_skip.width() - 10; | ||||
|         int top = m_rc_time_passed.bottom() + 10; | ||||
|         m_rc_skip.moveTo(left, top); | ||||
|     } | ||||
| 
 | ||||
|     m_img_ready = true; | ||||
| } | ||||
| 
 | ||||
| void Bar::_ms_to_str(uint32_t ms, QString& str) { | ||||
|     int h = 0, m = 0, s = 0; | ||||
|     s = ms / 1000; | ||||
|     if(ms % 1000 > 500) | ||||
|         s += 1; | ||||
| 
 | ||||
|     h = s / 3600; | ||||
|     s = s % 3600; | ||||
|     m = s / 60; | ||||
|     s = s % 60; | ||||
| 
 | ||||
|     if(h > 0) | ||||
|         str.sprintf("%02d:%02d:%02d", h, m, s); | ||||
|     else | ||||
|         str.sprintf("%02d:%02d", m, s); | ||||
| } | ||||
| 
 | ||||
| void Bar::update_passed_time(uint32_t ms) { | ||||
|     QString str_passed; | ||||
|     _ms_to_str(ms, str_passed); | ||||
| 
 | ||||
|     if(m_str_passed_time != str_passed) | ||||
|     { | ||||
|         m_str_passed_time = str_passed; | ||||
|         m_owner->update(m_rc.left()+m_rc_time_passed.left(), m_rc.top()+m_rc_time_passed.top(), m_rc_time_passed.width(), m_rc_time_passed.height()); | ||||
|     } | ||||
| 
 | ||||
|     int percent = 0; | ||||
|     if(ms > m_total_ms) { | ||||
|         percent = 100; | ||||
|         m_passed_ms = m_total_ms; | ||||
|     } | ||||
|     else { | ||||
|         m_passed_ms = ms; | ||||
|         percent = (int)(((double)m_passed_ms / (double)m_total_ms) * 100); | ||||
|     } | ||||
| 
 | ||||
|     if(percent != m_percent) { | ||||
|         m_percent = percent; | ||||
|         m_owner->update(m_rc.left()+m_rc_progress.left(), m_rc.top()+m_rc_progress.top(), m_rc_progress.width(), m_rc_progress.height()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Bar::onMouseMove(int x, int y) { | ||||
|     // 映射鼠标坐标点到本浮动窗内部的相对位置
 | ||||
|     QPoint pt(x-m_rc.left(), y-m_rc.top()); | ||||
| 
 | ||||
|     bool play_hover = m_rc_btn_play.contains(pt); | ||||
|     if(play_hover != m_play_hover) { | ||||
|         m_play_hover = play_hover; | ||||
|         m_owner->update(m_rc.left()+m_rc_btn_play.left(), m_rc.top()+m_rc_btn_play.top(), m_rc_btn_play.width(), m_rc_btn_play.height()); | ||||
|     } | ||||
|     if(play_hover) | ||||
|         return; | ||||
| 
 | ||||
|     int speed_hover = speed_count; | ||||
|     for(int i = 0; i < speed_count; ++i) { | ||||
|         if(m_rc_btn_speed[i].contains(pt)) { | ||||
|             speed_hover = i; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if(m_speed_hover != speed_hover) { | ||||
|         if(m_speed_hover != speed_count) { | ||||
|             m_owner->update(m_rc.left()+m_rc_btn_speed[m_speed_hover].left(), m_rc.top()+m_rc_btn_speed[m_speed_hover].top(), m_rc_btn_speed[m_speed_hover].width(), m_rc_btn_speed[m_speed_hover].height()); | ||||
|         } | ||||
|         m_speed_hover = speed_hover; | ||||
|         if(m_speed_hover != speed_count) { | ||||
|             m_owner->update(m_rc.left()+m_rc_btn_speed[m_speed_hover].left(), m_rc.top()+m_rc_btn_speed[m_speed_hover].top(), m_rc_btn_speed[m_speed_hover].width(), m_rc_btn_speed[m_speed_hover].height()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // TODO: more hover detect.
 | ||||
| } | ||||
| 
 | ||||
| void Bar::draw(QPainter& painter, const QRect& rc_draw){ | ||||
|     if(!m_width) | ||||
|         return; | ||||
|     if(!rc_draw.intersects(m_rc)) | ||||
|         return; | ||||
| 
 | ||||
|     // 绘制背景
 | ||||
|     { | ||||
|         QRect rc(m_rc); | ||||
|         //rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top());
 | ||||
| 
 | ||||
|         int from_x = max(rc_draw.left(), m_rc.left()) - m_rc.left(); | ||||
|         int from_y = max(rc_draw.top(), m_rc.top()) - m_rc.top(); | ||||
|         int w = min(m_rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|         int h = min(m_rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|         int to_x = m_rc.left() + from_x; | ||||
|         int to_y = m_rc.top() + from_y; | ||||
|         painter.drawPixmap(to_x, to_y, m_img_bg, from_x, from_y, w, h); | ||||
|     } | ||||
| 
 | ||||
|     // 绘制播放按钮
 | ||||
|     { | ||||
|         QRect rc(m_rc_btn_play); | ||||
|         rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top()); | ||||
|         if(rc_draw.intersects(rc)) { | ||||
|             int from_x = max(rc_draw.left(), rc.left()) - rc.left(); | ||||
|             int from_y = max(rc_draw.top(), rc.top()) - rc.top(); | ||||
|             int w = min(rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|             int h = min(rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|             int to_x = rc.left() + from_x; | ||||
|             int to_y = rc.top() + from_y; | ||||
|             if(m_playing){ | ||||
|                 if(m_play_hover) | ||||
|                     painter.drawPixmap(to_x, to_y, m_img_btn_play[play_running][widget_hover], from_x, from_y, w, h); | ||||
|                 else | ||||
|                     painter.drawPixmap(to_x, to_y, m_img_btn_play[play_running][widget_normal], from_x, from_y, w, h); | ||||
|             } else { | ||||
|                 if(m_play_hover) | ||||
|                     painter.drawPixmap(to_x, to_y, m_img_btn_play[play_paused][widget_hover], from_x, from_y, w, h); | ||||
|                 else | ||||
|                     painter.drawPixmap(to_x, to_y, m_img_btn_play[play_paused][widget_normal], from_x, from_y, w, h); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 绘制已播放时间
 | ||||
|     { | ||||
|         QRect rc(m_rc_time_passed); | ||||
|         rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top()); | ||||
|         if(rc_draw.intersects(rc)) { | ||||
|             if(m_str_passed_time != m_str_passed_time_last_draw) { | ||||
|                 m_img_time_passed = QPixmap(m_rc_time_passed.width(), m_rc_time_passed.height()); | ||||
|                 m_img_time_passed.fill(Qt::transparent); | ||||
|                 QPainter pp(&m_img_time_passed); | ||||
|                 pp.setPen(TEXT_COLOR); | ||||
|                 QFont font = pp.font(); | ||||
|                 font.setFamily("consolas"); | ||||
|                 font.setBold(true); | ||||
|                 font.setPixelSize(TIME_STR_PIXEL_SIZE); | ||||
|                 pp.setFont(font); | ||||
|                 pp.drawText(QRect(0,0,m_rc_time_passed.width(), m_rc_time_passed.height()), Qt::AlignRight, m_str_passed_time); | ||||
| 
 | ||||
|                 m_str_passed_time_last_draw = m_str_passed_time; | ||||
|             } | ||||
| 
 | ||||
|             int from_x = max(rc_draw.left(), rc.left()) - rc.left(); | ||||
|             int from_y = max(rc_draw.top(), rc.top()) - rc.top(); | ||||
|             int w = min(rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|             int h = min(rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|             int to_x = rc.left() + from_x; | ||||
|             int to_y = rc.top() + from_y; | ||||
|             painter.drawPixmap(to_x, to_y, m_img_time_passed, from_x, from_y, w, h); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 绘制总时间
 | ||||
|     { | ||||
|         QRect rc(m_rc_time_total); | ||||
|         rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top()); | ||||
|         if(rc_draw.intersects(rc)) { | ||||
|             int from_x = max(rc_draw.left(), rc.left()) - rc.left(); | ||||
|             int from_y = max(rc_draw.top(), rc.top()) - rc.top(); | ||||
|             int w = min(rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|             int h = min(rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|             int to_x = rc.left() + from_x; | ||||
|             int to_y = rc.top() + from_y; | ||||
|             painter.drawPixmap(to_x, to_y, m_img_time_total, from_x, from_y, w, h); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 绘制进度条
 | ||||
|     { | ||||
|         QRect rc(m_rc_progress); | ||||
|         rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top()); | ||||
| 
 | ||||
|         if(rc_draw.intersects(rc)) { | ||||
|             if(m_percent_last_draw != m_percent) { | ||||
|                 m_img_progress = QPixmap(m_rc_progress.width(), m_rc_progress.height()); | ||||
|                 m_img_progress.fill(Qt::transparent); | ||||
|                 QPainter pp(&m_img_progress); | ||||
| 
 | ||||
|                 // 进度条
 | ||||
|                 int top = (rc.height() - m_res[res_pbh_left].height())/2; | ||||
|                 int passed_width = rc.width() * m_percent / 100;    // 已经播放的进度条宽度
 | ||||
|                 int remain_width = rc.width() - passed_width;       // 剩下未播放的进度条宽度
 | ||||
| 
 | ||||
|                 if(passed_width >= m_res[res_pbh_left].width()) | ||||
|                     pp.drawPixmap(0, top , m_res[res_pbh_left].width(), m_res[res_pbh_left].height(), m_res[res_pbh_left]); | ||||
|                 if(passed_width > 0) { | ||||
|                     //pp.drawPixmap(m_res[res_pbh_left].width(), top, passed_width - m_res[res_pbh_left].width(), m_res[res_pbh_mid].height(), m_res[res_pbh_mid]);
 | ||||
|                     if(remain_width > m_res[res_pb_right].width()) | ||||
|                         pp.drawPixmap(m_res[res_pbh_left].width(), top, passed_width - m_res[res_pbh_left].width(), m_res[res_pbh_mid].height(), m_res[res_pbh_mid]); | ||||
|                     else | ||||
|                         pp.drawPixmap(m_res[res_pbh_left].width(), top, passed_width - m_res[res_pbh_left].width() - m_res[res_pb_right].width(), m_res[res_pbh_mid].height(), m_res[res_pbh_mid]); | ||||
|                 } | ||||
|                 if(remain_width > 0) | ||||
|                     pp.drawPixmap(passed_width, top,  remain_width - m_res[res_pb_right].width(), m_res[res_pb_mid].height(), m_res[res_pb_mid]); | ||||
|                 if(remain_width >= m_res[res_pb_right].width()) | ||||
|                     pp.drawPixmap(rc.width() - m_res[res_pb_right].width(), top , m_res[res_pb_right].width(), m_res[res_pb_right].height(), m_res[res_pb_right]); | ||||
| 
 | ||||
|                 // 进度位置指示
 | ||||
|                 int left = passed_width - m_img_progress_pointer->width() / 2; | ||||
|                 if(left < 0) | ||||
|                     left = 0; | ||||
|                 if(left + m_img_progress_pointer->width() > rc.width()) | ||||
|                     left = rc.width() - m_img_progress_pointer->width(); | ||||
|                 top = (rc.height() - m_img_progress_pointer[widget_normal].height())/2; | ||||
|                 pp.drawPixmap(left, top , m_img_progress_pointer[widget_normal].width(), m_img_progress_pointer[widget_normal].height(), m_img_progress_pointer[widget_normal]); | ||||
| 
 | ||||
|                 m_percent_last_draw = m_percent; | ||||
|             } | ||||
| 
 | ||||
|             int from_x = max(rc_draw.left(), rc.left()) - rc.left(); | ||||
|             int from_y = max(rc_draw.top(), rc.top()) - rc.top(); | ||||
|             int w = min(rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|             int h = min(rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|             int to_x = rc.left() + from_x; | ||||
|             int to_y = rc.top() + from_y; | ||||
|             painter.drawPixmap(to_x, to_y, m_img_progress, from_x, from_y, w, h); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 绘制速度按钮
 | ||||
|     { | ||||
|         for(int i = 0; i < speed_count; i++) { | ||||
|             QRect rc(m_rc_btn_speed[i]); | ||||
|             rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top()); | ||||
|             if(rc_draw.intersects(rc)) { | ||||
|                 int from_x = max(rc_draw.left(), rc.left()) - rc.left(); | ||||
|                 int from_y = max(rc_draw.top(), rc.top()) - rc.top(); | ||||
|                 int w = min(rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|                 int h = min(rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|                 int to_x = rc.left() + from_x; | ||||
|                 int to_y = rc.top() + from_y; | ||||
|                 if(m_speed_selected == i || m_speed_hover == i) | ||||
|                     painter.drawPixmap(to_x, to_y, m_img_btn_speed[i][widget_hover], from_x, from_y, w, h); | ||||
|                 else | ||||
|                     painter.drawPixmap(to_x, to_y, m_img_btn_speed[i][widget_normal], from_x, from_y, w, h); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 绘制跳过选项
 | ||||
|     { | ||||
|         QRect rc(m_rc_skip); | ||||
|         rc.moveTo(m_rc.left()+rc.left(), m_rc.top() + rc.top()); | ||||
|         if(rc_draw.intersects(rc)) { | ||||
|             int from_x = max(rc_draw.left(), rc.left()) - rc.left(); | ||||
|             int from_y = max(rc_draw.top(), rc.top()) - rc.top(); | ||||
|             int w = min(rc.right(), rc_draw.right()) - rc.left() - from_x + 1; | ||||
|             int h = min(rc.bottom(), rc_draw.bottom()) - rc.top() - from_y + 1; | ||||
|             int to_x = rc.left() + from_x; | ||||
|             int to_y = rc.top() + from_y; | ||||
|             //qDebug("skip (%d,%d), (%d,%d)/(%d,%d)", to_x, to_y, from_x, from_y, w, h);
 | ||||
|             if(m_skip_selected) | ||||
|                 painter.drawPixmap(to_x, to_y, m_img_skip[widget_hover], from_x, from_y, w, h); | ||||
|             else | ||||
|                 painter.drawPixmap(to_x, to_y, m_img_skip[widget_normal], from_x, from_y, w, h); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,49 +5,128 @@ | |||
| #include <QPixmap> | ||||
| #include <QWidget> | ||||
| 
 | ||||
| typedef enum { | ||||
|     res_bg_left = 0,    // 背景左侧
 | ||||
|     res_bg_mid,         // 背景中间,拉伸填充
 | ||||
|     res_bg_right,       // 背景右侧
 | ||||
|     res_bs_left,        // 速度按钮(未选中)左侧
 | ||||
|     res_bs_mid,         // 速度按钮(未选中)中间,拉伸填充
 | ||||
|     res_bs_right,       // 速度按钮(未选中)右侧
 | ||||
|     res_bsh_left,       // 速度按钮(选中)左侧
 | ||||
|     res_bsh_mid,        // 速度按钮(选中)中间,拉伸填充
 | ||||
|     res_bsh_right,      // 速度按钮(选中)右侧
 | ||||
|     res_pbh_left,       // 进度条(已经过)左侧
 | ||||
|     res_pbh_mid,        // 进度条(已经过)中间,拉伸填充
 | ||||
|     res_pb_mid,         // 进度条(未到达)中间,拉伸填充
 | ||||
|     res_pb_right,       // 进度条(未到达)右侧
 | ||||
| //    res_pp,             // 进度条上的指示点,未选中
 | ||||
| //    res_pph,            // 进度条上的指示点,选中高亮
 | ||||
|     res_cb,             // 复选框,未选中
 | ||||
|     res_cbh,            // 复选框,已勾选
 | ||||
| //    res_play,
 | ||||
| //    res_play_hover,
 | ||||
| //    res_pause,
 | ||||
| //    res_pause_hover,
 | ||||
| 
 | ||||
|     res__max | ||||
| }RES_ID; | ||||
| 
 | ||||
| typedef enum { | ||||
|     widget_normal = 0, | ||||
|     widget_hover, | ||||
|     widget__max | ||||
| }WIDGET_STAT; | ||||
| 
 | ||||
| typedef enum { | ||||
|     play_running = 0, | ||||
|     play_paused, | ||||
|     play__max | ||||
| }PLAY_STAT; | ||||
| 
 | ||||
| //typedef enum {
 | ||||
| //    speed_1x = 0,
 | ||||
| //    speed_2x,
 | ||||
| //    speed_4x,
 | ||||
| //    speed_8x,
 | ||||
| //    speed_16x,
 | ||||
| //    speed__max,
 | ||||
| //}SPEED;
 | ||||
| 
 | ||||
| #define speed_1x        0 | ||||
| #define speed_2x        1 | ||||
| #define speed_4x        2 | ||||
| #define speed_8x        3 | ||||
| #define speed_16x       4 | ||||
| #define speed_count     5 | ||||
| 
 | ||||
| class Bar { | ||||
| public: | ||||
|     Bar(); | ||||
|     ~Bar(); | ||||
| 
 | ||||
|     bool init(QWidget* owner, int width); | ||||
|     bool init(QWidget* owner); | ||||
|     void start(uint32_t total_ms, int width); | ||||
|     void end(); | ||||
|     void draw(QPainter& painter, const QRect& rc); | ||||
|     void update_passed_time(uint32_t ms); | ||||
| 
 | ||||
|     QRect rc(){return m_rc;} | ||||
| 
 | ||||
|     void onMouseMove(int x, int y); | ||||
| 
 | ||||
| private: | ||||
|     void _init_imgages(); | ||||
|     void _ms_to_str(uint32_t ms, QString& str); | ||||
| 
 | ||||
| private: | ||||
|     QWidget* m_owner; | ||||
| 
 | ||||
|     uint32_t m_total_ms;    // 录像的总时长
 | ||||
|     uint32_t m_passed_ms;   // 已经播放了的时长
 | ||||
|     int m_percent;       // 已经播放了的百分比(0~100)
 | ||||
|     int m_percent_last_draw; | ||||
|     QString m_str_total_time; | ||||
|     QString m_str_passed_time; | ||||
|     QString m_str_passed_time_last_draw; | ||||
| 
 | ||||
|     bool m_img_ready; | ||||
| 
 | ||||
|     //  从资源中加载的原始图像
 | ||||
|     QPixmap m_res[res__max]; | ||||
|     QPixmap m_img_progress_pointer[widget__max]; | ||||
| 
 | ||||
|     int m_width; | ||||
|     int m_height; | ||||
|     // 此浮动窗相对于父窗口的坐标和大小
 | ||||
|     QRect m_rc; | ||||
| 
 | ||||
|     // 尺寸和定位(此浮动窗内部的相对坐标)
 | ||||
|     QRect m_rc_btn_play; | ||||
|     QRect m_rc_btn_speed[speed_count]; | ||||
|     QRect m_rc_time_passed; | ||||
|     QRect m_rc_time_total; | ||||
|     QRect m_rc_progress; | ||||
|     QRect m_rc_skip; | ||||
| 
 | ||||
|     QPixmap m_bg; | ||||
|     // 画布,最终输出的图像
 | ||||
|     //QPixmap m_canvas;
 | ||||
| 
 | ||||
|     QPixmap m_bg_left; | ||||
|     QPixmap m_bg_mid; | ||||
|     QPixmap m_bg_right; | ||||
|     // 合成的图像
 | ||||
|     QPixmap m_img_bg; | ||||
|     QPixmap m_img_btn_play[play__max][widget__max]; | ||||
|     QPixmap m_img_btn_speed[speed_count][widget__max]; | ||||
|     QPixmap m_img_progress; | ||||
|     QPixmap m_img_skip[widget__max]; | ||||
|     QPixmap m_img_time_passed; | ||||
|     QPixmap m_img_time_total; | ||||
| 
 | ||||
|     QPixmap m_btn_left; | ||||
|     QPixmap m_btn_mid; | ||||
|     QPixmap m_btn_right; | ||||
| 
 | ||||
|     QPixmap m_btnsel_left; | ||||
|     QPixmap m_btnsel_mid; | ||||
|     QPixmap m_btnsel_right; | ||||
| 
 | ||||
|     QPixmap m_prgbarh_left; | ||||
|     QPixmap m_prgbarh_mid; | ||||
| 
 | ||||
|     QPixmap m_prgbar_left; | ||||
|     QPixmap m_prgbar_mid; | ||||
|     QPixmap m_prgbar_right; | ||||
| 
 | ||||
|     QPixmap m_prgpt; | ||||
|     QPixmap m_prgpt_hover; | ||||
| 
 | ||||
|     QPixmap m_select; | ||||
|     QPixmap m_selected; | ||||
| 
 | ||||
|     QPixmap m_play; | ||||
|     QPixmap m_play_hover; | ||||
|     // 各种状态
 | ||||
|     bool m_play_hover; | ||||
|     bool m_playing; // 0=play, 2=pause
 | ||||
|     int m_speed_selected; | ||||
|     int m_speed_hover;    // speed__max=no-hover
 | ||||
|     bool m_skip_selected; | ||||
|     //bool m_skip_hover;
 | ||||
| }; | ||||
| 
 | ||||
| #endif // BAR_H
 | ||||
|  |  | |||
|  | @ -41,10 +41,6 @@ bool rdpimg2QImage(QImage& out, int w, int h, int bitsPerPixel, bool isCompresse | |||
|                     uint8 r = ((a & 0xf800) >> 11) * 255 / 31; | ||||
|                     uint8 g = ((a & 0x07e0) >> 5) * 255 / 63; | ||||
|                     uint8 b = (a & 0x001f) * 255 / 31; | ||||
| //                    r = r * 255 / 31;
 | ||||
| //                    g = g * 255 / 63;
 | ||||
| //                    b = b * 255 / 31;
 | ||||
| 
 | ||||
|                     out.setPixelColor(x, y, QColor(r,g,b)); | ||||
|                 } | ||||
|             } | ||||
|  | @ -72,15 +68,17 @@ MainWindow::MainWindow(QWidget *parent) : | |||
|     ui(new Ui::MainWindow) | ||||
| { | ||||
|     m_shown = false; | ||||
|     m_show_bg = true; | ||||
|     m_bg = QImage(":/tp-player/res/bg"); | ||||
|     m_pt_normal = QImage(":/tp-player/res/cursor.png"); | ||||
|     m_show_default = true; | ||||
|     m_bar_shown = false; | ||||
|     memset(&m_pt, 0, sizeof(TS_RECORD_RDP_POINTER)); | ||||
| 
 | ||||
|     qDebug() << m_pt_normal.width() << "x" << m_pt_normal.height(); | ||||
| 
 | ||||
|     ui->setupUi(this); | ||||
| 
 | ||||
|     ui->centralWidget->setMouseTracking(true); | ||||
|     setMouseTracking(true); | ||||
| 
 | ||||
|     //qRegisterMetaType<update_data*>("update_data");
 | ||||
| 
 | ||||
|     // frame-less window.
 | ||||
|  | @ -91,15 +89,13 @@ MainWindow::MainWindow(QWidget *parent) : | |||
| //    setWindowFlags(Qt::FramelessWindowHint | Qt::MSWindowsFixedSizeDialogHint | windowFlags());
 | ||||
| //#endif //__APPLE__
 | ||||
| 
 | ||||
|     //m_canvas = QPixmap(m_bg.width(), m_bg.height());
 | ||||
|     m_canvas.load(":/tp-player/res/bg"); | ||||
| 
 | ||||
|     resize(m_bg.width(), m_bg.height()); | ||||
|     m_pt_normal.load(":/tp-player/res/cursor.png"); | ||||
|     m_default_bg.load(":/tp-player/res/bg.png"); | ||||
| 
 | ||||
|     setWindowFlags(windowFlags()&~Qt::WindowMaximizeButtonHint);    // 禁止最大化按钮
 | ||||
|     setFixedSize(m_bg.width(), m_bg.height());                     // 禁止拖动窗口大小
 | ||||
|     setFixedSize(m_default_bg.width(), m_default_bg.height());                     // 禁止拖动窗口大小
 | ||||
| 
 | ||||
|     if(!m_bar.init(this, 480)) | ||||
|     if(!m_bar.init(this)) | ||||
|         return; | ||||
| 
 | ||||
|     connect(&m_thr_play, SIGNAL(signal_update_data(update_data*)), this, SLOT(on_update_data(update_data*))); | ||||
|  | @ -112,49 +108,43 @@ MainWindow::~MainWindow() | |||
|     delete ui; | ||||
| } | ||||
| 
 | ||||
| void MainWindow::paintEvent(QPaintEvent *pe) | ||||
| void MainWindow::paintEvent(QPaintEvent *e) | ||||
| { | ||||
|     QPainter painter(this); | ||||
| 
 | ||||
|     painter.drawPixmap(pe->rect(), m_canvas, pe->rect()); | ||||
|     if(m_show_default) { | ||||
|         painter.drawPixmap(e->rect(), m_default_bg, e->rect()); | ||||
|     } | ||||
|     else { | ||||
|         painter.drawPixmap(e->rect(), m_canvas, e->rect()); | ||||
| 
 | ||||
|     if(!m_pt_history.empty()) { | ||||
|         for(int i = 0; i < m_pt_history.count(); i++) { | ||||
|             //qDebug("pt clean %d,%d", m_pt_history[i].x, m_pt_history[i].y);
 | ||||
|             QRect rcpt(m_pt_normal.rect()); | ||||
|             rcpt.moveTo(m_pt_history[i].x - m_pt_normal.width()/2, m_pt_history[i].y-m_pt_normal.height()/2); | ||||
|             //painter.drawPixmap(rcpt, m_canvas, rcpt);
 | ||||
|             qDebug("pt ---- (%d,%d), (%d,%d)", rcpt.x(), rcpt.y(), rcpt.width(), rcpt.height()); | ||||
|             painter.fillRect(rcpt, QColor(255, 255, 0, 128)); | ||||
|         QRect rcpt(m_pt_normal.rect()); | ||||
|         rcpt.moveTo(m_pt.x - m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2); | ||||
|         if(e->rect().intersects(rcpt)) { | ||||
|             painter.drawPixmap(m_pt.x-m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2, m_pt_normal); | ||||
|         } | ||||
|         m_pt_history.clear(); | ||||
| 
 | ||||
|         // 绘制浮动控制窗
 | ||||
|         if(m_bar_shown) | ||||
|             m_bar.draw(painter, e->rect()); | ||||
|     } | ||||
| 
 | ||||
|     QRect rcpt(m_pt_normal.rect()); | ||||
|     rcpt.moveTo(m_pt.x - m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2); | ||||
|     if(pe->rect().intersects(rcpt)) { | ||||
|         qDebug("pt draw (%d,%d), (%d,%d)", m_pt.x-m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2, m_pt_normal.width(), m_pt_normal.height()); | ||||
|         painter.drawImage(m_pt.x-m_pt_normal.width()/2, m_pt.y-m_pt_normal.height()/2, m_pt_normal); | ||||
|     if(!m_shown) { | ||||
|         m_shown = true; | ||||
|         m_thr_play.start(); | ||||
|     } | ||||
| 
 | ||||
|     m_bar.draw(painter, pe->rect()); | ||||
| 
 | ||||
| //    if(!m_shown) {
 | ||||
| //        m_shown = true;
 | ||||
| //        m_thr_play.start();
 | ||||
| //    }
 | ||||
| } | ||||
| 
 | ||||
| void MainWindow::on_update_data(update_data* dat) { | ||||
|     if(!dat) | ||||
|         return; | ||||
| 
 | ||||
|     UpdateDataHelper data_helper(dat); | ||||
| 
 | ||||
|     if(dat->data_type() == TYPE_DATA) { | ||||
|         m_show_bg = false; | ||||
| 
 | ||||
|         if(dat->data_len() <= sizeof(TS_RECORD_PKG)) { | ||||
|             qDebug() << "invalid record package(1)."; | ||||
|             delete dat; | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|  | @ -163,25 +153,21 @@ void MainWindow::on_update_data(update_data* dat) { | |||
|         if(pkg->type == TS_RECORD_TYPE_RDP_POINTER) { | ||||
|             if(dat->data_len() != sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_POINTER)) { | ||||
|                 qDebug() << "invalid record package(2)."; | ||||
|                 delete dat; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             // 将现有虚拟鼠标信息放入历史队列,这样下一次绘制界面时就会将其清除掉
 | ||||
|             m_pt_history.push_back(m_pt); | ||||
|             TS_RECORD_RDP_POINTER pt; | ||||
|             memcpy(&pt, &m_pt, sizeof(TS_RECORD_RDP_POINTER)); | ||||
| 
 | ||||
|             // 更新虚拟鼠标信息,这样下一次绘制界面时就会在新的位置绘制出虚拟鼠标
 | ||||
|             memcpy(&m_pt, dat->data_buf() + sizeof(TS_RECORD_PKG), sizeof(TS_RECORD_RDP_POINTER)); | ||||
|             //qDebug("pt new position %d,%d", m_pt.x, m_pt.y);
 | ||||
| 
 | ||||
|             //setUpdatesEnabled(false);
 | ||||
|             update(m_pt.x - m_pt_normal.width()/2, m_pt.y - m_pt_normal.width()/2, m_pt_normal.width(), m_pt_normal.height()); | ||||
|             //setUpdatesEnabled(true);
 | ||||
| 
 | ||||
|             update(pt.x - m_pt_normal.width()/2, pt.y - m_pt_normal.width()/2, m_pt_normal.width(), m_pt_normal.height()); | ||||
|         } | ||||
|         else if(pkg->type == TS_RECORD_TYPE_RDP_IMAGE) { | ||||
|             if(dat->data_len() <= sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_IMAGE_INFO)) { | ||||
|                 qDebug() << "invalid record package(3)."; | ||||
|                 delete dat; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|  | @ -189,53 +175,57 @@ void MainWindow::on_update_data(update_data* dat) { | |||
|             uint8_t* img_dat = dat->data_buf() + sizeof(TS_RECORD_PKG) + sizeof(TS_RECORD_RDP_IMAGE_INFO); | ||||
|             uint32_t img_len = dat->data_len() - sizeof(TS_RECORD_PKG) - sizeof(TS_RECORD_RDP_IMAGE_INFO); | ||||
| 
 | ||||
|             rdpimg2QImage(m_img_update, info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len); | ||||
|             QImage img_update; | ||||
|             rdpimg2QImage(img_update, info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len); | ||||
| 
 | ||||
|             m_img_update_x = info->destLeft; | ||||
|             m_img_update_y = info->destTop; | ||||
|             m_img_update_w = info->destRight - info->destLeft + 1; | ||||
|             m_img_update_h = info->destBottom - info->destTop + 1; | ||||
|             int x = info->destLeft; | ||||
|             int y = info->destTop; | ||||
|             int w = info->destRight - info->destLeft + 1; | ||||
|             int h = info->destBottom - info->destTop + 1; | ||||
| 
 | ||||
|             setUpdatesEnabled(false); | ||||
|             QPainter pp(&m_canvas); | ||||
|             pp.drawImage(m_img_update_x, m_img_update_y, m_img_update, 0, 0, m_img_update_w, m_img_update_h, Qt::AutoColor); | ||||
|             pp.drawImage(x, y, img_update, 0, 0, w, h, Qt::AutoColor); | ||||
| 
 | ||||
|             update(m_img_update_x, m_img_update_y, m_img_update_w, m_img_update_h); | ||||
|             setUpdatesEnabled(true); | ||||
|             update(x, y, w, h); | ||||
|         } | ||||
| 
 | ||||
|         delete dat; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if(dat->data_type() == TYPE_TIMER) { | ||||
|         m_bar.update_passed_time(dat->passed_ms()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if(dat->data_type() == TYPE_HEADER_INFO) { | ||||
|         if(dat->data_len() != sizeof(TS_RECORD_HEADER)) { | ||||
|             qDebug() << "invalid record header."; | ||||
|             delete dat; | ||||
|             return; | ||||
|         } | ||||
|         memcpy(&m_rec_hdr, dat->data_buf(), sizeof(TS_RECORD_HEADER)); | ||||
|         delete dat; | ||||
| 
 | ||||
|         qDebug() << "resize (" << m_rec_hdr.basic.width << "," << m_rec_hdr.basic.height << ")"; | ||||
|         if(m_rec_hdr.basic.width > 0 && m_rec_hdr.basic.height > 0) { | ||||
| 
 | ||||
|             m_canvas = QPixmap(m_rec_hdr.basic.width, m_rec_hdr.basic.height); | ||||
|             m_canvas.fill(QColor(38, 73, 111)); | ||||
| 
 | ||||
|             //m_win_board_w = frameGeometry().width() - geometry().width();
 | ||||
|             //m_win_board_h = frameGeometry().height() - geometry().height();
 | ||||
| 
 | ||||
|             m_win_board_w = frameGeometry().width() - geometry().width(); | ||||
|             m_win_board_h = frameGeometry().height() - geometry().height(); | ||||
|             QDesktopWidget *desktop = QApplication::desktop(); // =qApp->desktop();也可以
 | ||||
|             qDebug("desktop w:%d,h:%d, this w:%d,h:%d", desktop->width(), desktop->height(), width(), height()); | ||||
|             //move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
 | ||||
|             move(10, (desktop->height() - m_rec_hdr.basic.height)/2); | ||||
| 
 | ||||
|             //setFixedSize(m_rec_hdr.basic.width + m_win_board_w, m_rec_hdr.basic.height + m_win_board_h);
 | ||||
|             //resize(m_rec_hdr.basic.width + m_win_board_w, m_rec_hdr.basic.height + m_win_board_h);
 | ||||
|             //resize(m_rec_hdr.basic.width, m_rec_hdr.basic.height);
 | ||||
|             setFixedSize(m_rec_hdr.basic.width, m_rec_hdr.basic.height); | ||||
|             resize(m_rec_hdr.basic.width, m_rec_hdr.basic.height); | ||||
| 
 | ||||
|             QDesktopWidget *desktop = QApplication::desktop(); // =qApp->desktop();也可以
 | ||||
|             qDebug("desktop width: %d", desktop->width()); | ||||
|             //move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
 | ||||
|             move(10, (desktop->height() - this->height())/2); | ||||
|             m_show_default = false; | ||||
|             repaint(); | ||||
| 
 | ||||
|             m_bar.start(m_rec_hdr.info.time_ms, 640); | ||||
|         } | ||||
| 
 | ||||
|         QString title; | ||||
|  | @ -250,5 +240,30 @@ void MainWindow::on_update_data(update_data* dat) { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     delete dat; | ||||
|     if(dat->data_type() == TYPE_END) { | ||||
|         m_bar.end(); | ||||
|         return; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void MainWindow::mouseMoveEvent(QMouseEvent *e) { | ||||
|     if(!m_show_default) { | ||||
|         QRect rc = m_bar.rc(); | ||||
|         if(e->y() > rc.top() - 20 && e->y() < rc.bottom() + 20) { | ||||
|             if(!m_bar_shown) { | ||||
|                 m_bar_shown = true; | ||||
|                 update(rc); | ||||
|             } | ||||
| 
 | ||||
|             if(rc.contains(QPoint(e->x(), e->y()))) | ||||
|                 m_bar.onMouseMove(e->x(), e->y()); | ||||
|         } | ||||
|         else { | ||||
|             if(m_bar_shown) { | ||||
|                 m_bar_shown = false; | ||||
|                 update(rc); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ | |||
| #define MAINWINDOW_H | ||||
| 
 | ||||
| #include <QMainWindow> | ||||
| #include <QVector> | ||||
| #include "bar.h" | ||||
| #include "thr_play.h" | ||||
| #include "update_data.h" | ||||
|  | @ -21,16 +20,19 @@ public: | |||
|     ~MainWindow(); | ||||
| 
 | ||||
| private: | ||||
|     void paintEvent(QPaintEvent *); | ||||
| 
 | ||||
|     void paintEvent(QPaintEvent *e); | ||||
|     void mouseMoveEvent(QMouseEvent *e); | ||||
| 
 | ||||
| private slots: | ||||
|     void on_update_data(update_data*); | ||||
| 
 | ||||
| private: | ||||
|     Ui::MainWindow *ui; | ||||
|     QImage m_bg; | ||||
|     //QImage m_bg;
 | ||||
|     bool m_shown; | ||||
|     bool m_show_default; | ||||
|     bool m_bar_shown; | ||||
|     QPixmap m_default_bg; | ||||
| 
 | ||||
|     ThreadPlay m_thr_play; | ||||
| 
 | ||||
|  | @ -38,21 +40,10 @@ private: | |||
| 
 | ||||
|     Bar m_bar; | ||||
| 
 | ||||
|     bool m_show_bg; | ||||
|     TS_RECORD_HEADER m_rec_hdr; | ||||
| 
 | ||||
|     QImage m_pt_normal; | ||||
|     QPixmap m_pt_normal; | ||||
|     TS_RECORD_RDP_POINTER m_pt; | ||||
|     QVector<TS_RECORD_RDP_POINTER> m_pt_history; | ||||
| 
 | ||||
| 
 | ||||
|     QImage m_img_update; | ||||
|     int m_win_board_w; | ||||
|     int m_win_board_h; | ||||
|     int m_img_update_x; | ||||
|     int m_img_update_y; | ||||
|     int m_img_update_w; | ||||
|     int m_img_update_h; | ||||
| }; | ||||
| 
 | ||||
| #endif // MAINWINDOW_H
 | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ | |||
| 
 | ||||
| #define TYPE_HEADER_INFO    0 | ||||
| #define TYPE_DATA           1 | ||||
| #define TYPE_TIMER          2 | ||||
| #define TYPE_END            3 | ||||
| 
 | ||||
| 
 | ||||
| #define TS_RECORD_TYPE_RDP_POINTER          0x12    // 鼠标坐标位置改变,用于绘制虚拟鼠标
 | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.2 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.2 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 1.0 KiB | 
|  | @ -18,6 +18,9 @@ void ThreadPlay::stop() { | |||
| } | ||||
| 
 | ||||
| void ThreadPlay::run() { | ||||
| 
 | ||||
|     sleep(1); | ||||
| 
 | ||||
|     qint64 read_len = 0; | ||||
|     uint32_t total_pkg = 0; | ||||
| 
 | ||||
|  | @ -59,6 +62,7 @@ void ThreadPlay::run() { | |||
|     } | ||||
| 
 | ||||
|     uint32_t time_pass = 0; | ||||
|     uint32_t time_last_pass = 0; | ||||
| 
 | ||||
|     qint64 time_begin = QDateTime::currentMSecsSinceEpoch(); | ||||
| 
 | ||||
|  | @ -87,6 +91,14 @@ void ThreadPlay::run() { | |||
|         } | ||||
| 
 | ||||
|         time_pass = (uint32_t)(QDateTime::currentMSecsSinceEpoch() - time_begin); | ||||
|         if(time_pass - time_last_pass > 1000) { | ||||
|             update_data* _passed_ms = new update_data; | ||||
|             _passed_ms->data_type(TYPE_TIMER); | ||||
|             _passed_ms->passed_ms(time_pass); | ||||
| //            qDebug("--- 1  %d", time_pass);
 | ||||
|             emit signal_update_data(_passed_ms); | ||||
|             time_last_pass = time_pass; | ||||
|         } | ||||
| 
 | ||||
|         if(time_pass >= pkg.time_ms) { | ||||
|             //time_pass = pkg.time_ms;
 | ||||
|  | @ -99,8 +111,8 @@ void ThreadPlay::run() { | |||
|         uint32_t wait_this_time = 0; | ||||
|         for(;;) { | ||||
|             wait_this_time = time_wait; | ||||
|             if(wait_this_time > 5) | ||||
|                 wait_this_time = 5; | ||||
|             if(wait_this_time > 10) | ||||
|                 wait_this_time = 10; | ||||
| 
 | ||||
|             if(m_need_stop) { | ||||
|                 qDebug() << "stop, user cancel (2)."; | ||||
|  | @ -109,8 +121,15 @@ void ThreadPlay::run() { | |||
| 
 | ||||
|             msleep(wait_this_time); | ||||
| 
 | ||||
|             //time_pass += wait_this_time;
 | ||||
|             //time_pass = pkg.time_ms;
 | ||||
|             uint32_t _time_pass = (uint32_t)(QDateTime::currentMSecsSinceEpoch() - time_begin); | ||||
|             if(_time_pass - time_last_pass > 1000) { | ||||
|                 update_data* _passed_ms = new update_data; | ||||
|                 _passed_ms->data_type(TYPE_TIMER); | ||||
|                 _passed_ms->passed_ms(_time_pass); | ||||
| //                qDebug("--- 2  %d", _time_pass);
 | ||||
|                 emit signal_update_data(_passed_ms); | ||||
|                 time_last_pass = _time_pass; | ||||
|             } | ||||
| 
 | ||||
|             time_wait -= wait_this_time; | ||||
|             if(time_wait == 0) { | ||||
|  | @ -118,8 +137,9 @@ void ThreadPlay::run() { | |||
|                 break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| //        emit signal_update_data(dat);
 | ||||
| //        msleep(15);
 | ||||
|     } | ||||
| 
 | ||||
|     update_data* _end = new update_data; | ||||
|     _end->data_type(TYPE_END); | ||||
|     emit signal_update_data(_end); | ||||
| } | ||||
|  |  | |||
|  | @ -13,7 +13,8 @@ | |||
|         <file>res/bar/btnsel-right.png</file> | ||||
|         <file>res/bar/play-hover.png</file> | ||||
|         <file>res/bar/play.png</file> | ||||
|         <file>res/bar/prgbar-left.png</file> | ||||
|         <file>res/bar/pause-hover.png</file> | ||||
|         <file>res/bar/pause.png</file> | ||||
|         <file>res/bar/prgbar-mid.png</file> | ||||
|         <file>res/bar/prgbar-right.png</file> | ||||
|         <file>res/bar/prgbarh-left.png</file> | ||||
|  |  | |||
|  | @ -19,6 +19,9 @@ public: | |||
|     uint8_t* data_buf() {return m_data_buf;} | ||||
|     uint32_t data_len() const {return m_data_len;} | ||||
| 
 | ||||
|     void passed_ms(uint32_t ms) {m_passed_ms = ms;} | ||||
|     uint32_t passed_ms() {return m_passed_ms;} | ||||
| 
 | ||||
| signals: | ||||
| 
 | ||||
| public slots: | ||||
|  | @ -28,6 +31,22 @@ private: | |||
|     int m_data_type; | ||||
|     uint8_t* m_data_buf; | ||||
|     uint32_t m_data_len; | ||||
|     uint32_t m_passed_ms; | ||||
| }; | ||||
| 
 | ||||
| class UpdateDataHelper { | ||||
| public: | ||||
|     UpdateDataHelper(update_data* data) { | ||||
|         m_data = data; | ||||
|     } | ||||
|     ~UpdateDataHelper() { | ||||
|         if(m_data) | ||||
|             delete m_data; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     update_data* m_data; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #endif // UPDATE_DATA_H
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Apex Liu
						Apex Liu