Add listeners for most non-audio options that need them. Closes #1047.

Originally committed to SVN as r4764.
This commit is contained in:
Thomas Goyne 2010-08-26 18:38:37 +00:00
parent 0704887ad4
commit 0248e7c754
9 changed files with 108 additions and 55 deletions

View file

@ -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);
} }
} }

View file

@ -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) \

View file

@ -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>

View file

@ -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);
} }

View file

@ -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();

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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
};