Significantly speed up grid painting, especially when only some columns need to be repainted

Originally committed to SVN as r5571.
This commit is contained in:
Thomas Goyne 2011-08-27 06:52:42 +00:00
parent b8a1674c27
commit 03d7849d12
2 changed files with 77 additions and 63 deletions

View file

@ -387,8 +387,6 @@ BEGIN_EVENT_TABLE(BaseGrid,wxWindow)
END_EVENT_TABLE() END_EVENT_TABLE()
void BaseGrid::OnPaint(wxPaintEvent &event) { void BaseGrid::OnPaint(wxPaintEvent &event) {
wxPaintDC dc(this);
// Get size and pos // Get size and pos
int w = 0; int w = 0;
int h = 0; int h = 0;
@ -404,14 +402,30 @@ void BaseGrid::OnPaint(wxPaintEvent &event) {
} }
if (!bmp) bmp = new wxBitmap(w,h); if (!bmp) bmp = new wxBitmap(w,h);
// Find which columns need to be repainted
bool paint_columns[11];
memset(paint_columns, 0, sizeof paint_columns);
for (wxRegionIterator region(GetUpdateRegion()); region; ++region)
{
wxRect updrect = region.GetRect();
int x = 0;
for (size_t i = 0; i < 11; ++i) {
if (updrect.x < x + colWidth[i] && updrect.x + updrect.width > x)
paint_columns[i] = true;
x += colWidth[i];
}
}
// Draw bitmap // Draw bitmap
wxMemoryDC bmpDC; wxMemoryDC bmpDC;
bmpDC.SelectObject(*bmp); bmpDC.SelectObject(*bmp);
DrawImage(bmpDC); DrawImage(bmpDC, paint_columns);
wxPaintDC dc(this);
dc.Blit(0,0,w,h,&bmpDC,0,0); dc.Blit(0,0,w,h,&bmpDC,0,0);
} }
void BaseGrid::DrawImage(wxDC &dc) { void BaseGrid::DrawImage(wxDC &dc, bool paint_columns[]) {
int w = 0; int w = 0;
int h = 0; int h = 0;
GetClientSize(&w,&h); GetClientSize(&w,&h);
@ -453,26 +467,26 @@ void BaseGrid::DrawImage(wxDC &dc) {
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
// Draw rows // Draw rows
wxString strings[11] = {
_("#"),
_("L"),
_("Start"),
_("End"),
_("Style"),
_("Actor"),
_("Effect"),
_("Left"),
_("Right"),
_("Vert"),
_("Text")
};
for (int i = 0; i < nDraw + 1; i++) { for (int i = 0; i < nDraw + 1; i++) {
int curRow = i + yPos - 1; int curRow = i + yPos - 1;
int curColor = 0; int curColor = 0;
wxArrayString strings;
strings.reserve(11);
// Header // Header
if (i == 0) { if (i == 0) {
strings.Add(_("#"));
strings.Add(_("L"));
strings.Add(_("Start"));
strings.Add(_("End"));
strings.Add(_("Style"));
strings.Add(_("Actor"));
strings.Add(_("Effect"));
strings.Add(_("Left"));
strings.Add(_("Right"));
strings.Add(_("Vert"));
strings.Add(_("Text"));
curColor = 1; curColor = 1;
dc.SetTextForeground(text_standard); dc.SetTextForeground(text_standard);
} }
@ -480,55 +494,49 @@ void BaseGrid::DrawImage(wxDC &dc) {
// Lines // Lines
else if (AssDialogue *curDiag = GetDialogue(curRow)) { else if (AssDialogue *curDiag = GetDialogue(curRow)) {
// Set fields // Set fields
strings.Add(wxString::Format("%i", curRow + 1)); if (paint_columns[0]) strings[0] = wxString::Format("%i", curRow + 1);
strings.Add(wxString::Format("%i", curDiag->Layer)); if (paint_columns[1]) strings[1] = wxString::Format("%i", curDiag->Layer);
if (byFrame) { if (byFrame) {
strings.Add(wxString::Format("%i", context->videoController->FrameAtTime(curDiag->Start.GetMS(), agi::vfr::START))); if (paint_columns[2]) strings[2] = wxString::Format("%i", context->videoController->FrameAtTime(curDiag->Start.GetMS(), agi::vfr::START));
strings.Add(wxString::Format("%i", context->videoController->FrameAtTime(curDiag->End.GetMS(), agi::vfr::END))); if (paint_columns[3]) strings[3] = wxString::Format("%i", context->videoController->FrameAtTime(curDiag->End.GetMS(), agi::vfr::END));
} }
else { else {
strings.Add(curDiag->Start.GetASSFormated()); if (paint_columns[2]) strings[2] = curDiag->Start.GetASSFormated();
strings.Add(curDiag->End.GetASSFormated()); if (paint_columns[3]) strings[3] = curDiag->End.GetASSFormated();
} }
strings.Add(curDiag->Style); if (paint_columns[4]) strings[4] = curDiag->Style;
strings.Add(curDiag->Actor); if (paint_columns[5]) strings[5] = curDiag->Actor;
strings.Add(curDiag->Effect); if (paint_columns[6]) strings[6] = curDiag->Effect;
strings.Add(curDiag->GetMarginString(0)); if (paint_columns[7]) strings[7] = curDiag->GetMarginString(0);
strings.Add(curDiag->GetMarginString(1)); if (paint_columns[8]) strings[8] = curDiag->GetMarginString(1);
strings.Add(curDiag->GetMarginString(2)); if (paint_columns[9]) strings[9] = curDiag->GetMarginString(2);
// Set text // Set text
int mode = OPT_GET("Subtitle/Grid/Hide Overrides")->GetInt(); if (paint_columns[10]) {
wxString value; strings[10].clear();
int mode = OPT_GET("Subtitle/Grid/Hide Overrides")->GetInt();
// Hidden overrides // Hidden overrides
if (mode == 1 || mode == 2) { if (mode == 1 || mode == 2) {
wxString replaceWith = lagi_wxString(OPT_GET("Subtitle/Grid/Hide Overrides Char")->GetString()); wxString replaceWith = lagi_wxString(OPT_GET("Subtitle/Grid/Hide Overrides Char")->GetString());
size_t textlen = curDiag->Text.size(); strings[10].reserve(curDiag->Text.size());
value.reserve(textlen); size_t start = 0, pos;
bool in_comment = false; while ((pos = curDiag->Text.find('{', start)) != wxString::npos) {
for (size_t j = 0; j < textlen; ++j) { strings[10] += curDiag->Text.Mid(start, pos - start);
wxChar curChar = curDiag->Text[j]; strings[10] += replaceWith;
if (curChar == '{') { start = curDiag->Text.find('}', pos);
if (!in_comment && mode == 1) value += replaceWith; if (start != wxString::npos) ++start;
in_comment = true;
}
else if (in_comment && curChar == '}') {
in_comment = false;
}
else if (!in_comment) {
value += curChar;
} }
strings[10] += curDiag->Text.Mid(start);
} }
// Show overrides
else strings[10] = curDiag->Text;
// Cap length and set text
if (strings[10].size() > 512) strings[10] = strings[10].Left(512) + "...";
} }
// Show overrides
else value = curDiag->Text;
// Cap length and set text
if (value.size() > 512) value = value.Left(512) + "...";
strings.Add(value);
// Set color // Set color
curColor = 0; curColor = 0;
bool inSel = IsInSelection(curRow); bool inSel = IsInSelection(curRow);
@ -548,7 +556,7 @@ void BaseGrid::DrawImage(wxDC &dc) {
} }
} }
else { else {
strings.resize(11, "?"); assert(false);
} }
// Draw row background color // Draw row background color
@ -563,13 +571,19 @@ void BaseGrid::DrawImage(wxDC &dc) {
for (int j = 0; j < 11; j++) { for (int j = 0; j < 11; j++) {
if (colWidth[j] == 0) continue; if (colWidth[j] == 0) continue;
bool isCenter = !(j == 4 || j == 5 || j == 6 || j == 10); if (paint_columns[j]) {
wxSize ext = dc.GetTextExtent(strings[j]);
wxRect cur(dx+4,dy,colWidth[j]-6,lineHeight); int left = dx + 4;
dc.DestroyClippingRegion(); int top = dy + (lineHeight - ext.GetHeight()) / 2;
dc.SetClippingRegion(cur);
dc.DrawLabel(strings[j], cur, isCenter ? wxALIGN_CENTER : (wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT)); // Centered columns
if (!(j == 4 || j == 5 || j == 6 || j == 10)) {
left += (colWidth[j] - 6 - ext.GetWidth()) / 2;
}
dc.DrawText(strings[j], left, top);
}
dx += colWidth[j]; dx += colWidth[j];
} }

View file

@ -97,7 +97,7 @@ class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> {
void OnMouseEvent(wxMouseEvent &event); void OnMouseEvent(wxMouseEvent &event);
void OnKeyDown(wxKeyEvent &event); void OnKeyDown(wxKeyEvent &event);
void DrawImage(wxDC &dc); void DrawImage(wxDC &dc, bool paint_columns[]);
void ScrollTo(int y); void ScrollTo(int y);
virtual void OnPopupMenu(bool alternate = false) { } virtual void OnPopupMenu(bool alternate = false) { }