Split AudioDisplay::OnPaint into several methods
Originally committed to SVN as r6251.
This commit is contained in:
parent
3c62a38c7a
commit
702d1e9c22
2 changed files with 166 additions and 128 deletions
|
@ -845,12 +845,7 @@ void AudioDisplay::OnPaint(wxPaintEvent&)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_width, client_height;
|
wxRect audio_bounds(0, audio_top, GetClientSize().GetWidth(), audio_height);
|
||||||
GetClientSize(&client_width, &client_height);
|
|
||||||
|
|
||||||
wxRect audio_bounds(0, audio_top, client_width, audio_height);
|
|
||||||
const wxRect &scrollbar_bounds = scrollbar->GetBounds();
|
|
||||||
const wxRect &timeline_bounds = timeline->GetBounds();
|
|
||||||
bool redraw_scrollbar = false;
|
bool redraw_scrollbar = false;
|
||||||
bool redraw_timeline = false;
|
bool redraw_timeline = false;
|
||||||
|
|
||||||
|
@ -864,136 +859,24 @@ void AudioDisplay::OnPaint(wxPaintEvent&)
|
||||||
updrect.x += client_org.x; updrect.y += client_org.y;
|
updrect.x += client_org.x; updrect.y += client_org.y;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
redraw_scrollbar |= scrollbar_bounds.Intersects(updrect);
|
redraw_scrollbar |= scrollbar->GetBounds().Intersects(updrect);
|
||||||
redraw_timeline |= timeline_bounds.Intersects(updrect);
|
redraw_timeline |= timeline->GetBounds().Intersects(updrect);
|
||||||
|
|
||||||
if (!audio_bounds.Intersects(updrect))
|
if (audio_bounds.Intersects(updrect))
|
||||||
{
|
{
|
||||||
continue;
|
SampleRange updsamples(
|
||||||
}
|
SamplesFromRelativeX(updrect.x - foot_size),
|
||||||
|
SamplesFromRelativeX(updrect.x + updrect.width + foot_size));
|
||||||
|
|
||||||
SampleRange updsamples(
|
PaintAudio(dc, updsamples, updrect);
|
||||||
SamplesFromRelativeX(updrect.x - foot_size),
|
PaintMarkers(dc, updsamples);
|
||||||
SamplesFromRelativeX(updrect.x + updrect.width + foot_size));
|
PaintLabels(dc, updsamples);
|
||||||
|
|
||||||
std::map<int64_t, int>::iterator pt = style_ranges.upper_bound(updsamples.begin());
|
|
||||||
std::map<int64_t, int>::iterator pe = style_ranges.upper_bound(updsamples.end());
|
|
||||||
|
|
||||||
if (pt != style_ranges.begin())
|
|
||||||
--pt;
|
|
||||||
|
|
||||||
while (pt != pe)
|
|
||||||
{
|
|
||||||
AudioRenderingStyle range_style = static_cast<AudioRenderingStyle>(pt->second);
|
|
||||||
int range_x1 = std::max(updrect.x, RelativeXFromSamples(pt->first));
|
|
||||||
int range_x2 = (++pt == pe) ? updrect.x + updrect.width : RelativeXFromSamples(pt->first);
|
|
||||||
|
|
||||||
if (range_x2 > range_x1)
|
|
||||||
{
|
|
||||||
audio_renderer->Render(dc, wxPoint(range_x1, audio_top), range_x1 + scroll_left, range_x2 - range_x1, range_style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw markers on top of it all
|
|
||||||
AudioMarkerVector markers;
|
|
||||||
controller->GetMarkers(updsamples, markers);
|
|
||||||
wxDCPenChanger pen_retainer(dc, wxPen());
|
|
||||||
wxDCBrushChanger brush_retainer(dc, wxBrush());
|
|
||||||
for (AudioMarkerVector::iterator marker_i = markers.begin(); marker_i != markers.end(); ++marker_i)
|
|
||||||
{
|
|
||||||
const AudioMarker *marker = *marker_i;
|
|
||||||
dc.SetPen(marker->GetStyle());
|
|
||||||
int marker_x = RelativeXFromSamples(marker->GetPosition());
|
|
||||||
dc.DrawLine(marker_x, audio_top, marker_x, audio_top+audio_height);
|
|
||||||
dc.SetBrush(wxBrush(marker->GetStyle().GetColour()));
|
|
||||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
|
||||||
if (marker->GetFeet() & AudioMarker::Feet_Left)
|
|
||||||
{
|
|
||||||
wxPoint foot_top[3] = { wxPoint(-foot_size, 0), wxPoint(0, 0), wxPoint(0, foot_size) };
|
|
||||||
wxPoint foot_bot[3] = { wxPoint(-foot_size, 0), wxPoint(0, -foot_size), wxPoint(0, 0) };
|
|
||||||
dc.DrawPolygon(3, foot_top, marker_x, audio_top);
|
|
||||||
dc.DrawPolygon(3, foot_bot, marker_x, audio_top+audio_height);
|
|
||||||
}
|
|
||||||
if (marker->GetFeet() & AudioMarker::Feet_Right)
|
|
||||||
{
|
|
||||||
wxPoint foot_top[3] = { wxPoint(foot_size, 0), wxPoint(0, 0), wxPoint(0, foot_size) };
|
|
||||||
wxPoint foot_bot[3] = { wxPoint(foot_size, 0), wxPoint(0, -foot_size), wxPoint(0, 0) };
|
|
||||||
dc.DrawPolygon(3, foot_top, marker_x, audio_top);
|
|
||||||
dc.DrawPolygon(3, foot_bot, marker_x, audio_top+audio_height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw labels
|
|
||||||
std::vector<AudioLabelProvider::AudioLabel> labels;
|
|
||||||
controller->GetLabels(updsamples, labels);
|
|
||||||
if (!labels.empty())
|
|
||||||
{
|
|
||||||
wxDCFontChanger fc(dc);
|
|
||||||
wxFont font = dc.GetFont();
|
|
||||||
font.SetWeight(wxFONTWEIGHT_BOLD);
|
|
||||||
dc.SetFont(font);
|
|
||||||
dc.SetTextForeground(*wxWHITE);
|
|
||||||
for (size_t i = 0; i < labels.size(); ++i)
|
|
||||||
{
|
|
||||||
wxSize extent = dc.GetTextExtent(labels[i].text);
|
|
||||||
int left = RelativeXFromSamples(labels[i].range.begin());
|
|
||||||
int width = AbsoluteXFromSamples(labels[i].range.length());
|
|
||||||
|
|
||||||
// If it doesn't fit, truncate
|
|
||||||
if (width < extent.GetWidth())
|
|
||||||
{
|
|
||||||
dc.SetClippingRegion(left, audio_top + 4, width, extent.GetHeight());
|
|
||||||
dc.DrawText(labels[i].text, left, audio_top + 4);
|
|
||||||
dc.DestroyClippingRegion();
|
|
||||||
}
|
|
||||||
// Otherwise center in the range
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc.DrawText(labels[i].text, left + (width - extent.GetWidth()) / 2, audio_top + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track_cursor_pos >= 0)
|
if (track_cursor_pos >= 0)
|
||||||
{
|
{
|
||||||
wxDCPenChanger penchanger(dc, wxPen(*wxWHITE));
|
PaintTrackCursor(dc);
|
||||||
dc.DrawLine(track_cursor_pos-scroll_left, audio_top, track_cursor_pos-scroll_left, audio_top+audio_height);
|
|
||||||
|
|
||||||
if (!track_cursor_label.empty())
|
|
||||||
{
|
|
||||||
wxDCFontChanger fc(dc);
|
|
||||||
wxFont font = dc.GetFont();
|
|
||||||
font.SetWeight(wxFONTWEIGHT_BOLD);
|
|
||||||
dc.SetFont(font);
|
|
||||||
|
|
||||||
wxSize label_size(dc.GetTextExtent(track_cursor_label));
|
|
||||||
wxPoint label_pos(track_cursor_pos - scroll_left - label_size.x/2, audio_top + 2);
|
|
||||||
if (label_pos.x < 2) label_pos.x = 2;
|
|
||||||
if (label_pos.x + label_size.x >= client_width - 2) label_pos.x = client_width - label_size.x - 2;
|
|
||||||
|
|
||||||
int old_bg_mode = dc.GetBackgroundMode();
|
|
||||||
dc.SetBackgroundMode(wxTRANSPARENT);
|
|
||||||
// Draw border
|
|
||||||
dc.SetTextForeground(wxColour(64, 64, 64));
|
|
||||||
dc.DrawText(track_cursor_label, label_pos.x+1, label_pos.y+1);
|
|
||||||
dc.DrawText(track_cursor_label, label_pos.x+1, label_pos.y-1);
|
|
||||||
dc.DrawText(track_cursor_label, label_pos.x-1, label_pos.y+1);
|
|
||||||
dc.DrawText(track_cursor_label, label_pos.x-1, label_pos.y-1);
|
|
||||||
// Draw fill
|
|
||||||
dc.SetTextForeground(*wxWHITE);
|
|
||||||
dc.DrawText(track_cursor_label, label_pos.x, label_pos.y);
|
|
||||||
dc.SetBackgroundMode(old_bg_mode);
|
|
||||||
|
|
||||||
label_pos.x -= 2; label_pos.y -= 2;
|
|
||||||
label_size.IncBy(4, 4);
|
|
||||||
// If the rendered text changes size we have to draw it an extra time to make sure the entire thing was drawn
|
|
||||||
bool need_extra_redraw = track_cursor_label_rect.GetSize() != label_size;
|
|
||||||
track_cursor_label_rect.SetPosition(label_pos);
|
|
||||||
track_cursor_label_rect.SetSize(label_size);
|
|
||||||
if (need_extra_redraw)
|
|
||||||
RefreshRect(track_cursor_label_rect, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redraw_scrollbar)
|
if (redraw_scrollbar)
|
||||||
|
@ -1002,6 +885,135 @@ void AudioDisplay::OnPaint(wxPaintEvent&)
|
||||||
timeline->Paint(dc);
|
timeline->Paint(dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioDisplay::PaintAudio(wxDC &dc, SampleRange updsamples, wxRect updrect)
|
||||||
|
{
|
||||||
|
std::map<int64_t, int>::iterator pt = style_ranges.upper_bound(updsamples.begin());
|
||||||
|
std::map<int64_t, int>::iterator pe = style_ranges.upper_bound(updsamples.end());
|
||||||
|
|
||||||
|
if (pt != style_ranges.begin())
|
||||||
|
--pt;
|
||||||
|
|
||||||
|
while (pt != pe)
|
||||||
|
{
|
||||||
|
AudioRenderingStyle range_style = static_cast<AudioRenderingStyle>(pt->second);
|
||||||
|
int range_x1 = std::max(updrect.x, RelativeXFromSamples(pt->first));
|
||||||
|
int range_x2 = (++pt == pe) ? updrect.x + updrect.width : RelativeXFromSamples(pt->first);
|
||||||
|
|
||||||
|
if (range_x2 > range_x1)
|
||||||
|
{
|
||||||
|
audio_renderer->Render(dc, wxPoint(range_x1, audio_top), range_x1 + scroll_left, range_x2 - range_x1, range_style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDisplay::PaintMarkers(wxDC &dc, SampleRange updsamples)
|
||||||
|
{
|
||||||
|
AudioMarkerVector markers;
|
||||||
|
controller->GetMarkers(updsamples, markers);
|
||||||
|
if (markers.empty()) return;
|
||||||
|
|
||||||
|
wxDCPenChanger pen_retainer(dc, wxPen());
|
||||||
|
wxDCBrushChanger brush_retainer(dc, wxBrush());
|
||||||
|
for (AudioMarkerVector::iterator marker_i = markers.begin(); marker_i != markers.end(); ++marker_i)
|
||||||
|
{
|
||||||
|
const AudioMarker *marker = *marker_i;
|
||||||
|
int marker_x = RelativeXFromSamples(marker->GetPosition());
|
||||||
|
|
||||||
|
dc.SetPen(marker->GetStyle());
|
||||||
|
dc.DrawLine(marker_x, audio_top, marker_x, audio_top+audio_height);
|
||||||
|
|
||||||
|
if (marker->GetFeet() == AudioMarker::Feet_None) continue;
|
||||||
|
|
||||||
|
dc.SetBrush(wxBrush(marker->GetStyle().GetColour()));
|
||||||
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
|
|
||||||
|
if (marker->GetFeet() & AudioMarker::Feet_Left)
|
||||||
|
PaintFoot(dc, marker_x, -1);
|
||||||
|
if (marker->GetFeet() & AudioMarker::Feet_Right)
|
||||||
|
PaintFoot(dc, marker_x, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDisplay::PaintFoot(wxDC &dc, int marker_x, int dir)
|
||||||
|
{
|
||||||
|
wxPoint foot_top[3] = { wxPoint(foot_size * dir, 0), wxPoint(0, 0), wxPoint(0, foot_size) };
|
||||||
|
wxPoint foot_bot[3] = { wxPoint(foot_size * dir, 0), wxPoint(0, -foot_size), wxPoint(0, 0) };
|
||||||
|
dc.DrawPolygon(3, foot_top, marker_x, audio_top);
|
||||||
|
dc.DrawPolygon(3, foot_bot, marker_x, audio_top+audio_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDisplay::PaintLabels(wxDC &dc, SampleRange updsamples)
|
||||||
|
{
|
||||||
|
std::vector<AudioLabelProvider::AudioLabel> labels;
|
||||||
|
controller->GetLabels(updsamples, labels);
|
||||||
|
if (labels.empty()) return;
|
||||||
|
|
||||||
|
wxDCFontChanger fc(dc);
|
||||||
|
wxFont font = dc.GetFont();
|
||||||
|
font.SetWeight(wxFONTWEIGHT_BOLD);
|
||||||
|
dc.SetFont(font);
|
||||||
|
dc.SetTextForeground(*wxWHITE);
|
||||||
|
for (size_t i = 0; i < labels.size(); ++i)
|
||||||
|
{
|
||||||
|
wxSize extent = dc.GetTextExtent(labels[i].text);
|
||||||
|
int left = RelativeXFromSamples(labels[i].range.begin());
|
||||||
|
int width = AbsoluteXFromSamples(labels[i].range.length());
|
||||||
|
|
||||||
|
// If it doesn't fit, truncate
|
||||||
|
if (width < extent.GetWidth())
|
||||||
|
{
|
||||||
|
dc.SetClippingRegion(left, audio_top + 4, width, extent.GetHeight());
|
||||||
|
dc.DrawText(labels[i].text, left, audio_top + 4);
|
||||||
|
dc.DestroyClippingRegion();
|
||||||
|
}
|
||||||
|
// Otherwise center in the range
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc.DrawText(labels[i].text, left + (width - extent.GetWidth()) / 2, audio_top + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioDisplay::PaintTrackCursor(wxDC &dc) {
|
||||||
|
wxDCPenChanger penchanger(dc, wxPen(*wxWHITE));
|
||||||
|
dc.DrawLine(track_cursor_pos-scroll_left, audio_top, track_cursor_pos-scroll_left, audio_top+audio_height);
|
||||||
|
|
||||||
|
if (track_cursor_label.empty()) return;
|
||||||
|
|
||||||
|
wxDCFontChanger fc(dc);
|
||||||
|
wxFont font = dc.GetFont();
|
||||||
|
font.SetWeight(wxFONTWEIGHT_BOLD);
|
||||||
|
dc.SetFont(font);
|
||||||
|
|
||||||
|
wxSize label_size(dc.GetTextExtent(track_cursor_label));
|
||||||
|
wxPoint label_pos(track_cursor_pos - scroll_left - label_size.x/2, audio_top + 2);
|
||||||
|
label_pos.x = mid(2, label_pos.x, GetClientSize().GetWidth() - label_size.x - 2);
|
||||||
|
|
||||||
|
int old_bg_mode = dc.GetBackgroundMode();
|
||||||
|
dc.SetBackgroundMode(wxTRANSPARENT);
|
||||||
|
|
||||||
|
// Draw border
|
||||||
|
dc.SetTextForeground(wxColour(64, 64, 64));
|
||||||
|
dc.DrawText(track_cursor_label, label_pos.x+1, label_pos.y+1);
|
||||||
|
dc.DrawText(track_cursor_label, label_pos.x+1, label_pos.y-1);
|
||||||
|
dc.DrawText(track_cursor_label, label_pos.x-1, label_pos.y+1);
|
||||||
|
dc.DrawText(track_cursor_label, label_pos.x-1, label_pos.y-1);
|
||||||
|
|
||||||
|
// Draw fill
|
||||||
|
dc.SetTextForeground(*wxWHITE);
|
||||||
|
dc.DrawText(track_cursor_label, label_pos.x, label_pos.y);
|
||||||
|
dc.SetBackgroundMode(old_bg_mode);
|
||||||
|
|
||||||
|
label_pos.x -= 2;
|
||||||
|
label_pos.y -= 2;
|
||||||
|
label_size.IncBy(4, 4);
|
||||||
|
// If the rendered text changes size we have to draw it an extra time to make sure the entire thing was drawn
|
||||||
|
bool need_extra_redraw = track_cursor_label_rect.GetSize() != label_size;
|
||||||
|
track_cursor_label_rect.SetPosition(label_pos);
|
||||||
|
track_cursor_label_rect.SetSize(label_size);
|
||||||
|
if (need_extra_redraw)
|
||||||
|
RefreshRect(track_cursor_label_rect, false);
|
||||||
|
}
|
||||||
|
|
||||||
void AudioDisplay::SetDraggedObject(AudioDisplayInteractionObject *new_obj)
|
void AudioDisplay::SetDraggedObject(AudioDisplayInteractionObject *new_obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -184,6 +184,32 @@ class AudioDisplay: public wxWindow {
|
||||||
/// @param sample_end Last sample to repaint
|
/// @param sample_end Last sample to repaint
|
||||||
void Redraw(int64_t sample_start, int64_t sample_end);
|
void Redraw(int64_t sample_start, int64_t sample_end);
|
||||||
|
|
||||||
|
/// Paint the audio data for a range of samples
|
||||||
|
/// @param dc DC to paint to
|
||||||
|
/// @param updsamples Sample range to repaint
|
||||||
|
/// @param updrect Pixel range to repaint
|
||||||
|
void PaintAudio(wxDC &dc, SampleRange updsamples, wxRect updrect);
|
||||||
|
|
||||||
|
/// Paint the markers in a range of samples
|
||||||
|
/// @param dc DC to paint to
|
||||||
|
/// @param updsamples Sample range to repaint
|
||||||
|
void PaintMarkers(wxDC &dc, SampleRange updsamples);
|
||||||
|
|
||||||
|
/// Draw a single foot for a marker
|
||||||
|
/// @param dc DC to paint to
|
||||||
|
/// @param marker_x Position of the marker whose foot is being painted in pixels
|
||||||
|
/// @param dir -1 for left, 1 for right
|
||||||
|
void PaintFoot(wxDC &dc, int marker_x, int dir);
|
||||||
|
|
||||||
|
/// Paint the labels in a range of samples
|
||||||
|
/// @param dc DC to paint to
|
||||||
|
/// @param updsamples Sample range to repaint
|
||||||
|
void PaintLabels(wxDC &dc, SampleRange updsamples);
|
||||||
|
|
||||||
|
/// Paint the track cursor
|
||||||
|
/// @param dc DC to paint to
|
||||||
|
void PaintTrackCursor(wxDC &dc);
|
||||||
|
|
||||||
/// wxWidgets paint event
|
/// wxWidgets paint event
|
||||||
void OnPaint(wxPaintEvent &event);
|
void OnPaint(wxPaintEvent &event);
|
||||||
/// wxWidgets mouse input event
|
/// wxWidgets mouse input event
|
||||||
|
|
Loading…
Reference in a new issue