forked from mia/Aegisub
Fix crash when trying to seek to keyframes via the video slider with no keyframes loaded, and use wxAutoBufferedPaintDC rather than manual double-buffering
Originally committed to SVN as r6432.
This commit is contained in:
parent
b8a7c6cb1e
commit
6717334c12
2 changed files with 19 additions and 43 deletions
|
@ -37,6 +37,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
|
#include <wx/dcbuffer.h>
|
||||||
#include <wx/settings.h>
|
#include <wx/settings.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -56,6 +57,8 @@ VideoSlider::VideoSlider (wxWindow* parent, agi::Context *c)
|
||||||
{
|
{
|
||||||
SetClientSize(20,25);
|
SetClientSize(20,25);
|
||||||
SetMinSize(wxSize(20, 25));
|
SetMinSize(wxSize(20, 25));
|
||||||
|
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||||
|
|
||||||
slots.push_back(OPT_SUB("Video/Slider/Show Keyframes", &wxWindow::Refresh, this, false, (wxRect*)NULL));
|
slots.push_back(OPT_SUB("Video/Slider/Show Keyframes", &wxWindow::Refresh, this, false, (wxRect*)NULL));
|
||||||
slots.push_back(c->videoController->AddSeekListener(&VideoSlider::SetValue, this));
|
slots.push_back(c->videoController->AddSeekListener(&VideoSlider::SetValue, this));
|
||||||
slots.push_back(c->videoController->AddVideoOpenListener(&VideoSlider::VideoOpened, this));
|
slots.push_back(c->videoController->AddVideoOpenListener(&VideoSlider::VideoOpened, this));
|
||||||
|
@ -86,9 +89,7 @@ void VideoSlider::KeyframesChanged(std::vector<int> const& newKeyframes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoSlider::GetValueAtX(int x) {
|
int VideoSlider::GetValueAtX(int x) {
|
||||||
int w,h;
|
int w = GetClientSize().GetWidth();
|
||||||
GetClientSize(&w,&h);
|
|
||||||
|
|
||||||
// Special case
|
// Special case
|
||||||
if (w <= 10) return 0;
|
if (w <= 10) return 0;
|
||||||
|
|
||||||
|
@ -98,8 +99,7 @@ int VideoSlider::GetValueAtX(int x) {
|
||||||
int VideoSlider::GetXAtValue(int value) {
|
int VideoSlider::GetXAtValue(int value) {
|
||||||
if (max <= 0) return 0;
|
if (max <= 0) return 0;
|
||||||
|
|
||||||
int w,h;
|
int w = GetClientSize().GetWidth();
|
||||||
GetClientSize(&w,&h);
|
|
||||||
return (int64_t)value*(int64_t)(w-10)/(int64_t)max+5;
|
return (int64_t)value*(int64_t)(w-10)/(int64_t)max+5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,23 +109,24 @@ BEGIN_EVENT_TABLE(VideoSlider, wxWindow)
|
||||||
EVT_PAINT(VideoSlider::OnPaint)
|
EVT_PAINT(VideoSlider::OnPaint)
|
||||||
EVT_SET_FOCUS(VideoSlider::OnFocus)
|
EVT_SET_FOCUS(VideoSlider::OnFocus)
|
||||||
EVT_KILL_FOCUS(VideoSlider::OnFocus)
|
EVT_KILL_FOCUS(VideoSlider::OnFocus)
|
||||||
EVT_ERASE_BACKGROUND(VideoSlider::OnEraseBackground)
|
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
void VideoSlider::OnMouse(wxMouseEvent &event) {
|
void VideoSlider::OnMouse(wxMouseEvent &event) {
|
||||||
|
bool had_focus = HasFocus();
|
||||||
|
if (event.ButtonDown())
|
||||||
|
SetFocus();
|
||||||
|
|
||||||
if (event.LeftIsDown()) {
|
if (event.LeftIsDown()) {
|
||||||
int x = event.GetX();
|
int x = event.GetX();
|
||||||
|
|
||||||
// If the slider didn't already have focus, don't seek if the user
|
// If the slider didn't already have focus, don't seek if the user
|
||||||
// clicked very close to the current location as they were probably
|
// clicked very close to the current location as they were probably
|
||||||
// just trying to focus the slider
|
// just trying to focus the slider
|
||||||
if (wxWindow::FindFocus() != this && abs(x - GetXAtValue(val)) < 4) {
|
if (!had_focus && abs(x - GetXAtValue(val)) < 4)
|
||||||
SetFocus();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Shift click to snap to keyframe
|
// Shift click to snap to keyframe
|
||||||
if (event.ShiftDown()) {
|
if (event.ShiftDown() && keyframes.size()) {
|
||||||
int clickedFrame = GetValueAtX(x);
|
int clickedFrame = GetValueAtX(x);
|
||||||
std::vector<int>::const_iterator pos = lower_bound(keyframes.begin(), keyframes.end(), clickedFrame);
|
std::vector<int>::const_iterator pos = lower_bound(keyframes.begin(), keyframes.end(), clickedFrame);
|
||||||
if (pos == keyframes.end())
|
if (pos == keyframes.end())
|
||||||
|
@ -136,7 +137,6 @@ void VideoSlider::OnMouse(wxMouseEvent &event) {
|
||||||
if (*pos == val) return;
|
if (*pos == val) return;
|
||||||
SetValue(*pos);
|
SetValue(*pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal click
|
// Normal click
|
||||||
else {
|
else {
|
||||||
int go = GetValueAtX(x);
|
int go = GetValueAtX(x);
|
||||||
|
@ -145,10 +145,7 @@ void VideoSlider::OnMouse(wxMouseEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
c->videoController->JumpToFrame(val);
|
c->videoController->JumpToFrame(val);
|
||||||
SetFocus();
|
|
||||||
}
|
}
|
||||||
else if (event.ButtonDown())
|
|
||||||
SetFocus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoSlider::OnKeyDown(wxKeyEvent &event) {
|
void VideoSlider::OnKeyDown(wxKeyEvent &event) {
|
||||||
|
@ -165,18 +162,9 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoSlider::OnPaint(wxPaintEvent &) {
|
void VideoSlider::OnPaint(wxPaintEvent &) {
|
||||||
wxPaintDC dc(this);
|
wxAutoBufferedPaintDC dc(this);
|
||||||
DrawImage(dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoSlider::DrawImage(wxDC &destdc) {
|
|
||||||
int w,h;
|
int w,h;
|
||||||
GetClientSize(&w,&h);
|
GetClientSize(&w, &h);
|
||||||
|
|
||||||
// Back buffer
|
|
||||||
wxMemoryDC dc;
|
|
||||||
wxBitmap bmp(w,h);
|
|
||||||
dc.SelectObject(bmp);
|
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
wxColour shad = wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW);
|
wxColour shad = wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW);
|
||||||
|
@ -193,8 +181,7 @@ void VideoSlider::DrawImage(wxDC &destdc) {
|
||||||
dc.DrawRectangle(0,0,w,h);
|
dc.DrawRectangle(0,0,w,h);
|
||||||
|
|
||||||
// Selection border
|
// Selection border
|
||||||
bool selected = wxWindow::FindFocus() == this;
|
if (HasFocus()) {
|
||||||
if (selected) {
|
|
||||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||||
dc.SetPen(wxPen(shad,1,wxDOT));
|
dc.SetPen(wxPen(shad,1,wxDOT));
|
||||||
dc.DrawRectangle(0,0,w,h);
|
dc.DrawRectangle(0,0,w,h);
|
||||||
|
@ -253,12 +240,8 @@ void VideoSlider::DrawImage(wxDC &destdc) {
|
||||||
|
|
||||||
// Draw selection
|
// Draw selection
|
||||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
if (selected) dc.SetBrush(wxBrush(sel));
|
dc.SetBrush(HasFocus() ? wxBrush(sel) : wxBrush(notSel));
|
||||||
else dc.SetBrush(wxBrush(notSel));
|
|
||||||
dc.DrawRectangle(curX-3,y2+1,7,4);
|
dc.DrawRectangle(curX-3,y2+1,7,4);
|
||||||
|
|
||||||
// Draw final
|
|
||||||
destdc.Blit(0,0,w,h,&dc,0,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoSlider::OnFocus(wxFocusEvent &) {
|
void VideoSlider::OnFocus(wxFocusEvent &) {
|
||||||
|
|
|
@ -45,15 +45,11 @@
|
||||||
namespace agi { struct Context; }
|
namespace agi { struct Context; }
|
||||||
|
|
||||||
class VideoContext;
|
class VideoContext;
|
||||||
class SubtitlesGrid;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
/// @class VideoSlider
|
/// @class VideoSlider
|
||||||
/// @brief DOCME
|
/// @brief Slider for displaying and adjusting the video position
|
||||||
///
|
|
||||||
/// DOCME
|
|
||||||
class VideoSlider: public wxWindow {
|
class VideoSlider: public wxWindow {
|
||||||
agi::Context *c;
|
agi::Context *c; ///< Associated project context
|
||||||
std::vector<int> keyframes; ///< Currently loaded keyframes
|
std::vector<int> keyframes; ///< Currently loaded keyframes
|
||||||
std::vector<agi::signal::Connection> slots;
|
std::vector<agi::signal::Connection> slots;
|
||||||
|
|
||||||
|
@ -64,8 +60,6 @@ class VideoSlider: public wxWindow {
|
||||||
int GetValueAtX(int x);
|
int GetValueAtX(int x);
|
||||||
/// Get the x-coordinate for a frame number
|
/// Get the x-coordinate for a frame number
|
||||||
int GetXAtValue(int value);
|
int GetXAtValue(int value);
|
||||||
/// Render the slider
|
|
||||||
void DrawImage(wxDC &dc);
|
|
||||||
/// Set the position of the slider
|
/// Set the position of the slider
|
||||||
void SetValue(int value);
|
void SetValue(int value);
|
||||||
|
|
||||||
|
@ -76,9 +70,8 @@ class VideoSlider: public wxWindow {
|
||||||
|
|
||||||
void OnMouse(wxMouseEvent &event);
|
void OnMouse(wxMouseEvent &event);
|
||||||
void OnKeyDown(wxKeyEvent &event);
|
void OnKeyDown(wxKeyEvent &event);
|
||||||
void OnPaint(wxPaintEvent &event);
|
void OnPaint(wxPaintEvent &);
|
||||||
void OnFocus(wxFocusEvent &event);
|
void OnFocus(wxFocusEvent &);
|
||||||
void OnEraseBackground(wxEraseEvent &) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VideoSlider(wxWindow* parent, agi::Context *c);
|
VideoSlider(wxWindow* parent, agi::Context *c);
|
||||||
|
|
Loading…
Reference in a new issue