1 #include "core/subtitles.hpp"
2 #include "core/instance.hpp"
3 #include "core/moviedata.hpp"
5 #include "platform/wxwidgets/platform.hpp"
9 #include <wx/control.h>
10 #include <wx/combobox.h>
11 #include <wx/radiobut.h>
13 #include "library/string.hpp"
14 #include "core/dispatch.hpp"
15 #include "core/subtitles.hpp"
27 class wxeditor_subtitles
: public wxFrame
30 wxeditor_subtitles(wxWindow
* parent
);
31 ~wxeditor_subtitles() throw();
32 bool ShouldPreventAppExit() const;
33 void on_change(wxCommandEvent
& e
);
34 void on_add(wxCommandEvent
& e
);
35 void on_edit(wxCommandEvent
& e
);
36 void on_delete(wxCommandEvent
& e
);
37 void on_close(wxCommandEvent
& e
);
38 void on_wclose(wxCloseEvent
& e
);
48 std::map
<int, subdata
> subtexts
;
49 struct dispatch::target
<> subchange
;
55 class wxeditor_subtitles_subtitle
: public wxDialog
58 wxeditor_subtitles_subtitle(wxWindow
* parent
, subdata d
);
59 void on_change(wxCommandEvent
& e
);
60 void on_cancel(wxCommandEvent
& e
);
61 void on_ok(wxCommandEvent
& e
);
71 wxeditor_subtitles_subtitle::wxeditor_subtitles_subtitle(wxWindow
* parent
, subdata d
)
72 : wxDialog(parent
, wxID_ANY
, wxT("lsnes: Edit subtitle"), wxDefaultPosition
, wxSize(-1, -1))
75 wxFlexGridSizer
* top_s
= new wxFlexGridSizer(2, 1, 0, 0);
78 wxFlexGridSizer
* data_s
= new wxFlexGridSizer(3, 2, 0, 0);
79 data_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("First frame:")));
80 data_s
->Add(first
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(200, -1)));
81 data_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Last frame:")));
82 data_s
->Add(last
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(200, -1)));
83 data_s
->Add(new wxStaticText(this, wxID_ANY
, wxT("Text:")));
84 data_s
->Add(text
= new wxTextCtrl(this, wxID_ANY
, wxT(""), wxDefaultPosition
, wxSize(400, -1)));
85 top_s
->Add(data_s
, 1, wxGROW
);
87 first
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
88 wxCommandEventHandler(wxeditor_subtitles_subtitle::on_change
), NULL
, this);
89 last
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
90 wxCommandEventHandler(wxeditor_subtitles_subtitle::on_change
), NULL
, this);
91 text
->Connect(wxEVT_COMMAND_TEXT_UPDATED
,
92 wxCommandEventHandler(wxeditor_subtitles_subtitle::on_change
), NULL
, this);
94 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
95 pbutton_s
->AddStretchSpacer();
96 pbutton_s
->Add(ok
= new wxButton(this, wxID_ANY
, wxT("OK")), 0, wxGROW
);
97 pbutton_s
->Add(cancel
= new wxButton(this, wxID_ANY
, wxT("Cancel")), 0, wxGROW
);
98 ok
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
, wxCommandEventHandler(wxeditor_subtitles_subtitle::on_ok
),
100 cancel
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
,
101 wxCommandEventHandler(wxeditor_subtitles_subtitle::on_cancel
), NULL
, this);
102 top_s
->Add(pbutton_s
, 0, wxGROW
);
104 pbutton_s
->SetSizeHints(this);
105 top_s
->SetSizeHints(this);
107 first
->SetValue(towxstring((stringfmt() << d
.first
).str()));
108 last
->SetValue(towxstring((stringfmt() << d
.last
).str()));
109 text
->SetValue(towxstring(d
.text
));
113 void wxeditor_subtitles_subtitle::on_change(wxCommandEvent
& e
)
116 std::string _first
= tostdstring(first
->GetValue());
117 std::string _last
= tostdstring(last
->GetValue());
118 std::string _text
= tostdstring(text
->GetValue());
119 valid
= valid
&& regex_match("[0-9]{1,19}", _first
);
120 valid
= valid
&& regex_match("[0-9]{1,19}", _last
);
121 valid
= valid
&& (_text
!= "");
125 void wxeditor_subtitles_subtitle::on_cancel(wxCommandEvent
& e
)
127 EndModal(wxID_CANCEL
);
130 void wxeditor_subtitles_subtitle::on_ok(wxCommandEvent
& e
)
135 subdata
wxeditor_subtitles_subtitle::get_result()
138 d
.first
= parse_value
<uint64_t>(tostdstring(first
->GetValue()));
139 d
.last
= parse_value
<uint64_t>(tostdstring(last
->GetValue()));
140 d
.text
= tostdstring(text
->GetValue());
144 bool edit_subtext(wxWindow
* w
, struct subdata
& d
)
147 wxeditor_subtitles_subtitle
* editor
= NULL
;
149 editor
= new wxeditor_subtitles_subtitle(w
, d
);
150 int ret
= editor
->ShowModal();
152 d
= editor
->get_result();
165 wxeditor_subtitles::wxeditor_subtitles(wxWindow
* parent
)
166 : wxFrame(NULL
, wxID_ANY
, wxT("lsnes: Edit subtitles"), wxDefaultPosition
, wxSize(-1, -1))
170 wxFlexGridSizer
* top_s
= new wxFlexGridSizer(2, 1, 0, 0);
173 //TODO: Apppropriate controls.
174 top_s
->Add(subs
= new wxListBox(this, wxID_ANY
, wxDefaultPosition
, wxSize(300, 400), 0, NULL
,
175 wxLB_SINGLE
), 1, wxGROW
);
176 subs
->Connect(wxEVT_COMMAND_LISTBOX_SELECTED
,
177 wxCommandEventHandler(wxeditor_subtitles::on_change
), NULL
, this);
179 wxBoxSizer
* pbutton_s
= new wxBoxSizer(wxHORIZONTAL
);
180 pbutton_s
->AddStretchSpacer();
181 pbutton_s
->Add(add
= new wxButton(this, wxID_ANY
, wxT("Add")), 0, wxGROW
);
182 pbutton_s
->Add(edit
= new wxButton(this, wxID_ANY
, wxT("Edit")), 0, wxGROW
);
183 pbutton_s
->Add(_delete
= new wxButton(this, wxID_ANY
, wxT("Delete")), 0, wxGROW
);
184 pbutton_s
->Add(close
= new wxButton(this, wxID_ANY
, wxT("Close")), 0, wxGROW
);
185 add
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
, wxCommandEventHandler(wxeditor_subtitles::on_add
), NULL
, this);
186 edit
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
, wxCommandEventHandler(wxeditor_subtitles::on_edit
), NULL
, this);
187 _delete
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
, wxCommandEventHandler(wxeditor_subtitles::on_delete
), NULL
,
189 close
->Connect(wxEVT_COMMAND_BUTTON_CLICKED
, wxCommandEventHandler(wxeditor_subtitles::on_close
), NULL
, this);
190 top_s
->Add(pbutton_s
, 0, wxGROW
);
192 pbutton_s
->SetSizeHints(this);
193 top_s
->SetSizeHints(this);
195 subchange
.set(notify_subtitle_change
, [this]() { runuifun([this]() -> void { this->refresh(); }); });
199 wxeditor_subtitles::~wxeditor_subtitles() throw()
203 bool wxeditor_subtitles::ShouldPreventAppExit() const
208 void wxeditor_subtitles::on_close(wxCommandEvent
& e
)
214 void wxeditor_subtitles::on_wclose(wxCloseEvent
& e
)
219 void wxeditor_subtitles::refresh()
223 std::map
<std::pair
<uint64_t, uint64_t>, std::string
> _subtitles
;
224 lsnes_instance
.iqueue
->run([&_subtitles
]() -> void {
225 auto keys
= CORE().subtitles
->get_all();
227 _subtitles
[i
] = CORE().subtitles
->get(i
.first
, i
.second
);
229 int sel
= subs
->GetSelection();
230 bool found
= (subtexts
.count(sel
) != 0);
231 subdata matching
= subtexts
[sel
];
235 for(auto i
: _subtitles
) {
237 newdata
.first
= i
.first
.first
;
238 newdata
.last
= i
.first
.second
;
239 newdata
.text
= i
.second
;
240 subtexts
[num
++] = newdata
;
241 std::string s
= (stringfmt() << i
.first
.first
<< "-" << i
.first
.second
<< ": " << i
.second
).str();
242 subs
->Append(towxstring(s
));
244 for(size_t i
= 0; i
< subs
->GetCount(); i
++)
245 if(subtexts
[i
].first
== matching
.first
&& subtexts
[i
].last
== matching
.last
)
246 subs
->SetSelection(i
);
247 if(subs
->GetSelection() == wxNOT_FOUND
&& sel
< (ssize_t
)subs
->GetCount())
248 subs
->SetSelection(sel
);
249 sel
= subs
->GetSelection();
250 found
= (subtexts
.count(sel
) != 0);
252 _delete
->Enable(found
);
255 void wxeditor_subtitles::on_change(wxCommandEvent
& e
)
259 int sel
= subs
->GetSelection();
260 bool found
= (subtexts
.count(sel
) != 0);
262 _delete
->Enable(found
);
265 void wxeditor_subtitles::on_add(wxCommandEvent
& e
)
273 if(edit_subtext(this, t
))
274 lsnes_instance
.subtitles
->set(t
.first
, t
.last
, t
.text
);
277 void wxeditor_subtitles::on_edit(wxCommandEvent
& e
)
281 int sel
= subs
->GetSelection();
282 if(!subtexts
.count(sel
))
284 auto t
= subtexts
[sel
];
286 if(edit_subtext(this, t
)) {
287 lsnes_instance
.subtitles
->set(old
.first
, old
.last
, "");
288 lsnes_instance
.subtitles
->set(t
.first
, t
.last
, t
.text
);
292 void wxeditor_subtitles::on_delete(wxCommandEvent
& e
)
296 int sel
= subs
->GetSelection();
297 if(!subtexts
.count(sel
))
299 auto t
= subtexts
[sel
];
300 lsnes_instance
.subtitles
->set(t
.first
, t
.last
, "");
303 void wxeditor_subtitles_display(wxWindow
* parent
)
306 if(!lsnes_instance
.mlogic
) {
307 show_message_ok(parent
, "No movie", "Can't edit authors of nonexistent movie", wxICON_EXCLAMATION
);
311 editor
= new wxeditor_subtitles(parent
);