1 #include "stdafx.h"
2 #include "CortanaLyric.h"
3 #include "SongInfoHelper.h"
4 #include "CPlayerUIBase.h"
5 #include "CPlayerUIHelper.h"
6 #include "Player.h"
7 #include "WinVersionHelper.h"
8
9 CCriticalSection CCortanaLyric::m_critical;
10
CCortanaLyric()11 CCortanaLyric::CCortanaLyric()
12 {
13 m_draw.SetForCortanaLyric();
14 }
15
16
~CCortanaLyric()17 CCortanaLyric::~CCortanaLyric()
18 {
19 if (m_pDC != nullptr)
20 m_cortana_wnd->ReleaseDC(m_pDC);
21
22 //退出时恢复Cortana窗口透明
23 #ifndef COMPILE_IN_WIN_XP
24 SetCortanaBarOpaque(false);
25 #endif // !COMPILE_IN_WIN_XP
26
27 }
28
Init()29 void CCortanaLyric::Init()
30 {
31 m_hCortanaBar = NULL;
32 HWND hTaskBar = ::FindWindow(_T("Shell_TrayWnd"), NULL); //任务栏的句柄
33 if (CWinVersionHelper::IsWindows11OrLater())
34 {
35 auto isWindowSearchBox = [](HWND hWnd) -> bool
36 {
37 CRect rect_search_box;
38 ::GetClientRect(hWnd, rect_search_box);
39 return rect_search_box.Width() >= theApp.DPI(120); //确保搜索框的宽度大于一定值
40 };
41
42 m_hCortanaBar = ::FindWindowEx(hTaskBar, NULL, _T("SIBTrayButton"), NULL); //如果找到类名为SIBTrayButton的窗口,则说明搜索框是通过StartAllBack软件实现的
43
44 if (m_hCortanaBar != NULL)
45 {
46 //确保搜索框的宽度大于一定值
47 if (!isWindowSearchBox(m_hCortanaBar))
48 m_hCortanaBar = ::FindWindowEx(hTaskBar, m_hCortanaBar, _T("SIBTrayButton"), NULL); //查找下一个SIBTrayButton
49 }
50
51 if (m_hCortanaBar != NULL)
52 {
53 if (isWindowSearchBox(m_hCortanaBar))
54 {
55 m_cortana_hwnd = m_hCortanaBar;
56 m_hCortanaStatic = m_hCortanaBar;
57 }
58 else
59 {
60 m_cortana_hwnd = NULL;
61 m_hCortanaStatic = NULL;
62 }
63 }
64 }
65 if (m_hCortanaBar == NULL)
66 {
67 m_hCortanaBar = ::FindWindowEx(hTaskBar, NULL, _T("TrayDummySearchControl"), NULL); //Cortana栏的句柄(其中包含3个子窗口)
68 m_cortana_hwnd = ::FindWindowEx(m_hCortanaBar, NULL, _T("Button"), NULL); //Cortana搜索框中类名为“Button”的窗口的句柄
69 m_hCortanaStatic = ::FindWindowEx(m_hCortanaBar, NULL, _T("Static"), NULL); //Cortana搜索框中类名为“Static”的窗口的句柄
70 }
71 if (m_cortana_hwnd == NULL)
72 return;
73 if (m_enable)
74 {
75 CSingleLock sync(&m_critical, TRUE);
76 wchar_t buff[32];
77 ::GetWindowText(m_cortana_hwnd, buff, 31); //获取Cortana搜索框中原来的字符串,用于在程序退出时恢复
78 m_cortana_default_text = buff;
79 m_cortana_wnd = CWnd::FromHandle(m_cortana_hwnd); //获取Cortana搜索框的CWnd类的指针
80 if (m_cortana_wnd == nullptr) return;
81
82 ::GetClientRect(m_hCortanaBar, m_cortana_rect); //获取Cortana搜索框的矩形区域
83
84 CRect cortana_rect;
85 CRect cortana_static_rect; //Cortana搜索框中static控件的矩形区域
86 ::GetWindowRect(m_hCortanaBar, cortana_rect);
87 ::GetWindowRect(m_hCortanaStatic, cortana_static_rect); //获取Cortana搜索框中static控件的矩形区域
88
89 const int min_conver_width = theApp.DPI(40);
90 m_cover_width = cortana_static_rect.left - cortana_rect.left;
91 if (m_cover_width < min_conver_width)
92 m_cover_width = min_conver_width;
93
94 m_pDC = m_cortana_wnd->GetDC();
95 m_draw.Create(m_pDC, m_cortana_wnd->GetFont());
96
97
98 //获取用来检查小娜是否为深色模式的采样点的坐标
99 //m_check_dark_point.x = cortana_rect.right - 2;
100 //m_check_dark_point.y = cortana_rect.top + 2;
101
102 CWinVersionHelper::CheckWindows10LightTheme();
103 SetDarkMode(!CWinVersionHelper::IsWindows10LightTheme());
104
105 //设置字体
106 LOGFONT lf;
107 SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0); //获取系统默认字体
108 if (m_default_font.m_hObject)
109 m_default_font.DeleteObject();
110 m_default_font.CreatePointFont(110, lf.lfFaceName);
111
112 InitFont();
113
114 //为Cortana搜索框设置一个透明色,使Cortana搜索框不透明
115 #ifndef COMPILE_IN_WIN_XP
116 //if(theApp.m_lyric_setting_data.cortana_opaque)
117 //{
118 m_cortana_opaque = false;
119 SetCortanaBarOpaque(true);
120 //}
121 #endif // !COMPILE_IN_WIN_XP
122
123 }
124 }
125
InitFont()126 void CCortanaLyric::InitFont()
127 {
128 theApp.m_font_set.cortana.SetFont(theApp.m_lyric_setting_data.cortana_font);
129 FontInfo translate_font = theApp.m_lyric_setting_data.cortana_font;
130 translate_font.size--;
131 theApp.m_font_set.cortana_translate.SetFont(translate_font);
132 }
133
SetEnable(bool enable)134 void CCortanaLyric::SetEnable(bool enable)
135 {
136 m_enable = enable;
137 }
138
DrawInfo()139 void CCortanaLyric::DrawInfo()
140 {
141 if (!m_enable)
142 return;
143
144 CSingleLock sync(&m_critical, TRUE);
145 bool is_midi_lyric = CPlayerUIHelper::IsMidiLyric();
146
147 static wstring str_now_playing{ theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_PLAYING") + L": " };
148
149 //不使用兼容模式显示歌词,直接在小娜搜索框内绘图
150 if(!theApp.m_lyric_setting_data.cortana_lyric_compatible_mode || CWinVersionHelper::IsWindows11OrLater()) //Windows11无法使用兼容模式显示歌词
151 {
152 if (m_pDC != nullptr)
153 {
154 m_draw.SetFont(&theApp.m_font_set.cortana.GetFont());
155 // 设置m_draw的歌词字体,DrawLyricTextMultiLine / DrawLyricTextSingleLine依赖此状态
156 m_draw.SetLyricFont(&theApp.m_font_set.cortana.GetFont(), &theApp.m_font_set.cortana_translate.GetFont());
157 //双缓冲绘图
158 CDrawDoubleBuffer drawDoubleBuffer(m_pDC, m_cortana_rect);
159 //使用m_draw绘图
160 m_draw.SetDC(drawDoubleBuffer.GetMemDC());
161 m_draw.FillRect(m_cortana_rect, m_colors.back_color);
162
163 if(theApp.m_lyric_setting_data.cortana_show_spectrum)
164 DrawSpectrum();
165
166 if (is_midi_lyric)
167 {
168 wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() };
169 DrawCortanaTextSimple(current_lyric.c_str(), Alignment::LEFT);
170 }
171 else
172 {
173 const bool karaoke{ theApp.m_lyric_setting_data.lyric_karaoke_disp };
174 const bool ignore_blank{ theApp.m_lyric_setting_data.donot_show_blank_lines };
175 Time time{ CPlayer::GetInstance().GetCurrentPosition() };
176 int progress{ CPlayer::GetInstance().m_Lyrics.GetLyricProgress(time, ignore_blank, karaoke, [this](const wstring& str) { return m_draw.GetTextExtent(str.c_str()).cx; }) };
177 CLyrics::Lyric lyric{ CPlayer::GetInstance().m_Lyrics.GetLyric(time, false, ignore_blank, karaoke) };
178 bool no_lyric{ false };
179 //如果当前一句歌词为空,且持续了超过了20秒,则不显示歌词
180 no_lyric = (lyric.text.empty() && CPlayer::GetInstance().GetCurrentPosition() - lyric.time_start > 20000) || progress >= 1000;
181
182 if (!CPlayer::GetInstance().m_Lyrics.IsEmpty() && !no_lyric && theApp.m_lyric_setting_data.cortana_show_lyric) //有歌词时显示歌词
183 {
184 static int flag{};
185 if (m_draw.IsDrawMultiLine(m_cortana_rect.Height()))
186 m_draw.DrawLyricTextMultiLine(TextRect(), theApp.m_lyric_setting_data.cortana_lyric_align);
187 else
188 m_draw.DrawLyricTextSingleLine(TextRect(), flag, theApp.m_lyric_setting_data.cortana_lyric_double_line, theApp.m_lyric_setting_data.cortana_lyric_align);
189 }
190 else //没有歌词时在Cortana搜索框上以滚动的方式显示当前播放歌曲的文件名
191 {
192 static SongInfo last_song_info;
193 const SongInfo& song_info = CPlayer::GetInstance().GetCurrentSongInfo();
194 //如果当前播放的歌曲发生变化,DrawCortanaText函数的第2参数为true,即重置滚动位置
195 if (!song_info.IsSameSong(last_song_info))
196 {
197 DrawCortanaText((str_now_playing + CSongInfoHelper::GetDisplayStr(song_info, theApp.m_media_lib_setting_data.display_format)).c_str(), true, CPlayerUIHelper::GetScrollTextPixel());
198 last_song_info = song_info;
199 }
200 else
201 {
202 DrawCortanaText((str_now_playing + CSongInfoHelper::GetDisplayStr(song_info, theApp.m_media_lib_setting_data.display_format)).c_str(), false, CPlayerUIHelper::GetScrollTextPixel());
203 }
204 }
205 }
206
207 //计算频谱,根据频谱幅值使Cortana图标显示动态效果
208 float spectrum_avr{}; //取前面N个频段频谱值的平均值
209 const int IMIN = FFT_SAMPLE / 20;
210 const int IMAX = FFT_SAMPLE / 3;
211 for (int i{ IMIN }; i < IMAX; i++)
212 spectrum_avr += CPlayer::GetInstance().GetFFTData()[i];
213 spectrum_avr /= (IMAX - IMIN);
214 int spetraum = static_cast<int>(spectrum_avr * 22000); //调整乘号后面的数值可以调整Cortana图标跳动时缩放的大小
215 SetBeatAmp(spetraum);
216 //显示专辑封面,如果没有专辑封面,则显示Cortana图标
217 AlbumCoverEnable(theApp.m_lyric_setting_data.cortana_show_album_cover/* && CPlayer::GetInstance().AlbumCoverExist()*/);
218 DrawAlbumCover(CPlayer::GetInstance().GetAlbumCover());
219
220 //if (!m_colors.dark /*&& !theApp.m_lyric_setting_data.cortana_opaque*/) //非深色模式下,在搜索顶部绘制边框
221 //{
222 // CRect rect{ m_cortana_rect };
223 // rect.left += m_cover_width;
224 // m_draw.DrawRectTopFrame(rect, m_border_color);
225 //}
226 }
227 }
228
229 //使用兼容模式显示歌词,给小娜搜索框设置文本
230 else
231 {
232 CWnd* pWnd = CWnd::FromHandle(m_hCortanaStatic);
233 if (pWnd != nullptr)
234 {
235 static wstring str_disp_last;
236 wstring str_disp;
237 if (is_midi_lyric)
238 {
239 str_disp = CPlayer::GetInstance().GetMidiLyric();
240 }
241 else if (!CPlayer::GetInstance().m_Lyrics.IsEmpty()) //有歌词时显示歌词
242 {
243 static const wstring& empty_lyric = theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE");
244 Time time{ CPlayer::GetInstance().GetCurrentPosition() };
245 str_disp = CPlayer::GetInstance().m_Lyrics.GetLyric(time, false, false, false).text;
246 if (str_disp.empty())
247 str_disp = empty_lyric;
248 }
249 else
250 {
251 //没有歌词时显示当前播放歌曲的名称
252 str_disp = str_now_playing + CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format);
253 }
254
255 if(str_disp != str_disp_last)
256 {
257 pWnd->SetWindowText(str_disp.c_str());
258 pWnd->Invalidate();
259 str_disp_last = str_disp;
260 }
261 }
262 }
263 }
264
SetCortanaBarOpaque(bool opaque)265 void CCortanaLyric::SetCortanaBarOpaque(bool opaque)
266 {
267 if (opaque)
268 {
269 if(!m_cortana_opaque)
270 {
271 //设置不透明
272 SetWindowLong(m_hCortanaBar, GWL_EXSTYLE, GetWindowLong(m_hCortanaBar, GWL_EXSTYLE) | WS_EX_LAYERED);
273 ::SetLayeredWindowAttributes(m_hCortanaBar, theApp.m_lyric_setting_data.cortana_transparent_color, 0, LWA_COLORKEY);
274 }
275 }
276 else
277 {
278 if(m_cortana_opaque)
279 //恢复不透明
280 SetWindowLong(m_hCortanaBar, GWL_EXSTYLE, GetWindowLong(m_hCortanaBar, GWL_EXSTYLE) & ~WS_EX_LAYERED);
281 }
282 m_cortana_opaque = opaque;
283 }
284
DrawCortanaTextSimple(LPCTSTR str,Alignment align)285 void CCortanaLyric::DrawCortanaTextSimple(LPCTSTR str, Alignment align)
286 {
287 if (m_enable && m_cortana_hwnd != NULL && m_cortana_wnd != nullptr)
288 {
289 CRect text_rect{ TextRect() };
290 m_draw.DrawWindowText(text_rect, str, m_colors.info_text_color, align, false, false, true);
291 }
292 }
293
DrawCortanaText(LPCTSTR str,bool reset,double scroll_pixel)294 void CCortanaLyric::DrawCortanaText(LPCTSTR str, bool reset, double scroll_pixel)
295 {
296 if (m_enable && m_cortana_hwnd != NULL && m_cortana_wnd != nullptr)
297 {
298 static CDrawCommon::ScrollInfo cortana_scroll_info;
299 CRect text_rect{ TextRect() };
300 m_draw.DrawScrollText(text_rect, str, m_colors.info_text_color, scroll_pixel, false, cortana_scroll_info, reset);
301 }
302 }
303
DrawCortanaText(LPCTSTR str,int progress)304 void CCortanaLyric::DrawCortanaText(LPCTSTR str, int progress)
305 {
306 if (m_enable && m_cortana_hwnd != NULL && m_cortana_wnd != nullptr)
307 {
308 CRect text_rect{ TextRect() };
309 if(theApp.m_lyric_setting_data.lyric_karaoke_disp)
310 m_draw.DrawWindowText(text_rect, str, m_colors.text_color, m_colors.text_color2, progress);
311 else
312 m_draw.DrawWindowText(text_rect, str, m_colors.text_color, m_colors.text_color, progress);
313 }
314 }
315
DrawAlbumCover(const CImage & album_cover)316 void CCortanaLyric::DrawAlbumCover(const CImage & album_cover)
317 {
318 if (m_enable)
319 {
320 CRect cover_rect = CoverRect();
321 DrawAreaGuard guard(&m_draw, cover_rect);
322 if (album_cover.IsNull() || !m_show_album_cover)
323 {
324 if (theApp.m_lyric_setting_data.show_default_album_icon_in_search_box)
325 {
326 CRect rc_icon{};
327 const int icon_side = theApp.DPI(32);
328 rc_icon.right = rc_icon.bottom = icon_side;
329 rc_icon.MoveToX(cover_rect.left + (cover_rect.Width() - icon_side) / 2);
330 rc_icon.MoveToY(cover_rect.top + (cover_rect.Height() - icon_side) / 2);
331
332 IconMgr::IconType icon_type = IconMgr::IconType::IT_Default_Cover_Stopped;
333 if (CPlayer::GetInstance().IsPlaying())
334 icon_type = IconMgr::IconType::IT_Default_Cover_Playing;
335 HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_32);
336
337 m_draw.DrawIcon(hIcon, rc_icon.TopLeft(), rc_icon.Size());
338 }
339 else
340 {
341 int cortana_img_id{ m_colors.dark ? IDB_CORTANA_BLACK : IDB_CORTANA_WHITE };
342 if (theApp.m_lyric_setting_data.cortana_icon_beat)
343 {
344 m_draw.FillRect(cover_rect, m_colors.back_color);
345 CRect rect{ cover_rect };
346 rect.DeflateRect(theApp.DPI(4), theApp.DPI(4));
347 int inflate;
348 inflate = m_beat_amp * theApp.DPI(14) / 1000;
349 rect.InflateRect(inflate, inflate);
350 m_draw.DrawBitmap(cortana_img_id, rect.TopLeft(), rect.Size(), CDrawCommon::StretchMode::FIT);
351 }
352 else
353 {
354 m_draw.DrawBitmap(cortana_img_id, cover_rect.TopLeft(), cover_rect.Size(), CDrawCommon::StretchMode::FIT);
355 }
356 }
357
358 //if(!m_colors.dark)
359 // m_draw.DrawRectTopFrame(cover_rect, m_border_color);
360 }
361 else
362 {
363 m_draw.DrawBitmap(album_cover, cover_rect.TopLeft(), cover_rect.Size(), CDrawCommon::StretchMode::FILL);
364 }
365 }
366 }
367
DrawSpectrum()368 void CCortanaLyric::DrawSpectrum()
369 {
370 CRect rc_spectrum{ TextRect() };
371 const int max_spectrum_height{ theApp.DPI(80) }; //频谱区域的最大高度
372 if (rc_spectrum.Height() > max_spectrum_height)
373 rc_spectrum.top = rc_spectrum.bottom - max_spectrum_height;
374
375 DrawAreaGuard guard(&m_draw, rc_spectrum);
376 rc_spectrum.right += theApp.DPI(8);
377 m_draw.DrawSpectrum(rc_spectrum, CUIDrawer::SC_64, false, theApp.m_app_setting_data.spectrum_low_freq_in_center, true);
378 }
379
TextRect() const380 CRect CCortanaLyric::TextRect() const
381 {
382 CRect text_rect{ m_cortana_rect };
383 text_rect.left += m_cover_width;
384 text_rect.DeflateRect(theApp.DPI(4), theApp.DPI(2));
385 text_rect.top -= theApp.DPI(1);
386 return text_rect;
387 }
388
CoverRect() const389 CRect CCortanaLyric::CoverRect() const
390 {
391 CRect cover_rect = m_cortana_rect;
392 cover_rect.right = cover_rect.left + m_cover_width;
393 return cover_rect;
394 }
395
ResetCortanaText()396 void CCortanaLyric::ResetCortanaText()
397 {
398 if (m_enable && m_cortana_hwnd != NULL && m_cortana_wnd != nullptr)
399 {
400 CSingleLock sync(&m_critical, TRUE);
401 CWnd* pWnd = CWnd::FromHandle(m_hCortanaStatic);
402 if (pWnd != nullptr)
403 {
404 CString str;
405 pWnd->GetWindowText(str);
406 if (str != m_cortana_default_text.c_str())
407 {
408 pWnd->SetWindowText(m_cortana_default_text.c_str());
409 pWnd->Invalidate();
410 }
411 }
412
413 if (!theApp.m_lyric_setting_data.cortana_lyric_compatible_mode && m_pDC != nullptr)
414 {
415 m_draw.SetFont(&m_default_font);
416 COLORREF color; //Cortana默认文本的颜色
417 color = (m_dark_mode ? GRAY(173) : GRAY(16));
418 m_draw.SetDC(m_pDC);
419 //先绘制Cortana图标
420 CRect cover_rect = CoverRect();
421 if (m_dark_mode)
422 m_draw.DrawBitmap(IDB_CORTANA_BLACK, cover_rect.TopLeft(), cover_rect.Size(), CDrawCommon::StretchMode::FIT);
423 else
424 m_draw.DrawBitmap(IDB_CORTANA_WHITE, cover_rect.TopLeft(), cover_rect.Size(), CDrawCommon::StretchMode::FIT);
425 //再绘制Cortana默认文本
426 CRect rect{ m_cortana_rect };
427 rect.left += m_cover_width;
428 m_draw.FillRect(rect, m_colors.back_color);
429 m_draw.DrawWindowText(rect, m_cortana_default_text.c_str(), color);
430 //if (!m_dark_mode)
431 //{
432 // rect.left -= m_cover_width;
433 // m_draw.DrawRectTopFrame(rect, m_border_color);
434 //}
435 //m_cortana_wnd->Invalidate();
436 }
437 }
438 }
439
SetDarkMode(bool dark_mode)440 void CCortanaLyric::SetDarkMode(bool dark_mode)
441 {
442 if (m_enable)
443 {
444 m_dark_mode = dark_mode;
445 SetCortanaBarOpaque(!m_dark_mode);
446 SetUIColors();
447 }
448 }
449
ApplySearchBoxTransparentChanged()450 void CCortanaLyric::ApplySearchBoxTransparentChanged()
451 {
452 if (CWinVersionHelper::IsWindows10LightTheme())
453 {
454 m_cortana_opaque = false;
455 SetCortanaBarOpaque(true);
456 }
457 }
458
IsSearchBoxAvailable() const459 bool CCortanaLyric::IsSearchBoxAvailable() const
460 {
461 return m_cortana_hwnd != NULL;
462 }
463
AlbumCoverEnable(bool enable)464 void CCortanaLyric::AlbumCoverEnable(bool enable)
465 {
466 CSingleLock sync(&m_critical, TRUE);
467 bool last_enable;
468 last_enable = m_show_album_cover;
469 m_show_album_cover = enable;
470 if (last_enable && !enable && m_pDC != nullptr)
471 {
472 CRect cover_rect = CoverRect();
473 DrawAreaGuard guard(&m_draw, cover_rect);
474 m_pDC->FillSolidRect(cover_rect, m_colors.back_color);
475 }
476 }
477
SetBeatAmp(int beat_amp)478 void CCortanaLyric::SetBeatAmp(int beat_amp)
479 {
480 m_beat_amp = beat_amp;
481 if (m_beat_amp < 0) m_beat_amp = 0;
482 if (m_beat_amp > 2000) m_beat_amp = 2000;
483 }
484
SetUIColors()485 void CCortanaLyric::SetUIColors()
486 {
487 if (theApp.m_lyric_setting_data.cortana_color == 1)
488 m_colors.dark = true;
489 else if (theApp.m_lyric_setting_data.cortana_color == 2)
490 m_colors.dark = false;
491 else
492 m_colors.dark = m_dark_mode;
493
494 m_lyric_colors = CPlayerUIHelper::GetUIColors(theApp.m_app_setting_data.theme_color, m_colors.dark);
495
496 if (m_colors.dark)
497 {
498 m_colors.text_color = theApp.m_app_setting_data.theme_color.light3;
499 m_colors.text_color2 = theApp.m_app_setting_data.theme_color.light1;
500 m_colors.info_text_color = theApp.m_app_setting_data.theme_color.light3;
501 m_lyric_colors.color_spectrum = theApp.m_app_setting_data.theme_color.dark0;
502
503 DWORD dwStyle = GetWindowLong(m_hCortanaStatic, GWL_STYLE);
504 if ((dwStyle & WS_VISIBLE) != 0) //根据Cortana搜索框中static控件是否有WS_VISIBLE属性为绘图背景设置不同的背景色
505 m_colors.back_color = GRAY(47); //设置绘图的背景颜色
506 else
507 m_colors.back_color = GRAY(10); //设置绘图的背景颜色
508 }
509 else
510 {
511 m_colors.text_color = theApp.m_app_setting_data.theme_color.dark3;
512 m_colors.text_color2 = theApp.m_app_setting_data.theme_color.dark1;
513 m_colors.info_text_color = theApp.m_app_setting_data.theme_color.dark2;
514 m_colors.back_color = LIGHT_MODE_SEARCH_BOX_BACKGROUND_COLOR;
515 m_lyric_colors.color_spectrum = theApp.m_app_setting_data.theme_color.dark0;
516
517 m_lyric_colors.color_text = theApp.m_app_setting_data.theme_color.dark3;
518 m_lyric_colors.color_text_2 = theApp.m_app_setting_data.theme_color.dark1;
519 }
520 }
521