1 #include "stdafx.h" 2 #include "CUIDrawer.h" 3 #include "MusicPlayer2.h" 4 5 6 CUIDrawer::CUIDrawer(UIColors& colors) 7 : m_colors(colors) 8 { 9 } 10 11 12 CUIDrawer::~CUIDrawer() 13 { 14 } 15 16 void CUIDrawer::DrawLryicCommon(CRect rect, Alignment align) 17 { 18 SetDrawArea(rect); 19 20 if (!IsDrawMultiLine(rect.Height())) 21 DrawLyricTextSingleLine(rect, true, align); 22 else 23 DrawLyricTextMultiLine(rect, align); 24 } 25 26 int CUIDrawer::GetLyricTextHeight() const 27 { 28 //�����ı��߶� 29 if(!m_for_cortana_lyric) 30 m_pDC->SelectObject(&theApp.m_font_set.lyric.GetFont(theApp.m_ui_data.full_screen)); 31 else 32 m_pDC->SelectObject(&theApp.m_font_set.cortana.GetFont()); 33 return m_pDC->GetTextExtent(L"��").cy; //���ݵ�ǰ���������ü����ı��ĸ߶� 34 } 35 36 void CUIDrawer::Create(CDC * pDC, CWnd * pMainWnd) 37 { 38 CDrawCommon::Create(pDC, pMainWnd); 39 } 40 41 bool CUIDrawer::IsDrawMultiLine(int height) const 42 { 43 return height >= static_cast<int>(GetLyricTextHeight() * 3.5); 44 } 45 46 void CUIDrawer::SetForCortanaLyric(bool for_cortana_lyric) 47 { 48 m_for_cortana_lyric = for_cortana_lyric; 49 } 50 51 void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) 52 { 53 int line_space{}; 54 if (m_for_cortana_lyric) 55 { 56 line_space = theApp.DPI(4); 57 } 58 else 59 { 60 line_space = theApp.m_app_setting_data.lyric_line_space; 61 if (theApp.m_ui_data.full_screen) 62 line_space = static_cast<int>(line_space * CONSTVAL::FULL_SCREEN_ZOOM_FACTOR); 63 } 64 65 int lyric_height = GetLyricTextHeight() + line_space; //�ı��߶ȼ����м�� 66 int lyric_height2 = lyric_height * 2 + line_space; //��������ĸ�ʸ߶� 67 68 SetLyricFont(); 69 if (CPlayerUIHelper::IsMidiLyric()) 70 { 71 wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() }; 72 DrawWindowText(lyric_area, current_lyric.c_str(), m_colors.color_text, Alignment::CENTER, false, true); 73 } 74 else if (CPlayer::GetInstance().m_Lyrics.IsEmpty()) 75 { 76 DrawWindowText(lyric_area, CCommon::LoadText(IDS_NO_LYRIC_INFO), m_colors.color_text_2, Alignment::CENTER); 77 } 78 else 79 { 80 //CRect arect{ lyric_area }; //һ�и�ʵľ������� 81 //arect.bottom = arect.top + lyric_height; 82 //vector<CRect> rects(CPlayer::GetInstance().m_Lyrics.GetLyricCount() + 1, arect); 83 //Ϊÿһ���ʴ���һ�����Σ������������� 84 vector<CRect> rects; 85 int lyric_count = CPlayer::GetInstance().m_Lyrics.GetLyricCount() + 1; //��ȡ������������ڵ�һ�и����Ҫ��ʾ���⣬��������Ҫ+1�� 86 for (int i{}; i < lyric_count; i++) 87 { 88 CRect arect{ lyric_area }; 89 if (!CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.empty() && theApp.m_ui_data.show_translate) 90 arect.bottom = arect.top + lyric_height2; 91 else 92 arect.bottom = arect.top + lyric_height; 93 rects.push_back(arect); 94 } 95 int center_pos = (lyric_area.top + lyric_area.bottom) / 2; //������������y���� 96 Time time{ CPlayer::GetInstance().GetCurrentPosition() }; //��ǰ����ʱ�� 97 int lyric_index = CPlayer::GetInstance().m_Lyrics.GetLyricIndex(time) + 1; //��ǰ��ʵ���ţ���ʵĵ�һ��GetLyricIndex���ص���0��������ʾʱ��һ����Ҫ��ʾ���⣬��������Ҫ+1�� 98 int progress = CPlayer::GetInstance().m_Lyrics.GetLyricProgress(time); //��ǰ��ʽ��ȣ���ΧΪ0~1000�� 99 int y_progress; //��ǰ�����y���ϵĽ��� 100 if (!CPlayer::GetInstance().m_Lyrics.GetLyric(lyric_index).translate.empty() && theApp.m_ui_data.show_translate) 101 y_progress = progress * lyric_height2 / 1000; 102 else 103 y_progress = progress * lyric_height / 1000; 104 //int start_pos = center_pos - y_progress - (lyric_index + 1)*lyric_height; //��1���ʵ���ʼy���� 105 //�����1���ʵ���ʼy���� 106 //���ڵ�ǰ�����Ҫ��ʾ�ڸ�����������λ�ã���˴�����λ�ÿ�ʼ����ȥ��ǰ�����Y���ϵĽ��� 107 //�����μ�ȥ֮ǰÿһ���ʵĸ߶ȣ����õ��˵�һ���ʵ���ʼλ�� 108 int start_pos; 109 start_pos = center_pos - y_progress; 110 for (int i{ lyric_index - 1 }; i >= 0; i--) 111 { 112 if (theApp.m_ui_data.show_translate && !CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.empty()) 113 start_pos -= lyric_height2; 114 else 115 start_pos -= lyric_height; 116 } 117 118 //���λ���ÿһ���� 119 for (size_t i{}; i < rects.size(); i++) 120 { 121 //����ÿһ���ʵ�λ�� 122 if (i == 0) 123 rects[i].MoveToY(start_pos); 124 else 125 rects[i].MoveToY(rects[i - 1].bottom); 126 //���Ƹ���ı� 127 if (!(rects[i] & lyric_area).IsRectEmpty()) //ֻ�е�һ���ʵľ�������������ľ����н���ʱ���Ż��Ƹ�� 128 { 129 //���ø���ı��ͷ����ı��ľ������� 130 CRect rect_text{ rects[i] }; 131 CRect rect_translate; 132 if (!CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.empty() && theApp.m_ui_data.show_translate) 133 { 134 rect_text.MoveToY(rect_text.top + line_space); 135 rect_text.bottom = rect_text.top + GetLyricTextHeight(); 136 rect_translate = rect_text; 137 rect_translate.MoveToY(rect_text.bottom + line_space); 138 } 139 140 if (i == lyric_index && progress < 1000) //�������ڲ��ŵĸ�� 141 { 142 CLyrics::Lyric lyric = CPlayer::GetInstance().m_Lyrics.GetLyric(i); 143 //����ʵ���ı��ӷǸ��������仯������Ч�� 144 int last_time_span = time - lyric.time; //��ǰ���ŵĸ���ѳ�����ʱ�� 145 int fade_percent = last_time_span / 8; //������ɫ�����仯�İٷֱȣ�����Խ�������ʱ��Խ����10��Ϊ1�� 146 COLORREF text_color = CColorConvert::GetGradientColor(m_colors.color_text_2, m_colors.color_text, fade_percent); 147 //���Ƹ���ı� 148 SetLyricFont(); 149 if (theApp.m_lyric_setting_data.lyric_karaoke_disp) 150 DrawWindowText(rect_text, lyric.text.c_str(), m_colors.color_text, m_colors.color_text_2, progress, align, true); 151 else 152 DrawWindowText(rect_text, lyric.text.c_str(), text_color, text_color, progress, align, true); 153 //���Ʒ����ı� 154 if (!lyric.translate.empty() && theApp.m_ui_data.show_translate) 155 { 156 SetLyricFontTranslated(); 157 DrawWindowText(rect_translate, CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.c_str(), text_color, text_color, progress, align, true); 158 } 159 } 160 else //���Ʒ����ڲ��ŵĸ�� 161 { 162 SetLyricFont(); 163 COLORREF text_color; 164 if (i == lyric_index - 1) //������һ���ʣ�����ʵ����һ������ɫ�Ӹ��������仯���Ǹ���Ч���� 165 { 166 CLyrics::Lyric playing_lyric = CPlayer::GetInstance().m_Lyrics.GetLyric(lyric_index); 167 int last_time_span = time - playing_lyric.time; //��ǰ���ŵĸ���ѳ�����ʱ�� 168 int fade_percent = last_time_span / 20; //������ɫ�����仯�İٷֱȣ�������ʱ��Ϊ2000����ʱΪ100%������ɫ�����仯��ʱ��Ϊ2�� 169 text_color = CColorConvert::GetGradientColor(m_colors.color_text, m_colors.color_text_2, fade_percent); 170 } 171 else 172 { 173 text_color = m_colors.color_text_2; 174 } 175 //���Ƹ���ı� 176 DrawWindowText(rect_text, CPlayer::GetInstance().m_Lyrics.GetLyric(i).text.c_str(), text_color, align, true); 177 //���Ʒ����ı� 178 if (!CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.empty() && theApp.m_ui_data.show_translate) 179 { 180 SetLyricFontTranslated(); 181 DrawWindowText(rect_translate, CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.c_str(), text_color, align, true); 182 } 183 } 184 } 185 } 186 } 187 } 188 189 void CUIDrawer::DrawLyricTextSingleLine(CRect rect, bool double_line, Alignment align) 190 { 191 SetLyricFont(); 192 193 if (CPlayerUIHelper::IsMidiLyric()) 194 { 195 wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() }; 196 DrawWindowText(rect, current_lyric.c_str(), m_colors.color_text, Alignment::CENTER, false, true); 197 } 198 else if (CPlayer::GetInstance().m_Lyrics.IsEmpty()) 199 { 200 DrawWindowText(rect, CCommon::LoadText(IDS_NO_LYRIC_INFO), m_colors.color_text_2, Alignment::CENTER); 201 } 202 else 203 { 204 CRect lyric_rect = rect; 205 Time time = CPlayer::GetInstance().GetCurrentPosition(); 206 CLyrics::Lyric current_lyric{ CPlayer::GetInstance().m_Lyrics.GetLyric(time, 0) }; //��ȡ����� 207 if (current_lyric.text.empty()) //�����ǰ���Ϊ�հף�����ʾΪʡ�Ժ� 208 current_lyric.text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT); 209 int progress{ CPlayer::GetInstance().m_Lyrics.GetLyricProgress(time) }; //��ȡ��ǰ��ʽ��ȣ���ΧΪ0~1000�� 210 211 //˫����ʾ��� 212 if (double_line && (!CPlayer::GetInstance().m_Lyrics.IsTranslated() || !theApp.m_ui_data.show_translate) && rect.Height() > static_cast<int>(GetLyricTextHeight() * 1.73)) 213 { 214 wstring next_lyric_text = CPlayer::GetInstance().m_Lyrics.GetLyric(time, 1).text; 215 if (next_lyric_text.empty()) 216 next_lyric_text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT); 217 //����ʵ���ı��ӷǸ��������仯������Ч�� 218 int last_time_span = time - current_lyric.time; //��ǰ���ŵĸ���ѳ�����ʱ�� 219 int fade_percent = last_time_span / 8; //������ɫ�����仯�İٷֱȣ�����Խ�������ʱ��Խ����10��Ϊ1�� 220 DrawLyricDoubleLine(lyric_rect, current_lyric.text.c_str(), next_lyric_text.c_str(), progress, fade_percent); 221 } 222 else 223 { 224 if (theApp.m_ui_data.show_translate && !current_lyric.translate.empty() && rect.Height() > static_cast<int>(GetLyricTextHeight() * 1.73)) 225 { 226 lyric_rect.bottom = lyric_rect.top + rect.Height() / 2; 227 CRect translate_rect = lyric_rect; 228 translate_rect.MoveToY(lyric_rect.bottom); 229 230 SetLyricFontTranslated(); 231 DrawWindowText(translate_rect, current_lyric.translate.c_str(), m_colors.color_text, m_colors.color_text, progress, align, true); 232 } 233 234 SetLyricFont(); 235 if (theApp.m_lyric_setting_data.lyric_karaoke_disp) 236 DrawWindowText(lyric_rect, current_lyric.text.c_str(), m_colors.color_text, m_colors.color_text_2, progress, align, true); 237 else 238 DrawWindowText(lyric_rect, current_lyric.text.c_str(), m_colors.color_text, m_colors.color_text, progress, align, true); 239 } 240 241 SetFont(m_pMainWnd->GetFont()); 242 } 243 } 244 245 void CUIDrawer::DrawSpectrum(CRect rect, SpectrumCol col, bool draw_reflex /*= false*/, bool low_freq_in_center) 246 { 247 int cols; //Ҫ��ʾ��Ƶ�����ε����� 248 switch (col) 249 { 250 case CUIDrawer::SC_64: 251 cols = 64; 252 break; 253 case CUIDrawer::SC_32: 254 cols = 32; 255 break; 256 case CUIDrawer::SC_16: 257 cols = 16; 258 break; 259 case CUIDrawer::SC_8: 260 cols = 8; 261 break; 262 default: 263 cols = SPECTRUM_COL; 264 break; 265 } 266 int gap_width{ rect.Width() * (SPECTRUM_COL / cols) / 168 }; //Ƶ�����μ�϶��� 267 if (theApp.m_ui_data.full_screen) 268 gap_width *= CONSTVAL::FULL_SCREEN_ZOOM_FACTOR; 269 if (gap_width < 1) 270 gap_width = 1; 271 int width = (rect.Width() - (cols - 1) * gap_width) / (cols - 1); 272 273 DrawSpectrum(rect, width, gap_width, cols, m_colors.color_spectrum, draw_reflex, low_freq_in_center); 274 } 275 276 void CUIDrawer::DrawSpectrum(CRect rect, int col_width, int gap_width, int cols, COLORREF color, bool draw_reflex /*= false*/, bool low_freq_in_center) 277 { 278 CRect rc_spectrum_top = rect; 279 if (draw_reflex) //���Ҫ���Ƶ�Ӱ����Ӱռ�ܸ߶ȵ�1/3 280 rc_spectrum_top.bottom = rect.top + (rect.Height() * 2 / 3); 281 282 CRect rects[SPECTRUM_COL]; 283 rects[0] = rc_spectrum_top; 284 rects[0].right = rects[0].left + col_width; 285 for (int i{ 1 }; i < cols; i++) 286 { 287 rects[i] = rects[0]; 288 rects[i].left += (i * (col_width + gap_width)); 289 rects[i].right += (i * (col_width + gap_width)); 290 } 291 for (int i{}; i < cols; i++) 292 { 293 int index; 294 if (low_freq_in_center) 295 { 296 if (i < cols / 2) 297 index = (-i + cols / 2) * 2 - 1; 298 else 299 index = (i - cols / 2) * 2; 300 } 301 else 302 { 303 index = i; 304 } 305 if (index >= cols) 306 index = cols; 307 if (index < 0) 308 index = 0; 309 float spetral_data = CPlayer::GetInstance().GetSpectralData()[index * (SPECTRUM_COL / cols)]; 310 float peak_data = CPlayer::GetInstance().GetSpectralPeakData()[index * (SPECTRUM_COL / cols)]; 311 312 CRect rect_tmp{ rects[i] }; 313 int spetral_height = static_cast<int>(spetral_data * rects[0].Height() / 30 * theApp.m_app_setting_data.sprctrum_height / 100); 314 int peak_height = static_cast<int>(peak_data * rects[0].Height() / 30 * theApp.m_app_setting_data.sprctrum_height / 100); 315 if (spetral_height <= 0 || CPlayer::GetInstance().IsError()) spetral_height = 1; //Ƶ�߶�����Ϊ1�����أ�������ų���Ҳ����ʾƵ�� 316 if (peak_height <= 0 || CPlayer::GetInstance().IsError()) peak_height = 1; //Ƶ�߶�����Ϊ1�����أ�������ų���Ҳ����ʾƵ�� 317 rect_tmp.top = rect_tmp.bottom - spetral_height; 318 if (rect_tmp.top < rects[0].top) rect_tmp.top = rects[0].top; 319 FillRect(rect_tmp, color, true); 320 //���Ƶ�Ӱ 321 if (draw_reflex) 322 { 323 CRect rc_invert = rect_tmp; 324 rc_invert.bottom = rect_tmp.top + rect_tmp.Height() * 2 / 3; 325 rc_invert.MoveToY(rect_tmp.bottom + gap_width); 326 FillAlphaRect(rc_invert, color, 96, true); 327 } 328 329 //���ƶ��� 330 CRect rect_peak{ rect_tmp }; 331 rect_peak.bottom = rect_tmp.bottom - peak_height - gap_width; 332 rect_peak.top = rect_peak.bottom - max(theApp.DPIRound(1.1), gap_width / 2); 333 FillRect(rect_peak, color, true); 334 ////���ƶ��˵�Ӱ 335 //CRect rc_peak_invert = rect_peak; 336 //rc_peak_invert.MoveToY(rc_invert.top + peak_height + theApp.DPIRound(1.1)); 337 //FillAlphaRect(rc_peak_invert, color, 96); 338 } 339 340 } 341 342 void CUIDrawer::DrawLyricDoubleLine(CRect rect, LPCTSTR lyric, LPCTSTR next_lyric, int progress, int fade_percent) 343 { 344 SetLyricFont(); 345 static bool swap; 346 static int last_progress; 347 if (last_progress > progress) //�����ǰ�ĸ�ʽ��ȱ��ϴε�С��˵������л�������һ�� 348 { 349 swap = !swap; 350 } 351 last_progress = progress; 352 353 354 CRect up_rect{ rect }, down_rect{ rect }; //�ϰ벿�ֺ��°벿�ָ�ʵľ������� 355 up_rect.bottom = up_rect.top + (up_rect.Height() / 2); 356 down_rect.top = down_rect.bottom - (down_rect.Height() / 2); 357 //������һ���ʵ��ı�������Ҫ�Ŀ�ȣ��Ӷ�ʵ����һ�и���Ҷ��� 358 //GetDC()->SelectObject(&theApp.m_font_set.lyric.GetFont(theApp.m_ui_data.full_screen)); 359 int width; 360 if (!swap) 361 width = GetTextExtent(next_lyric).cx; 362 else 363 width = GetTextExtent(lyric).cx; 364 if (width < rect.Width()) 365 down_rect.left = down_rect.right - width; 366 367 COLORREF color1, color2; 368 if (theApp.m_lyric_setting_data.lyric_karaoke_disp) 369 { 370 color1 = m_colors.color_text; 371 color2 = m_colors.color_text_2; 372 } 373 else 374 { 375 color1 = color2 = CColorConvert::GetGradientColor(m_colors.color_text_2, m_colors.color_text, fade_percent); 376 } 377 378 if (!swap) 379 { 380 DrawWindowText(up_rect, lyric, color1, color2, progress); 381 DrawWindowText(down_rect, next_lyric, m_colors.color_text_2); 382 } 383 else 384 { 385 DrawWindowText(up_rect, next_lyric, m_colors.color_text_2); 386 DrawWindowText(down_rect, lyric, color1, color2, progress); 387 } 388 } 389 390 void CUIDrawer::SetLyricFont() 391 { 392 if (!m_for_cortana_lyric) 393 SetFont(&theApp.m_font_set.lyric.GetFont(theApp.m_ui_data.full_screen)); 394 else 395 SetFont(&theApp.m_font_set.cortana.GetFont()); 396 } 397 398 void CUIDrawer::SetLyricFontTranslated() 399 { 400 if (!m_for_cortana_lyric) 401 SetFont(&theApp.m_font_set.lyric_translate.GetFont(theApp.m_ui_data.full_screen)); 402 else 403 SetFont(&theApp.m_font_set.cortana_translate.GetFont()); 404 } 405