#include <iomanip>
#include <boost/lexical_cast.hpp>
+#include <boost/bind.hpp>
#include "lib/film.h"
#include "lib/config.h"
#include "properties_dialog.h"
PropertiesDialog::PropertiesDialog (wxWindow* parent, Film* film)
: wxDialog (parent, wxID_ANY, _("Film Properties"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
+ , _film (film)
{
wxFlexGridSizer* table = new wxFlexGridSizer (2, 3, 6);
table->Add (_total_disk, 1, wxALIGN_CENTER_VERTICAL);
add_label_to_sizer (table, this, "Frames already encoded");
- _encoded = new wxStaticText (this, wxID_ANY, std_to_wx (""));
+ _encoded = new ThreadedStaticText (this, "calculating...", boost::bind (&PropertiesDialog::frames_already_encoded, this));
table->Add (_encoded, 1, wxALIGN_CENTER_VERTICAL);
- _frames->SetLabel (std_to_wx (lexical_cast<string> (film->length ())));
- double const disk = ((double) Config::instance()->j2k_bandwidth() / 8) * film->length() / (film->frames_per_second () * 1073741824);
+ _frames->SetLabel (std_to_wx (lexical_cast<string> (_film->length ())));
+ double const disk = ((double) Config::instance()->j2k_bandwidth() / 8) * _film->length() / (_film->frames_per_second () * 1073741824);
stringstream s;
s << fixed << setprecision (1) << disk << "Gb";
_disk_for_frames->SetLabel (std_to_wx (s.str ()));
t << fixed << setprecision (1) << (disk * 2) << "Gb";
_total_disk->SetLabel (std_to_wx (t.str ()));
- stringstream u;
- u << film->encoded_frames();
- if (film->length()) {
- u << " (" << (film->encoded_frames() * 100 / film->length()) << "%)";
- }
- _encoded->SetLabel (std_to_wx (u.str ()));
-
wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
overall_sizer->Add (table, 0, wxALL, 8);
SetSizer (overall_sizer);
overall_sizer->SetSizeHints (this);
}
+
+string
+PropertiesDialog::frames_already_encoded () const
+{
+ stringstream u;
+ u << _film->encoded_frames();
+ if (_film->length()) {
+ u << " (" << (_film->encoded_frames() * 100 / _film->length()) << "%)";
+ }
+ return u.str ();
+}
#include <wx/wx.h>
class Film;
+class ThreadedStaticText;
class PropertiesDialog : public wxDialog
{
PropertiesDialog (wxWindow *, Film *);
private:
+ std::string frames_already_encoded () const;
+
+ Film* _film;
wxStaticText* _frames;
wxStaticText* _disk_for_frames;
wxStaticText* _total_disk;
- wxStaticText* _encoded;
+ ThreadedStaticText* _encoded;
};
*/
/** @file src/wx/wx_util.cc
- * @brief Some utility functions.
+ * @brief Some utility functions and classes.
*/
+#include <boost/thread.hpp>
#include "wx_util.h"
using namespace std;
+using namespace boost;
wxStaticText *
add_label_to_sizer (wxSizer* s, wxWindow* p, string t, int prop)
{
return wxString (s.c_str(), wxConvUTF8);
}
+
+int const ThreadedStaticText::_update_event_id = 10000;
+
+/** @param parent Parent for the wxStaticText.
+ * @param initial Initial text for the wxStaticText while the computation is being run.
+ * @param fn Function which works out what the wxStaticText content should be and returns it.
+ */
+ThreadedStaticText::ThreadedStaticText (wxWindow* parent, string initial, function<string ()> fn)
+ : wxStaticText (parent, wxID_ANY, std_to_wx (initial))
+{
+ Connect (_update_event_id, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ThreadedStaticText::thread_finished), 0, this);
+ thread t (bind (&ThreadedStaticText::run, this, fn));
+}
+
+void
+ThreadedStaticText::run (function<string ()> fn)
+{
+ /* Run the thread and post the result to the GUI thread via AddPendingEvent */
+ wxCommandEvent ev (wxEVT_COMMAND_TEXT_UPDATED, _update_event_id);
+ ev.SetString (std_to_wx (fn ()));
+ GetEventHandler()->AddPendingEvent (ev);
+}
+
+void
+ThreadedStaticText::thread_finished (wxCommandEvent& ev)
+{
+ SetLabel (ev.GetString ());
+}
*/
#include <wx/wx.h>
+#include <boost/function.hpp>
/** @file src/wx/wx_util.h
- * @brief Some utility functions.
+ * @brief Some utility functions and classes.
*/
extern void error_dialog (wxWindow *, std::string);
extern wxStaticText* add_label_to_sizer (wxSizer *, wxWindow *, std::string, int prop = 0);
extern std::string wx_to_std (wxString);
extern wxString std_to_wx (std::string);
+
+/** A wxStaticText whose content is computed in a separate thread, to avoid holding
+ * up the GUI while work is done.
+ */
+class ThreadedStaticText : public wxStaticText
+{
+public:
+ ThreadedStaticText (wxWindow* parent, std::string initial, boost::function<std::string ()> fn);
+
+private:
+ void run (boost::function<std::string ()> fn);
+ void thread_finished (wxCommandEvent& ev);
+
+ static const int _update_event_id;
+};