From 7b1dea1a7abbc8f542398a9ac55601753c20644f Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 29 Sep 2011 18:17:37 +0000 Subject: [PATCH] Eliminate flickering when moving the mouse over the karaoke split/join bar Originally committed to SVN as r5681. --- aegisub/src/audio_karaoke.cpp | 57 ++++++++++++++++++++--------------- aegisub/src/audio_karaoke.h | 7 +++++ 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/aegisub/src/audio_karaoke.cpp b/aegisub/src/audio_karaoke.cpp index 66e383e21..1fa4ddc3e 100644 --- a/aegisub/src/audio_karaoke.cpp +++ b/aegisub/src/audio_karaoke.cpp @@ -128,23 +128,19 @@ void AudioKaraoke::OnFileChanged(int type) { } void AudioKaraoke::SetEnabled(bool en) { - if (en) { - LoadFromLine(); - enabled = true; - c->audioController->SetTimingController(CreateKaraokeTimingController(c, kara.get(), file_changed)); - } - else { - accept_button->Enable(false); - cancel_button->Enable(false); - enabled = false; - c->audioController->SetTimingController(CreateDialogueTimingController(c)); - } + enabled = en; - c->audioBox->ShowKaraokeBar(en); + c->audioBox->ShowKaraokeBar(enabled); split_area->SetSize(GetSize().GetWidth(), -1); - if (en) + if (enabled) { + LoadFromLine(); + c->audioController->SetTimingController(CreateKaraokeTimingController(c, kara.get(), file_changed)); Refresh(false); + } + else { + c->audioController->SetTimingController(CreateDialogueTimingController(c)); + } } void AudioKaraoke::OnPaint(wxPaintEvent &evt) { @@ -152,14 +148,31 @@ void AudioKaraoke::OnPaint(wxPaintEvent &evt) { split_area->GetClientSize(&w, &h); wxPaintDC dc(split_area); + wxMemoryDC bmp_dc(rendered_line); + + // Draw the text and split lines + dc.Blit(0, 0, w, h, &bmp_dc, 0, 0); + + // Draw the split line under the mouse + dc.SetPen(*wxRED); + dc.DrawLine(mouse_pos, 0, mouse_pos, h); +} + +void AudioKaraoke::RenderText() { + int w, h; + split_area->GetClientSize(&w, &h); + + if (split_area->GetClientSize() != rendered_line.GetSize()) { + rendered_line = wxBitmap(w, h); + } + + wxMemoryDC dc(rendered_line); // Draw background - dc.SetBrush(wxBrush(wxSystemSettings::GetColour(enabled ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_FRAMEBK))); + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(0, 0, w, h); - if (!enabled) return; - dc.SetFont(split_font); dc.SetTextForeground(wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT))); @@ -169,10 +182,6 @@ void AudioKaraoke::OnPaint(wxPaintEvent &evt) { dc.DrawText(spaced_text[i], char_x[i], y); } - // Draw the split line under the mouse - dc.SetPen(*wxRED); - dc.DrawLine(mouse_pos, 0, mouse_pos, h); - // Draw the lines between each syllable dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)); for (size_t i = 0; i < syl_lines.size(); ++i) { @@ -202,7 +211,6 @@ void AudioKaraoke::OnContextMenu(wxContextMenuEvent&) { void AudioKaraoke::OnMouse(wxMouseEvent &event) { if (!enabled) return; - int old_mouse_pos = mouse_pos; mouse_pos = event.GetX(); if (event.Leaving()) @@ -210,10 +218,7 @@ void AudioKaraoke::OnMouse(wxMouseEvent &event) { if (!event.LeftDown()) { // Erase the old line and draw the new one - wxRect r1(mouse_pos - 1, 0, mouse_pos + 1, 100); - wxRect r2(old_mouse_pos - 1, 0, old_mouse_pos + 1, 100); - split_area->Refresh(false, &r1); - split_area->Refresh(false, &r2); + split_area->Refresh(false); return; } @@ -282,6 +287,8 @@ void AudioKaraoke::SetDisplayText() { // Get line height wxSize extents = dc.GetTextExtent(spaced_text); char_height = extents.GetHeight(); + + RenderText(); } void AudioKaraoke::CancelSplit() { diff --git a/aegisub/src/audio_karaoke.h b/aegisub/src/audio_karaoke.h index 8399f5c83..7e8fcde81 100644 --- a/aegisub/src/audio_karaoke.h +++ b/aegisub/src/audio_karaoke.h @@ -25,6 +25,7 @@ #include #include +#include #include #endif @@ -82,6 +83,9 @@ class AudioKaraoke : public wxWindow, private SelectionListener { /// Current line's stripped text with spaces added between each syllable wxString spaced_text; + /// spaced_text + syl_lines rendered to a bitmap + wxBitmap rendered_line; + /// Indexes in spaced_text which are the beginning of syllables std::vector syl_start_points; @@ -114,6 +118,9 @@ class AudioKaraoke : public wxWindow, private SelectionListener { /// Set the karaoke tags for the selected syllables to the indicated one void SetTagType(wxString new_type); + /// Prerender the current line along with syllable split lines + void RenderText(); + /// Refresh the area of the display around a single character /// @param pos Index in spaced_text void LimitedRefresh(int pos);