Add listeners for most non-audio options that need them. Closes #1047.
Originally committed to SVN as r4764.
This commit is contained in:
parent
0704887ad4
commit
0248e7c754
9 changed files with 108 additions and 55 deletions
|
@ -28,18 +28,18 @@ namespace agi {
|
||||||
|
|
||||||
void OptionValue::NotifyChanged() {
|
void OptionValue::NotifyChanged() {
|
||||||
for (ChangeListenerSet::const_iterator nfcb = listeners.begin(); nfcb != listeners.end(); ++nfcb) {
|
for (ChangeListenerSet::const_iterator nfcb = listeners.begin(); nfcb != listeners.end(); ++nfcb) {
|
||||||
(nfcb->first->*(nfcb->second))(*this);
|
nfcb->second(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionValue::Subscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function) {
|
void OptionValue::Subscribe(void *key, ChangeListener listener) {
|
||||||
assert(listeners.find(listener) == listeners.end());
|
assert(listeners.find(key) == listeners.end());
|
||||||
listeners[listener] = function;
|
listeners[key] = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionValue::Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function) {
|
void OptionValue::Unsubscribe(void *key) {
|
||||||
assert(listeners.find(listener) != listeners.end() && listeners[listener] == function);
|
assert(listeners.find(key) != listeners.end());
|
||||||
listeners.erase(listener);
|
listeners.erase(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <functional>
|
||||||
|
#else
|
||||||
|
#include <tr1/functional>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libaegisub/exception.h>
|
#include <libaegisub/exception.h>
|
||||||
|
@ -38,24 +44,16 @@ DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidType, OptionValueError, "
|
||||||
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidListType, OptionValueError, "options/array/invalid_type")
|
DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidListType, OptionValueError, "options/array/invalid_type")
|
||||||
|
|
||||||
|
|
||||||
class OptionValue;
|
|
||||||
class ConfigVisitor;
|
class ConfigVisitor;
|
||||||
|
|
||||||
|
|
||||||
/// @class OptionValueListener
|
|
||||||
/// Inherit from this class to get the proper type for the notification callback
|
|
||||||
/// signature.
|
|
||||||
class OptionValueListener {
|
|
||||||
public:
|
|
||||||
/// @brief Type of a notification callback function for option value changes
|
|
||||||
typedef void (OptionValueListener::*ChangeEvent)(const OptionValue &option);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// @class OptionValue
|
/// @class OptionValue
|
||||||
/// Holds an actual option.
|
/// Holds an actual option.
|
||||||
class OptionValue {
|
class OptionValue {
|
||||||
typedef std::map<OptionValueListener*, OptionValueListener::ChangeEvent> ChangeListenerSet;
|
public:
|
||||||
|
typedef std::tr1::function<void (const OptionValue &)> ChangeListener;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<void*, ChangeListener> ChangeListenerSet;
|
||||||
ChangeListenerSet listeners;
|
ChangeListenerSet listeners;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -131,9 +129,8 @@ public:
|
||||||
virtual void GetDefaultListBool(std::vector<bool> &out) const { throw ListTypeError("string"); }
|
virtual void GetDefaultListBool(std::vector<bool> &out) const { throw ListTypeError("string"); }
|
||||||
|
|
||||||
|
|
||||||
void Subscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function);
|
void Subscribe(void *key, ChangeListener listener);
|
||||||
void Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function);
|
void Unsubscribe(void *key);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONFIG_OPTIONVALUE(type_name, type) \
|
#define CONFIG_OPTIONVALUE(type_name, type) \
|
||||||
|
|
|
@ -30,14 +30,17 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <map>
|
#include <map>
|
||||||
#ifdef _WIN32
|
|
||||||
#include <memory>
|
|
||||||
#else
|
|
||||||
#include <tr1/memory>
|
|
||||||
#endif
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#else
|
||||||
|
#include <tr1/functional>
|
||||||
|
#include <tr1/memory>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __DEPRECATED // Dodge GCC warnings
|
#ifdef __DEPRECATED // Dodge GCC warnings
|
||||||
# undef __DEPRECATED
|
# undef __DEPRECATED
|
||||||
# include <strstream>
|
# include <strstream>
|
||||||
|
|
|
@ -105,6 +105,25 @@ BaseGrid::BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wx
|
||||||
|
|
||||||
// Set style
|
// Set style
|
||||||
UpdateStyle();
|
UpdateStyle();
|
||||||
|
|
||||||
|
agi::OptionValue::ChangeListener UpdateStyle(std::tr1::bind(&BaseGrid::UpdateStyle, this));
|
||||||
|
OPT_GET("Subtitle/Grid/Font Face")->Subscribe(this, UpdateStyle);
|
||||||
|
OPT_GET("Subtitle/Grid/Font Size")->Subscribe(this, UpdateStyle);
|
||||||
|
|
||||||
|
agi::OptionValue::ChangeListener Refresh(std::tr1::bind(&BaseGrid::Refresh, this, false, (wxRect*)NULL));
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Active Border")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Background/Background")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Background/Comment")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Background/Inframe")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Background/Selected Comment")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Background/Selection")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Collision")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Header")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Left Column")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Lines")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Selection")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Colour/Subtitle Grid/Standard")->Subscribe(this, Refresh);
|
||||||
|
OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame")->Subscribe(this, Refresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -180,8 +180,27 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, S
|
||||||
Bind(wxEVT_COMMAND_MENU_SELECTED, function<void (wxCommandEvent &)>(bind(&SubsTextEditCtrl::SelectAll, this)), EDIT_MENU_SELECT_ALL);
|
Bind(wxEVT_COMMAND_MENU_SELECTED, function<void (wxCommandEvent &)>(bind(&SubsTextEditCtrl::SelectAll, this)), EDIT_MENU_SELECT_ALL);
|
||||||
|
|
||||||
Bind(wxEVT_STC_STYLENEEDED, &SubsTextEditCtrl::UpdateCallTip, this);
|
Bind(wxEVT_STC_STYLENEEDED, &SubsTextEditCtrl::UpdateCallTip, this);
|
||||||
|
|
||||||
|
agi::OptionValue::ChangeListener SetStyles = bind(&SubsTextEditCtrl::SetStyles, this);
|
||||||
|
|
||||||
|
OPT_GET("Subtitle/Edit Box/Font Face")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Subtitle/Edit Box/Font Size")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Normal")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Brackets")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Slashes")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Highlight Tags")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Error")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Background/Error")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Parameters")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Line Break")->Subscribe(this, SetStyles);
|
||||||
|
OPT_GET("Colour/Subtitle/Syntax/Karaoke Template")->Subscribe(this, SetStyles);
|
||||||
|
|
||||||
|
OPT_GET("Subtitle/Highlight/Syntax")->Subscribe(this, bind(&SubsTextEditCtrl::UpdateStyle, this, 0, -1));
|
||||||
|
static wxStyledTextEvent evt;
|
||||||
|
OPT_GET("App/Call Tips")->Subscribe(this, bind(&SubsTextEditCtrl::UpdateCallTip, this, ref(evt)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SubsTextEditCtrl::~SubsTextEditCtrl() {
|
SubsTextEditCtrl::~SubsTextEditCtrl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +280,11 @@ void SubsTextEditCtrl::SetStyles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
|
void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
|
||||||
if (OPT_GET("Subtitle/Highlight/Syntax")->GetBool() == 0) return;
|
if (!OPT_GET("Subtitle/Highlight/Syntax")->GetBool()) {
|
||||||
|
StartStyling(0,255);
|
||||||
|
SetUnicodeStyling(start, _length, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if it's a template line
|
// Check if it's a template line
|
||||||
AssDialogue *diag = grid->GetActiveLine();
|
AssDialogue *diag = grid->GetActiveLine();
|
||||||
|
|
|
@ -108,6 +108,17 @@ VideoContext::VideoContext()
|
||||||
{
|
{
|
||||||
Bind(EVT_VIDEO_ERROR, &VideoContext::OnVideoError, this);
|
Bind(EVT_VIDEO_ERROR, &VideoContext::OnVideoError, this);
|
||||||
Bind(EVT_SUBTITLES_ERROR, &VideoContext::OnSubtitlesError, this);
|
Bind(EVT_SUBTITLES_ERROR, &VideoContext::OnSubtitlesError, this);
|
||||||
|
|
||||||
|
agi::OptionValue::ChangeListener providerChanged(std::tr1::bind(&VideoContext::Reload, this));
|
||||||
|
OPT_GET("Subtitle/Provider")->Subscribe(this, providerChanged);
|
||||||
|
OPT_GET("Video/Provider")->Subscribe(this, providerChanged);
|
||||||
|
|
||||||
|
// It would be nice to find a way to move these to the individual providers
|
||||||
|
OPT_GET("Provider/Avisynth/Allow Ancient")->Subscribe(this, providerChanged);
|
||||||
|
OPT_GET("Provider/Avisynth/Memory Max")->Subscribe(this, providerChanged);
|
||||||
|
|
||||||
|
OPT_GET("Provider/Video/FFmpegSource/Decoding Threads")->Subscribe(this, providerChanged);
|
||||||
|
OPT_GET("Provider/Video/FFmpegSource/Unsafe Seeking")->Subscribe(this, providerChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoContext::~VideoContext () {
|
VideoContext::~VideoContext () {
|
||||||
|
@ -115,6 +126,8 @@ VideoContext::~VideoContext () {
|
||||||
delete audio->provider;
|
delete audio->provider;
|
||||||
delete audio->player;
|
delete audio->player;
|
||||||
}
|
}
|
||||||
|
// Don't unsubscribe from option change notifications as the options object
|
||||||
|
// might not even exist anymore
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoContext *VideoContext::Get() {
|
VideoContext *VideoContext::Get() {
|
||||||
|
@ -161,6 +174,7 @@ void VideoContext::SetVideo(const wxString &filename) {
|
||||||
|
|
||||||
provider.reset(new ThreadedFrameSource(filename, this), std::mem_fun(&ThreadedFrameSource::End));
|
provider.reset(new ThreadedFrameSource(filename, this), std::mem_fun(&ThreadedFrameSource::End));
|
||||||
videoProvider = provider->GetVideoProvider();
|
videoProvider = provider->GetVideoProvider();
|
||||||
|
videoFile = filename;
|
||||||
|
|
||||||
keyFrames = videoProvider->GetKeyFrames();
|
keyFrames = videoProvider->GetKeyFrames();
|
||||||
|
|
||||||
|
@ -208,6 +222,14 @@ void VideoContext::SetVideo(const wxString &filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoContext::Reload() {
|
||||||
|
if (IsLoaded()) {
|
||||||
|
int frame = frame_n;
|
||||||
|
SetVideo(videoFile);
|
||||||
|
JumpToFrame(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VideoContext::AddDisplay(VideoDisplay *display) {
|
void VideoContext::AddDisplay(VideoDisplay *display) {
|
||||||
if (std::find(displayList.begin(), displayList.end(), display) == displayList.end())
|
if (std::find(displayList.begin(), displayList.end(), display) == displayList.end())
|
||||||
displayList.push_back(display);
|
displayList.push_back(display);
|
||||||
|
|
|
@ -86,6 +86,9 @@ private:
|
||||||
/// DOCME
|
/// DOCME
|
||||||
std::tr1::shared_ptr<ThreadedFrameSource> provider;
|
std::tr1::shared_ptr<ThreadedFrameSource> provider;
|
||||||
|
|
||||||
|
/// Filename of currently open video
|
||||||
|
wxString videoFile;
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
std::vector<int> keyFrames;
|
std::vector<int> keyFrames;
|
||||||
|
|
||||||
|
@ -218,6 +221,8 @@ public:
|
||||||
void SetVideo(const wxString &filename);
|
void SetVideo(const wxString &filename);
|
||||||
/// @brief Close the video, keyframes and timecodes
|
/// @brief Close the video, keyframes and timecodes
|
||||||
void Reset();
|
void Reset();
|
||||||
|
/// @brief Close and reopen the current video
|
||||||
|
void Reload();
|
||||||
|
|
||||||
/// @brief Jump to the beginning of a frame
|
/// @brief Jump to the beginning of a frame
|
||||||
/// @param n Frame number to jump to
|
/// @param n Frame number to jump to
|
||||||
|
|
|
@ -52,6 +52,11 @@
|
||||||
#include "video_display.h"
|
#include "video_display.h"
|
||||||
#include "video_slider.h"
|
#include "video_slider.h"
|
||||||
|
|
||||||
|
/// IDs
|
||||||
|
enum {
|
||||||
|
NextFrame = 1300,
|
||||||
|
PrevFrame
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Constructor
|
/// @brief Constructor
|
||||||
/// @param parent
|
/// @param parent
|
||||||
|
@ -68,19 +73,13 @@ VideoSlider::VideoSlider (wxWindow* parent, wxWindowID id)
|
||||||
SetMinSize(wxSize(20, 25));
|
SetMinSize(wxSize(20, 25));
|
||||||
locked = false;
|
locked = false;
|
||||||
SetRange(0,1);
|
SetRange(0,1);
|
||||||
|
OPT_GET("Video/Slider/Show Keyframes")->Subscribe(this, std::tr1::bind(&wxWindow::Refresh, this, false, (wxRect*)NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VideoSlider::~VideoSlider() {
|
||||||
|
OPT_GET("Video/Slider/Show Keyframes")->Unsubscribe(this);
|
||||||
/// @brief Get value
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
int VideoSlider::GetValue() {
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Set value
|
/// @brief Set value
|
||||||
/// @param value
|
/// @param value
|
||||||
/// @return
|
/// @return
|
||||||
|
|
|
@ -57,8 +57,6 @@ class SubtitlesGrid;
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class VideoSlider: public wxWindow {
|
class VideoSlider: public wxWindow {
|
||||||
private:
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
|
@ -96,27 +94,14 @@ public:
|
||||||
SubtitlesGrid *grid;
|
SubtitlesGrid *grid;
|
||||||
|
|
||||||
VideoSlider(wxWindow* parent, wxWindowID id);
|
VideoSlider(wxWindow* parent, wxWindowID id);
|
||||||
|
~VideoSlider();
|
||||||
|
|
||||||
void NextFrame();
|
void NextFrame();
|
||||||
void PrevFrame();
|
void PrevFrame();
|
||||||
|
|
||||||
void SetRange(int start,int end);
|
void SetRange(int start,int end);
|
||||||
int GetValue();
|
int GetValue() const { return val; };
|
||||||
void SetValue(int value);
|
void SetValue(int value);
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///////
|
|
||||||
// IDs
|
|
||||||
enum {
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
NextFrame = 1300,
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
PrevFrame
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue