diff --git a/aegisub/libaegisub/common/option_value.cpp b/aegisub/libaegisub/common/option_value.cpp index 535ac2a63..7f5984401 100644 --- a/aegisub/libaegisub/common/option_value.cpp +++ b/aegisub/libaegisub/common/option_value.cpp @@ -28,18 +28,18 @@ namespace agi { void OptionValue::NotifyChanged() { 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) { - assert(listeners.find(listener) == listeners.end()); - listeners[listener] = function; +void OptionValue::Subscribe(void *key, ChangeListener listener) { + assert(listeners.find(key) == listeners.end()); + listeners[key] = listener; } -void OptionValue::Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function) { - assert(listeners.find(listener) != listeners.end() && listeners[listener] == function); - listeners.erase(listener); +void OptionValue::Unsubscribe(void *key) { + assert(listeners.find(key) != listeners.end()); + listeners.erase(key); } } diff --git a/aegisub/libaegisub/include/libaegisub/option_value.h b/aegisub/libaegisub/include/libaegisub/option_value.h index 1403849e8..05fd689cd 100644 --- a/aegisub/libaegisub/include/libaegisub/option_value.h +++ b/aegisub/libaegisub/include/libaegisub/option_value.h @@ -24,6 +24,12 @@ #include #include #include + +#ifdef _WIN32 +#include +#else +#include +#endif #endif #include @@ -38,24 +44,16 @@ DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidType, OptionValueError, " DEFINE_SIMPLE_EXCEPTION_NOINNER(OptionValueErrorInvalidListType, OptionValueError, "options/array/invalid_type") -class OptionValue; 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 /// Holds an actual option. class OptionValue { - typedef std::map ChangeListenerSet; +public: + typedef std::tr1::function ChangeListener; + +private: + typedef std::map ChangeListenerSet; ChangeListenerSet listeners; protected: @@ -131,9 +129,8 @@ public: virtual void GetDefaultListBool(std::vector &out) const { throw ListTypeError("string"); } - void Subscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function); - void Unsubscribe(OptionValueListener *listener, OptionValueListener::ChangeEvent function); - + void Subscribe(void *key, ChangeListener listener); + void Unsubscribe(void *key); }; #define CONFIG_OPTIONVALUE(type_name, type) \ diff --git a/aegisub/libaegisub/lagi_pre.h b/aegisub/libaegisub/lagi_pre.h index beb6e2200..57c1b1c27 100644 --- a/aegisub/libaegisub/lagi_pre.h +++ b/aegisub/libaegisub/lagi_pre.h @@ -30,14 +30,17 @@ #include #include #include -#ifdef _WIN32 -#include -#else -#include -#endif #include #include +#ifdef _WIN32 +#include +#include +#else +#include +#include +#endif + #ifdef __DEPRECATED // Dodge GCC warnings # undef __DEPRECATED # include diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index 80a22036c..65a16a4fc 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -105,6 +105,25 @@ BaseGrid::BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wx // Set style 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); } diff --git a/aegisub/src/subs_edit_ctrl.cpp b/aegisub/src/subs_edit_ctrl.cpp index d111f4d8b..4595549fc 100644 --- a/aegisub/src/subs_edit_ctrl.cpp +++ b/aegisub/src/subs_edit_ctrl.cpp @@ -180,8 +180,27 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, S Bind(wxEVT_COMMAND_MENU_SELECTED, function(bind(&SubsTextEditCtrl::SelectAll, this)), EDIT_MENU_SELECT_ALL); 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() { } @@ -261,7 +280,11 @@ void SubsTextEditCtrl::SetStyles() { } 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 AssDialogue *diag = grid->GetActiveLine(); diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 91f637ff7..17b914dac 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -108,6 +108,17 @@ VideoContext::VideoContext() { Bind(EVT_VIDEO_ERROR, &VideoContext::OnVideoError, 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 () { @@ -115,6 +126,8 @@ VideoContext::~VideoContext () { delete audio->provider; delete audio->player; } + // Don't unsubscribe from option change notifications as the options object + // might not even exist anymore } VideoContext *VideoContext::Get() { @@ -161,6 +174,7 @@ void VideoContext::SetVideo(const wxString &filename) { provider.reset(new ThreadedFrameSource(filename, this), std::mem_fun(&ThreadedFrameSource::End)); videoProvider = provider->GetVideoProvider(); + videoFile = filename; 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) { if (std::find(displayList.begin(), displayList.end(), display) == displayList.end()) displayList.push_back(display); diff --git a/aegisub/src/video_context.h b/aegisub/src/video_context.h index 9093f1949..ba9ac70eb 100644 --- a/aegisub/src/video_context.h +++ b/aegisub/src/video_context.h @@ -86,6 +86,9 @@ private: /// DOCME std::tr1::shared_ptr provider; + /// Filename of currently open video + wxString videoFile; + /// DOCME std::vector keyFrames; @@ -218,6 +221,8 @@ public: void SetVideo(const wxString &filename); /// @brief Close the video, keyframes and timecodes void Reset(); + /// @brief Close and reopen the current video + void Reload(); /// @brief Jump to the beginning of a frame /// @param n Frame number to jump to diff --git a/aegisub/src/video_slider.cpp b/aegisub/src/video_slider.cpp index 3e45bb845..3cfe50164 100644 --- a/aegisub/src/video_slider.cpp +++ b/aegisub/src/video_slider.cpp @@ -52,6 +52,11 @@ #include "video_display.h" #include "video_slider.h" +/// IDs +enum { + NextFrame = 1300, + PrevFrame +}; /// @brief Constructor /// @param parent @@ -68,19 +73,13 @@ VideoSlider::VideoSlider (wxWindow* parent, wxWindowID id) SetMinSize(wxSize(20, 25)); locked = false; SetRange(0,1); + OPT_GET("Video/Slider/Show Keyframes")->Subscribe(this, std::tr1::bind(&wxWindow::Refresh, this, false, (wxRect*)NULL)); } - - -/// @brief Get value -/// @return -/// -int VideoSlider::GetValue() { - return val; +VideoSlider::~VideoSlider() { + OPT_GET("Video/Slider/Show Keyframes")->Unsubscribe(this); } - - /// @brief Set value /// @param value /// @return diff --git a/aegisub/src/video_slider.h b/aegisub/src/video_slider.h index e4cb59ce6..83138c8c6 100644 --- a/aegisub/src/video_slider.h +++ b/aegisub/src/video_slider.h @@ -57,8 +57,6 @@ class SubtitlesGrid; /// /// DOCME class VideoSlider: public wxWindow { -private: - /// DOCME int val; @@ -96,27 +94,14 @@ public: SubtitlesGrid *grid; VideoSlider(wxWindow* parent, wxWindowID id); + ~VideoSlider(); void NextFrame(); void PrevFrame(); void SetRange(int start,int end); - int GetValue(); + int GetValue() const { return val; }; void SetValue(int value); DECLARE_EVENT_TABLE() }; - - -/////// -// IDs -enum { - - /// DOCME - NextFrame = 1300, - - /// DOCME - PrevFrame -}; - -