Esempio n. 1
0
DialogAttachments::DialogAttachments(wxWindow *parent, AssFile *ass)
: wxDialog(parent,-1,_("Attachment List"),wxDefaultPosition,wxDefaultSize,wxDEFAULT_DIALOG_STYLE)
, ass(ass)
{
	SetIcon(GETICON(attach_button_16));

	listView = new wxListView(this,ATTACHMENT_LIST,wxDefaultPosition,wxSize(500,200));
	UpdateList();

	// Buttons
	extractButton = new wxButton(this,BUTTON_EXTRACT,_("E&xtract"));
	deleteButton = new wxButton(this,BUTTON_DELETE,_("&Delete"));
	extractButton->Enable(false);
	deleteButton->Enable(false);

	// Buttons sizer
	wxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
	buttonSizer->Add(new wxButton(this,BUTTON_ATTACH_FONT,_("Attach &Font")),1,0,0);
	buttonSizer->Add(new wxButton(this,BUTTON_ATTACH_GRAPHICS,_("Attach &Graphics")),1,0,0);
	buttonSizer->Add(extractButton,1,0,0);
	buttonSizer->Add(deleteButton,1,0,0);
	buttonSizer->Add(new HelpButton(this,"Attachment Manager"),1,wxLEFT,5);
	buttonSizer->Add(new wxButton(this,wxID_CANCEL,_("&Close")),1,0,0);

	// Main sizer
	wxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
	mainSizer->Add(listView,1,wxTOP | wxLEFT | wxRIGHT | wxEXPAND,5);
	mainSizer->Add(buttonSizer,0,wxALL | wxEXPAND,5);
	SetSizerAndFit(mainSizer);
	CenterOnParent();
}
Esempio n. 2
0
DialogDummyVideo::DialogDummyVideo(wxWindow *parent)
: wxDialog(parent, -1, _("Dummy video options"))
, fps(OPT_GET("Video/Dummy/FPS")->GetDouble())
, width(OPT_GET("Video/Dummy/Last/Width")->GetInt())
, height(OPT_GET("Video/Dummy/Last/Height")->GetInt())
, length(OPT_GET("Video/Dummy/Last/Length")->GetInt())
, color(OPT_GET("Colour/Video Dummy/Last Colour")->GetColor())
, pattern(OPT_GET("Video/Dummy/Pattern")->GetBool())
{
	SetIcon(GETICON(use_dummy_video_menu_16));

	auto res_sizer = new wxBoxSizer(wxHORIZONTAL);
	res_sizer->Add(spin_ctrl(this, 1, 10000, &width), wxSizerFlags(1).Expand());
	res_sizer->Add(new wxStaticText(this, -1, " x "), wxSizerFlags().Center());
	res_sizer->Add(spin_ctrl(this, 1, 10000, &height), wxSizerFlags(1).Expand());

	auto color_sizer = new wxBoxSizer(wxHORIZONTAL);
	auto color_btn = new ColourButton(this, wxSize(30, 17), false, color);
	color_sizer->Add(color_btn, wxSizerFlags().DoubleBorder(wxRIGHT));
	color_sizer->Add(new wxCheckBox(this, -1, _("Checkerboard &pattern"), wxDefaultPosition, wxDefaultSize, 0, wxGenericValidator(&pattern)), wxSizerFlags(1).Center());

	sizer = new wxFlexGridSizer(2, 5, 5);
	AddCtrl(_("Video resolution:"), resolution_shortcuts(this, width, height));
	AddCtrl("", res_sizer);
	AddCtrl(_("Color:"), color_sizer);
	AddCtrl(_("Frame rate (fps):"), spin_ctrl(this, .1, 1000.0, &fps));
	AddCtrl(_("Duration (frames):"), spin_ctrl(this, 2, 36000000, &length)); // Ten hours of 1k FPS
	AddCtrl("", length_display = new wxStaticText(this, -1, ""));

	wxStdDialogButtonSizer *btn_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP);
	btn_sizer->GetHelpButton()->Bind(wxEVT_BUTTON, std::bind(&HelpButton::OpenPage, "Dummy Video"));

	auto main_sizer = new wxBoxSizer(wxVERTICAL);
	main_sizer->Add(sizer, wxSizerFlags(1).Border().Expand());
	main_sizer->Add(new wxStaticLine(this, wxHORIZONTAL), wxSizerFlags().HorzBorder().Expand());
	main_sizer->Add(btn_sizer, wxSizerFlags().Expand().Border());

	UpdateLengthDisplay();

	SetSizerAndFit(main_sizer);
	CenterOnParent();

	Bind(wxEVT_COMBOBOX, &DialogDummyVideo::OnResolutionShortcut, this);
	color_btn->Bind(EVT_COLOR, [=](wxThreadEvent& e) { color = color_btn->GetColor(); });
	Bind(wxEVT_SPINCTRL, [=](wxCommandEvent&) {
		TransferDataFromWindow();
		UpdateLengthDisplay();
	});
}
Esempio n. 3
0
DialogAttachments::DialogAttachments(wxWindow *parent, AssFile *ass)
: wxDialog(parent, -1, _("Attachment List"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
, ass(ass)
{
	SetIcon(GETICON(attach_button_16));

	listView = new wxListView(this, -1, wxDefaultPosition, wxSize(500, 200));
	UpdateList();

	auto attachFont = new wxButton(this, -1, _("Attach &Font"));
	auto attachGraphics = new wxButton(this, -1, _("Attach &Graphics"));
	extractButton = new wxButton(this, -1, _("E&xtract"));
	deleteButton = new wxButton(this, -1, _("&Delete"));
	extractButton->Enable(false);
	deleteButton->Enable(false);

	auto buttonSizer = new wxBoxSizer(wxHORIZONTAL);
	buttonSizer->Add(attachFont, 1);
	buttonSizer->Add(attachGraphics, 1);
	buttonSizer->Add(extractButton, 1);
	buttonSizer->Add(deleteButton, 1);
	buttonSizer->Add(new HelpButton(this, "Attachment Manager"), 1, wxLEFT, 5);
	buttonSizer->Add(new wxButton(this, wxID_CANCEL, _("&Close")), 1);

	auto mainSizer = new wxBoxSizer(wxVERTICAL);
	mainSizer->Add(listView, 1, wxTOP | wxLEFT | wxRIGHT | wxEXPAND, 5);
	mainSizer->Add(buttonSizer, 0, wxALL | wxEXPAND, 5);
	SetSizerAndFit(mainSizer);
	CenterOnParent();

	attachFont->Bind(wxEVT_BUTTON, &DialogAttachments::OnAttachFont, this);
	attachGraphics->Bind(wxEVT_BUTTON, &DialogAttachments::OnAttachGraphics, this);
	extractButton->Bind(wxEVT_BUTTON, &DialogAttachments::OnExtract, this);
	deleteButton->Bind(wxEVT_BUTTON, &DialogAttachments::OnDelete, this);

	listView->Bind(wxEVT_LIST_ITEM_SELECTED, &DialogAttachments::OnListClick, this);
	listView->Bind(wxEVT_LIST_ITEM_DESELECTED, &DialogAttachments::OnListClick, this);
	listView->Bind(wxEVT_LIST_ITEM_FOCUSED, &DialogAttachments::OnListClick, this);
}
Esempio n. 4
0
DialogJumpTo::DialogJumpTo(agi::Context *c)
: wxDialog(c->parent, -1, _("Jump to"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS)
, c(c)
, jumpframe(c->videoController->GetFrameN())
{
	SetIcon(GETICON(jumpto_button_16));

	auto LabelFrame = new wxStaticText(this, -1, _("Frame: "));
	auto LabelTime = new wxStaticText(this, -1, _("Time: "));

	JumpFrame = new wxTextCtrl(this,-1,"",wxDefaultPosition,wxSize(-1,-1),wxTE_PROCESS_ENTER, IntValidator((int)jumpframe));
	JumpFrame->SetMaxLength(std::to_string(c->videoController->GetLength() - 1).size());
	JumpTime = new TimeEdit(this, -1, c, AssTime(c->videoController->TimeAtFrame(jumpframe)).GetAssFormated(), wxSize(-1,-1));

	auto TimesSizer = new wxGridSizer(2, 5, 5);

	TimesSizer->Add(LabelFrame, 1, wxALIGN_CENTER_VERTICAL);
	TimesSizer->Add(JumpFrame, wxEXPAND);

	TimesSizer->Add(LabelTime, 1, wxALIGN_CENTER_VERTICAL);
	TimesSizer->Add(JumpTime, wxEXPAND);

	auto ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);

	// General layout
	auto MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(TimesSizer, 0, wxALL | wxALIGN_CENTER, 5);
	MainSizer->Add(ButtonSizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 5);
	SetSizerAndFit(MainSizer);
	CenterOnParent();

	Bind(wxEVT_INIT_DIALOG, &DialogJumpTo::OnInitDialog, this);
	Bind(wxEVT_TEXT_ENTER, &DialogJumpTo::OnOK, this);
	Bind(wxEVT_BUTTON, &DialogJumpTo::OnOK, this, wxID_OK);
	JumpTime->Bind(wxEVT_TEXT, &DialogJumpTo::OnEditTime, this);
	JumpFrame->Bind(wxEVT_TEXT, &DialogJumpTo::OnEditFrame, this);
}
DialogStyling::DialogStyling(agi::Context *context)
: wxDialog(context->parent, -1, _("Styling Assistant"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX)
, c(context)
, active_line_connection(context->selectionController->AddActiveLineListener(&DialogStyling::OnActiveLineChanged, this))
, active_line(0)
{
	SetIcon(GETICON(styling_toolbutton_16));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
	wxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL);

	{
		wxSizer *cur_line_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Current line"));
		current_line_text = new wxTextCtrl(this, -1, _("Current line"), wxDefaultPosition, wxSize(300, 60), wxTE_MULTILINE | wxTE_READONLY);
		cur_line_box->Add(current_line_text, 1, wxEXPAND, 0);
		main_sizer->Add(cur_line_box, 0, wxEXPAND | wxALL, 5);
	}

	{
		wxSizer *styles_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Styles available"));
		style_list = new wxListBox(this, -1, wxDefaultPosition, wxSize(150, 180), context->ass->GetStyles());
		styles_box->Add(style_list, 1, wxEXPAND, 0);
		bottom_sizer->Add(styles_box, 1, wxEXPAND | wxRIGHT, 5);
	}

	wxSizer *right_sizer = new wxBoxSizer(wxVERTICAL);
	{
		wxSizer *style_text_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Set style"));
		style_name = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxSize(180, -1), wxTE_PROCESS_ENTER);
		style_text_box->Add(style_name, 1, wxEXPAND);
		right_sizer->Add(style_text_box, 0, wxEXPAND | wxBOTTOM, 5);
	}

	{
		wxSizer *hotkey_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Keys"));

		wxSizer *hotkey_grid = new wxGridSizer(2, 0, 5);
		add_hotkey(hotkey_grid, this, "tool/styling_assistant/commit", _("Accept changes"));
		add_hotkey(hotkey_grid, this, "tool/styling_assistant/preview", _("Preview changes"));
		add_hotkey(hotkey_grid, this, "grid/line/prev", _("Previous line"));
		add_hotkey(hotkey_grid, this, "grid/line/next", _("Next line"));
		add_hotkey(hotkey_grid, this, "video/play/line", _("Play video"));
		add_hotkey(hotkey_grid, this, "audio/play/selection", _("Play audio"));
		hotkey_grid->Add(new wxStaticText(this, -1, _("Click on list")));
		hotkey_grid->Add(new wxStaticText(this, -1, _("Select style")));

		hotkey_box->Add(hotkey_grid, 0, wxEXPAND | wxBOTTOM, 5);

		auto_seek = new wxCheckBox(this, -1, _("&Seek video to line start time"));
		auto_seek->SetValue(true);
		hotkey_box->Add(auto_seek, 0, 0, 0);
		hotkey_box->AddStretchSpacer(1);

		right_sizer->Add(hotkey_box, 0, wxEXPAND | wxBOTTOM, 5);
	}

	{
		wxSizer *actions_box = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Actions"));
		actions_box->AddStretchSpacer(1);

		play_audio = new wxButton(this, -1, _("Play &Audio"));
		play_audio->Enable(c->audioController->IsAudioOpen());
		actions_box->Add(play_audio, 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);

		play_video = new wxButton(this, -1, _("Play &Video"));
		play_video->Enable(c->videoController->IsLoaded());
		actions_box->Add(play_video, 0, wxBOTTOM | wxRIGHT, 5);

		actions_box->AddStretchSpacer(1);
		right_sizer->Add(actions_box, 0, wxEXPAND, 5);
	}
	bottom_sizer->Add(right_sizer);
	main_sizer->Add(bottom_sizer, 1, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 5);

	{
		wxStdDialogButtonSizer *button_sizer = new wxStdDialogButtonSizer;
		button_sizer->AddButton(new wxButton(this, wxID_CANCEL));
		button_sizer->AddButton(new HelpButton(this, "Styling Assistant"));
		button_sizer->Realize();

		main_sizer->Add(button_sizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 5);
	}

	SetSizerAndFit(main_sizer);

	persist.reset(new PersistLocation(this, "Tool/Styling Assistant"));

	Bind(wxEVT_ACTIVATE, &DialogStyling::OnActivate, this);
	Bind(wxEVT_CHAR_HOOK, &DialogStyling::OnCharHook, this);
	style_name->Bind(wxEVT_CHAR_HOOK, &DialogStyling::OnCharHook, this);
	style_name->Bind(wxEVT_KEY_DOWN, &DialogStyling::OnKeyDown, this);
	play_video->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayVideoButton, this);
	play_audio->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyling::OnPlayAudioButton, this);
	style_list->Bind(wxEVT_COMMAND_LISTBOX_SELECTED, &DialogStyling::OnListClicked, this);
	style_list->Bind(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, &DialogStyling::OnListDoubleClicked, this);
	style_name->Bind(wxEVT_COMMAND_TEXT_UPDATED, &DialogStyling::OnStyleBoxModified, this);

	OnActiveLineChanged(c->selectionController->GetActiveLine());
}
Esempio n. 6
0
DialogShiftTimes::DialogShiftTimes(agi::Context *context)
: wxDialog(context->parent, -1, _("Shift Times"))
, context(context)
, history_filename(config::path->Decode("?user/shift_history.json"))
, history(agi::util::make_unique<json::Array>())
, timecodes_loaded_slot(context->videoController->AddTimecodesListener(&DialogShiftTimes::OnTimecodesLoaded, this))
, selected_set_changed_slot(context->selectionController->AddSelectionListener(&DialogShiftTimes::OnSelectedSetChanged, this))
{
	SetIcon(GETICON(shift_times_toolbutton_16));

	// Create controls
	shift_by_time = new wxRadioButton(this, -1, _("&Time: "), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	shift_by_time->SetToolTip(_("Shift by time"));
	shift_by_time->Bind(wxEVT_RADIOBUTTON, &DialogShiftTimes::OnByTime, this);

	shift_by_frames = new wxRadioButton(this, -1 , _("&Frames: "));
	shift_by_frames->SetToolTip(_("Shift by frames"));
	shift_by_frames->Bind(wxEVT_RADIOBUTTON, &DialogShiftTimes::OnByFrames, this);

	shift_time = new TimeEdit(this, -1, context);
	shift_time->SetToolTip(_("Enter time in h:mm:ss.cs notation"));

	shift_frames = new wxTextCtrl(this, -1);
	shift_frames->SetToolTip(_("Enter number of frames to shift by"));

	shift_forward = new wxRadioButton(this, -1, _("For&ward"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	shift_forward->SetToolTip(_("Shifts subs forward, making them appear later. Use if they are appearing too soon."));

	shift_backward = new wxRadioButton(this, -1, _("&Backward"));
	shift_backward->SetToolTip(_("Shifts subs backward, making them appear earlier. Use if they are appearing too late."));

	wxString selection_mode_vals[] = { _("&All rows"), _("Selected &rows"), _("Selection &onward") };
	selection_mode = new wxRadioBox(this, -1, _("Affect"), wxDefaultPosition, wxDefaultSize, 3, selection_mode_vals, 1);

	wxString time_field_vals[] = { _("Start a&nd End times"), _("&Start times only"), _("&End times only") };
	time_fields = new wxRadioBox(this, -1, _("Times"), wxDefaultPosition, wxDefaultSize, 3, time_field_vals, 1);

	history_box = new wxListBox(this, -1, wxDefaultPosition, wxSize(350, 100), 0, nullptr, wxLB_HSCROLL);

	wxButton *clear_button = new wxButton(this, -1, _("&Clear"));
	clear_button->Bind(wxEVT_BUTTON, &DialogShiftTimes::OnClear, this);

	// Set initial control states
	OnTimecodesLoaded(context->videoController->FPS());
	OnSelectedSetChanged();
	LoadHistory();

	shift_time->SetTime(OPT_GET("Tool/Shift Times/Time")->GetInt());
	*shift_frames << (int)OPT_GET("Tool/Shift Times/Frames")->GetInt();
	shift_by_frames->SetValue(!OPT_GET("Tool/Shift Times/ByTime")->GetBool() && shift_by_frames->IsEnabled());
	time_fields->SetSelection(OPT_GET("Tool/Shift Times/Type")->GetInt());
	selection_mode->SetSelection(OPT_GET("Tool/Shift Times/Affect")->GetInt());
	shift_backward->SetValue(OPT_GET("Tool/Shift Times/Direction")->GetBool());

	if (shift_by_frames->GetValue())
		shift_time->Disable();
	else
		shift_frames->Disable();


	// Position controls
	wxSizer *shift_amount_sizer = new wxFlexGridSizer(2, 2, 5, 5);
	shift_amount_sizer->Add(shift_by_time, wxSizerFlags(0).Align(wxALIGN_CENTER_VERTICAL));
	shift_amount_sizer->Add(shift_time, wxSizerFlags(1));
	shift_amount_sizer->Add(shift_by_frames, wxSizerFlags(0).Align(wxALIGN_CENTER_VERTICAL));
	shift_amount_sizer->Add(shift_frames, wxSizerFlags(1));

	wxSizer *shift_direction_sizer = new wxBoxSizer(wxHORIZONTAL);
	shift_direction_sizer->Add(shift_forward, wxSizerFlags(1).Expand());
	shift_direction_sizer->Add(shift_backward, wxSizerFlags(1).Expand().Border(wxLEFT));

	wxSizer *shift_by_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Shift by"));
	shift_by_sizer->Add(shift_amount_sizer, wxSizerFlags().Expand());
	shift_by_sizer->Add(shift_direction_sizer, wxSizerFlags().Expand().Border(wxTOP));

	wxSizer *left_sizer = new wxBoxSizer(wxVERTICAL);
	left_sizer->Add(shift_by_sizer, wxSizerFlags().Expand().Border(wxBOTTOM));
	left_sizer->Add(selection_mode, wxSizerFlags().Expand().Border(wxBOTTOM));
	left_sizer->Add(time_fields, wxSizerFlags().Expand());

	wxSizer *history_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Load from history"));
	history_sizer->Add(history_box, wxSizerFlags(1).Expand());
	history_sizer->Add(clear_button, wxSizerFlags().Expand().Border(wxTOP));

	wxSizer *top_sizer = new wxBoxSizer(wxHORIZONTAL);
	top_sizer->Add(left_sizer, wxSizerFlags().Border(wxALL & ~wxRIGHT).Expand());
	top_sizer->Add(history_sizer, wxSizerFlags().Border().Expand());

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
	main_sizer->Add(top_sizer, wxSizerFlags().Border(wxALL & ~wxBOTTOM));
	main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL | wxHELP), wxSizerFlags().Right().Border());
	SetSizerAndFit(main_sizer);
	CenterOnParent();

	Bind(wxEVT_BUTTON, &DialogShiftTimes::Process, this, wxID_OK);
	Bind(wxEVT_BUTTON, std::bind(&HelpButton::OpenPage, "Shift Times"), wxID_HELP);
	shift_time->Bind(wxEVT_TEXT_ENTER, &DialogShiftTimes::Process, this);
	history_box->Bind(wxEVT_LISTBOX_DCLICK, &DialogShiftTimes::OnHistoryClick, this);
}
Esempio n. 7
0
DialogProperties::DialogProperties(agi::Context *c)
: wxDialog(c->parent, -1, _("Script Properties"))
, c(c)
{
	SetIcon(GETICON(properties_toolbutton_16));

	// Script details crap
	wxSizer *TopSizer = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Script"));
	wxFlexGridSizer *TopSizerGrid = new wxFlexGridSizer(0,2,5,5);

	AddProperty(TopSizerGrid, _("Title:"), "Title");
	AddProperty(TopSizerGrid, _("Original script:"), "Original Script");
	AddProperty(TopSizerGrid, _("Translation:"), "Original Translation");
	AddProperty(TopSizerGrid, _("Editing:"), "Original Editing");
	AddProperty(TopSizerGrid, _("Timing:"), "Original Timing");
	AddProperty(TopSizerGrid, _("Synch point:"), "Synch Point");
	AddProperty(TopSizerGrid, _("Updated by:"), "Script Updated By");
	AddProperty(TopSizerGrid, _("Update details:"), "Update Details");

	TopSizerGrid->AddGrowableCol(1,1);
	TopSizer->Add(TopSizerGrid,1,wxALL | wxEXPAND,0);

	// Resolution box
	wxSizer *ResSizer = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Resolution"));
	ResX = new wxTextCtrl(this,-1,"",wxDefaultPosition,wxSize(50,20),0,NumValidator(c->ass->GetScriptInfo("PlayResX")));
	ResY = new wxTextCtrl(this,-1,"",wxDefaultPosition,wxSize(50,20),0,NumValidator(c->ass->GetScriptInfo("PlayResY")));
	wxStaticText *ResText = new wxStaticText(this,-1,"x");

	wxButton *FromVideo = new wxButton(this,-1,_("From &video"));
	if (!c->videoController->IsLoaded())
		FromVideo->Enable(false);
	else
		FromVideo->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogProperties::OnSetFromVideo, this);

	ResSizer->Add(ResX,1,wxRIGHT | wxALIGN_CENTER_VERTICAL,5);
	ResSizer->Add(ResText,0,wxALIGN_CENTER | wxRIGHT,5);
	ResSizer->Add(ResY,1,wxRIGHT | wxALIGN_CENTER_VERTICAL,5);
	ResSizer->Add(FromVideo,1,0,0);

	// Options
	wxSizer *optionsBox = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Options"));
	wxFlexGridSizer *optionsGrid = new wxFlexGridSizer(3,2,5,5);
	wxString wrap_opts[] = {
		_("0: Smart wrapping, top line is wider"),
		_("1: End-of-line word wrapping, only \\N breaks"),
		_("2: No word wrapping, both \\n and \\N break"),
		_("3: Smart wrapping, bottom line is wider")
	};
	WrapStyle = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 4, wrap_opts, wxCB_READONLY);
	WrapStyle->SetSelection(c->ass->GetScriptInfoAsInt("WrapStyle"));
	optionsGrid->Add(new wxStaticText(this,-1,_("Wrap Style: ")),0,wxALIGN_CENTER_VERTICAL,0);
	optionsGrid->Add(WrapStyle,1,wxEXPAND,0);

	wxString coll_opts[] = { _("Normal"), _("Reverse") };
	collision = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 2, coll_opts, wxCB_READONLY);
	collision->SetSelection(c->ass->GetScriptInfo("Collisions").Lower() == "reverse");
	optionsGrid->Add(new wxStaticText(this,-1,_("Collision: ")),0,wxALIGN_CENTER_VERTICAL,0);
	optionsGrid->Add(collision,1,wxEXPAND,0);

	ScaleBorder = new wxCheckBox(this,-1,_("Scale Border and Shadow"));
	ScaleBorder->SetToolTip(_("Scale border and shadow together with script/render resolution. If this is unchecked, relative border and shadow size will depend on renderer."));
	ScaleBorder->SetValue(c->ass->GetScriptInfo("ScaledBorderAndShadow").Lower() == "yes");
	optionsGrid->AddSpacer(0);
	optionsGrid->Add(ScaleBorder,1,wxEXPAND,0);
	optionsGrid->AddGrowableCol(1,1);
	optionsBox->Add(optionsGrid,1,wxEXPAND,0);

	// Button sizer
	wxStdDialogButtonSizer *ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogProperties::OnOK, this, wxID_OK);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&HelpButton::OpenPage, "Properties"), wxID_HELP);

	// MainSizer
	wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(TopSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
	MainSizer->Add(ResSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
	MainSizer->Add(optionsBox,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);
	MainSizer->Add(ButtonSizer,0,wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND,5);

	SetSizerAndFit(MainSizer);
	CenterOnParent();
}
Esempio n. 8
0
DialogSelection::DialogSelection(agi::Context *c) :
wxDialog (c->parent, -1, _("Select"), wxDefaultPosition, wxDefaultSize, wxCAPTION)
, con(c)
{
	SetIcon(GETICON(select_lines_button_16));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);

	wxSizerFlags main_flags = wxSizerFlags().Expand().Border();

	wxRadioButton *select_matching_lines = nullptr;
	{
		wxSizer *match_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Match"));
		{
			wxSizerFlags radio_flags = wxSizerFlags().Border(wxLEFT | wxRIGHT);
			wxSizer *match_radio_line = new wxBoxSizer(wxHORIZONTAL);
			match_radio_line->Add(select_matching_lines = new wxRadioButton(this, -1, _("&Matches"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP), radio_flags);
			match_radio_line->Add(select_unmatching_lines = new wxRadioButton(this, -1, _("&Doesn't Match")), radio_flags);
			match_radio_line->Add(case_sensitive = new wxCheckBox(this, -1, _("Match c&ase")), radio_flags);
			match_sizer->Add(match_radio_line);
		}
		match_sizer->Add(match_text = new wxTextCtrl(this, -1, to_wx(OPT_GET("Tool/Select Lines/Text")->GetString())), main_flags);

		main_sizer->Add(match_sizer, main_flags);
	}

	{
		wxString modes[] = { _("&Exact match"), _("&Contains"), _("&Regular Expression match") };
		main_sizer->Add(match_mode = new wxRadioBox(this, -1, _("Mode"), wxDefaultPosition, wxDefaultSize, 3, modes, 1), main_flags);
	}

	{
		wxString fields[] = { _("&Text"), _("&Style"), _("Act&or"), _("E&ffect") };
		main_sizer->Add(dialogue_field = new wxRadioBox(this, -1, _("In Field"), wxDefaultPosition, wxDefaultSize, 4, fields), main_flags);
	}

	{
		wxSizer *comment_sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Match dialogues/comments"));
		comment_sizer->Add(apply_to_dialogue = new wxCheckBox(this, -1, _("D&ialogues")), wxSizerFlags().Border());
		comment_sizer->Add(apply_to_comments = new wxCheckBox(this, -1, _("Comme&nts")), wxSizerFlags().Border());
		main_sizer->Add(comment_sizer, main_flags);
	}

	{
		wxString actions[] = { _("Set se&lection"), _("&Add to selection"), _("S&ubtract from selection"), _("Intersect &with selection") };
		main_sizer->Add(selection_change_type = new wxRadioBox(this, -1, _("Action"), wxDefaultPosition, wxDefaultSize, 4, actions, 1), main_flags);
	}

	main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL | wxHELP), main_flags);

	SetSizerAndFit(main_sizer);
	CenterOnParent();

	dialogue_field->SetSelection(OPT_GET("Tool/Select Lines/Field")->GetInt());
	selection_change_type->SetSelection(OPT_GET("Tool/Select Lines/Action")->GetInt());
	case_sensitive->SetValue(OPT_GET("Tool/Select Lines/Match/Case")->GetBool());
	apply_to_dialogue->SetValue(OPT_GET("Tool/Select Lines/Match/Dialogue")->GetBool());
	apply_to_comments->SetValue(OPT_GET("Tool/Select Lines/Match/Comment")->GetBool());
	select_unmatching_lines->SetValue(!!OPT_GET("Tool/Select Lines/Condition")->GetInt());
	select_matching_lines->SetValue(!select_unmatching_lines->GetValue());
	match_mode->SetSelection(OPT_GET("Tool/Select Lines/Mode")->GetInt());

	Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSelection::Process, this, wxID_OK);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&HelpButton::OpenPage, "Select Lines"), wxID_HELP);
	apply_to_comments->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, std::bind(&DialogSelection::OnDialogueCheckbox, this, apply_to_dialogue));
	apply_to_dialogue->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, std::bind(&DialogSelection::OnDialogueCheckbox, this, apply_to_comments));
}
Esempio n. 9
0
DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Context *c, AssStyleStorage *store, std::string const& new_name, wxArrayString const& font_list)
: wxDialog (parent, -1, _("Style Editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, c(c)
, style(style)
, store(store)
{
	if (new_name.size()) {
		is_new = true;
		style = this->style = new AssStyle(*style);
		style->name = new_name;
	}
	else if (!style) {
		is_new = true;
		style = this->style = new AssStyle;
	}

	work = agi::make_unique<AssStyle>(*style);

	SetIcon(GETICON(style_toolbutton_16));

	auto add_with_label = [&](wxSizer *sizer, wxString const& label, wxWindow *ctrl) {
		sizer->Add(new wxStaticText(this, -1, label), wxSizerFlags().Center().Right().Border(wxLEFT | wxRIGHT));
		sizer->Add(ctrl, wxSizerFlags(1).Left().Expand());
	};

	auto spin_ctrl = [&](float value, int max_value) {
		return new wxSpinCtrl(this, -1, wxString::Format("%g", value), wxDefaultPosition, wxSize(60, -1), wxSP_ARROW_KEYS, 0, max_value, value);
	};

	auto num_text_ctrl = [&](double *value, double min, double max, double step) -> wxSpinCtrlDouble * {
		auto scd = new wxSpinCtrlDouble(this, -1, "", wxDefaultPosition,
			wxSize(75, -1), wxSP_ARROW_KEYS, min, max, *value, step);
		scd->SetValidator(DoubleSpinValidator(value));
		scd->Bind(wxEVT_SPINCTRLDOUBLE, [=](wxSpinDoubleEvent &evt) {
			evt.Skip();
			if (updating) return;

			bool old = updating;
			updating = true;
			scd->GetValidator()->TransferFromWindow();
			updating = old;
			SubsPreview->SetStyle(*work);
		});
		return scd;
	};

	// Prepare control values
	wxString EncodingValue = std::to_wstring(style->encoding);
	wxString alignValues[9] = { "7", "8", "9", "4", "5", "6", "1", "2", "3" };

	// Encoding options
	wxArrayString encodingStrings;
	AssStyle::GetEncodings(encodingStrings);

	// Create sizers
	wxSizer *NameSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Style Name"));
	wxSizer *FontSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Font"));
	wxSizer *ColorsSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Colors"));
	wxSizer *MarginSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Margins"));
	wxSizer *OutlineBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Outline"));
	wxSizer *MiscBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Miscellaneous"));
	wxSizer *PreviewBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Preview"));

	// Create controls
	StyleName = new wxTextCtrl(this, -1, to_wx(style->name));
	FontName = new wxComboBox(this, -1, to_wx(style->font), wxDefaultPosition, wxSize(150, -1), 0, nullptr, wxCB_DROPDOWN);
	auto FontSize = num_text_ctrl(&work->fontsize, 0, 10000.0, 1.0);
	BoxBold = new wxCheckBox(this, -1, _("&Bold"));
	BoxItalic = new wxCheckBox(this, -1, _("&Italic"));
	BoxUnderline = new wxCheckBox(this, -1, _("&Underline"));
	BoxStrikeout = new wxCheckBox(this, -1, _("&Strikeout"));
	ColourButton *colorButton[] = {
		new ColourButton(this, wxSize(55, 16), true, style->primary, ColorValidator(&work->primary)),
		new ColourButton(this, wxSize(55, 16), true, style->secondary, ColorValidator(&work->secondary)),
		new ColourButton(this, wxSize(55, 16), true, style->outline, ColorValidator(&work->outline)),
		new ColourButton(this, wxSize(55, 16), true, style->shadow, ColorValidator(&work->shadow))
	};
	for (int i = 0; i < 3; i++)
		margin[i] = spin_ctrl(style->Margin[i], 9999);
	Alignment = new wxRadioBox(this, -1, _("Alignment"), wxDefaultPosition, wxDefaultSize, 9, alignValues, 3, wxRA_SPECIFY_COLS);
	auto Outline = num_text_ctrl(&work->outline_w, 0.0, 1000.0, 0.1);
	auto Shadow = num_text_ctrl(&work->shadow_w, 0.0, 1000.0, 0.1);
	OutlineType = new wxCheckBox(this, -1, _("&Opaque box"));
	auto ScaleX = num_text_ctrl(&work->scalex, 0.0, 10000.0, 1.0);
	auto ScaleY = num_text_ctrl(&work->scaley, 0.0, 10000.0, 1.0);
	auto Angle = num_text_ctrl(&work->angle, -180.0, 180.0, 1.0);
	auto Spacing = num_text_ctrl(&work->spacing, 0.0, 1000.0, 0.1);
	Encoding = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, encodingStrings, wxCB_READONLY);

	// Set control tooltips
	StyleName->SetToolTip(_("Style name"));
	FontName->SetToolTip(_("Font face"));
	FontSize->SetToolTip(_("Font size"));
	colorButton[0]->SetToolTip(_("Choose primary color"));
	colorButton[1]->SetToolTip(_("Choose secondary color"));
	colorButton[2]->SetToolTip(_("Choose outline color"));
	colorButton[3]->SetToolTip(_("Choose shadow color"));
	margin[0]->SetToolTip(_("Distance from left edge, in pixels"));
	margin[1]->SetToolTip(_("Distance from right edge, in pixels"));
	margin[2]->SetToolTip(_("Distance from top/bottom edge, in pixels"));
	OutlineType->SetToolTip(_("When selected, display an opaque box behind the subtitles instead of an outline around the text"));
	Outline->SetToolTip(_("Outline width, in pixels"));
	Shadow->SetToolTip(_("Shadow distance, in pixels"));
	ScaleX->SetToolTip(_("Scale X, in percentage"));
	ScaleY->SetToolTip(_("Scale Y, in percentage"));
	Angle->SetToolTip(_("Angle to rotate in Z axis, in degrees"));
	Encoding->SetToolTip(_("Encoding, only useful in unicode if the font doesn't have the proper unicode mapping"));
	Spacing->SetToolTip(_("Character spacing, in pixels"));
	Alignment->SetToolTip(_("Alignment in screen, in numpad style"));

	// Set up controls
	BoxBold->SetValue(style->bold);
	BoxItalic->SetValue(style->italic);
	BoxUnderline->SetValue(style->underline);
	BoxStrikeout->SetValue(style->strikeout);
	OutlineType->SetValue(style->borderstyle == 3);
	Alignment->SetSelection(AlignToControl(style->alignment));
	// Fill font face list box
	FontName->Freeze();
	FontName->Append(font_list);
	FontName->SetValue(to_wx(style->font));
	FontName->Thaw();

	// Set encoding value
	bool found = false;
	for (size_t i=0;i<encodingStrings.Count();i++) {
		if (encodingStrings[i].StartsWith(EncodingValue)) {
			Encoding->Select(i);
			found = true;
			break;
		}
	}
	if (!found) Encoding->Select(0);

	// Style name sizer
	NameSizer->Add(StyleName, 1, wxALL, 0);

	// Font sizer
	wxSizer *FontSizerTop = new wxBoxSizer(wxHORIZONTAL);
	wxSizer *FontSizerBottom = new wxBoxSizer(wxHORIZONTAL);
	FontSizerTop->Add(FontName, 1, wxALL, 0);
	FontSizerTop->Add(FontSize, 0, wxLEFT, 5);
	FontSizerBottom->AddStretchSpacer(1);
	FontSizerBottom->Add(BoxBold, 0, 0, 0);
	FontSizerBottom->Add(BoxItalic, 0, wxLEFT, 5);
	FontSizerBottom->Add(BoxUnderline, 0, wxLEFT, 5);
	FontSizerBottom->Add(BoxStrikeout, 0, wxLEFT, 5);
	FontSizerBottom->AddStretchSpacer(1);
	FontSizer->Add(FontSizerTop, 1, wxALL | wxEXPAND, 0);
	FontSizer->Add(FontSizerBottom, 1, wxTOP | wxEXPAND, 5);

	// Colors sizer
	wxString colorLabels[] = { _("Primary"), _("Secondary"), _("Outline"), _("Shadow") };
	ColorsSizer->AddStretchSpacer(1);
	for (int i = 0; i < 4; ++i) {
		auto sizer = new wxBoxSizer(wxVERTICAL);
		sizer->Add(new wxStaticText(this, -1, colorLabels[i]), 0, wxBOTTOM | wxALIGN_CENTER, 5);
		sizer->Add(colorButton[i], 0, wxBOTTOM | wxALIGN_CENTER, 5);
		ColorsSizer->Add(sizer, 0, wxLEFT, i?5:0);
	}
	ColorsSizer->AddStretchSpacer(1);

	// Margins
	wxString marginLabels[] = { _("Left"), _("Right"), _("Vert") };
	MarginSizer->AddStretchSpacer(1);
	for (int i=0;i<3;i++) {
		auto sizer = new wxBoxSizer(wxVERTICAL);
		sizer->AddStretchSpacer(1);
		sizer->Add(new wxStaticText(this, -1, marginLabels[i]), 0, wxCENTER, 0);
		sizer->Add(margin[i], 0, wxTOP | wxCENTER, 5);
		sizer->AddStretchSpacer(1);
		MarginSizer->Add(sizer, 0, wxEXPAND | wxLEFT, i?5:0);
	}
	MarginSizer->AddStretchSpacer(1);

	// Margins+Alignment
	wxSizer *MarginAlign = new wxBoxSizer(wxHORIZONTAL);
	MarginAlign->Add(MarginSizer, 1, wxLEFT | wxEXPAND, 0);
	MarginAlign->Add(Alignment, 0, wxLEFT | wxEXPAND, 5);

	// Outline
	add_with_label(OutlineBox, _("Outline:"), Outline);
	add_with_label(OutlineBox, _("Shadow:"), Shadow);
	OutlineBox->Add(OutlineType, 0, wxLEFT | wxALIGN_CENTER, 5);

	// Misc
	auto MiscBoxTop = new wxFlexGridSizer(2, 4, 5, 5);
	add_with_label(MiscBoxTop, _("Scale X%:"), ScaleX);
	add_with_label(MiscBoxTop, _("Scale Y%:"), ScaleY);
	add_with_label(MiscBoxTop, _("Rotation:"), Angle);
	add_with_label(MiscBoxTop, _("Spacing:"), Spacing);

	wxSizer *MiscBoxBottom = new wxBoxSizer(wxHORIZONTAL);
	add_with_label(MiscBoxBottom, _("Encoding:"), Encoding);

	MiscBox->Add(MiscBoxTop, wxSizerFlags().Expand().Center());
	MiscBox->Add(MiscBoxBottom, wxSizerFlags().Expand().Center().Border(wxTOP));

	// Preview
	auto previewButton = new ColourButton(this, wxSize(45, 16), false, OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());
	PreviewText = new wxTextCtrl(this, -1, to_wx(OPT_GET("Tool/Style Editor/Preview Text")->GetString()));
	SubsPreview = new SubtitlesPreview(this, wxSize(100, 60), wxSUNKEN_BORDER, OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());

	SubsPreview->SetToolTip(_("Preview of current style"));
	SubsPreview->SetStyle(*style);
	SubsPreview->SetText(from_wx(PreviewText->GetValue()));
	PreviewText->SetToolTip(_("Text to be used for the preview"));
	previewButton->SetToolTip(_("Color of preview background"));

	wxSizer *PreviewBottomSizer = new wxBoxSizer(wxHORIZONTAL);
	PreviewBottomSizer->Add(PreviewText, 1, wxEXPAND | wxRIGHT, 5);
	PreviewBottomSizer->Add(previewButton, 0, wxEXPAND, 0);
	PreviewBox->Add(SubsPreview, 1, wxEXPAND | wxBOTTOM, 5);
	PreviewBox->Add(PreviewBottomSizer, 0, wxEXPAND | wxBOTTOM, 0);

	// Buttons
	auto ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxAPPLY | wxHELP);

	// Left side sizer
	wxSizer *LeftSizer = new wxBoxSizer(wxVERTICAL);
	LeftSizer->Add(NameSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(FontSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(ColorsSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(MarginAlign, 0, wxBOTTOM | wxEXPAND, 0);

	// Right side sizer
	wxSizer *RightSizer = new wxBoxSizer(wxVERTICAL);
	RightSizer->Add(OutlineBox, wxSizerFlags().Expand().Border(wxBOTTOM));
	RightSizer->Add(MiscBox, wxSizerFlags().Expand().Border(wxBOTTOM));
	RightSizer->Add(PreviewBox, wxSizerFlags(1).Expand());

	// Controls Sizer
	wxSizer *ControlSizer = new wxBoxSizer(wxHORIZONTAL);
	ControlSizer->Add(LeftSizer, 0, wxEXPAND, 0);
	ControlSizer->Add(RightSizer, 1, wxLEFT | wxEXPAND, 5);

	// General Layout
	wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(ControlSizer, 1, wxALL | wxALIGN_CENTER | wxEXPAND, 5);
	MainSizer->Add(ButtonSizer, 0, wxBOTTOM | wxEXPAND, 5);

	SetSizerAndFit(MainSizer);

	// Force the style name text field to scroll based on its final size, rather
	// than its initial size
	StyleName->SetInsertionPoint(0);
	StyleName->SetInsertionPoint(-1);

	persist = agi::make_unique<PersistLocation>(this, "Tool/Style Editor", true);

	Bind(wxEVT_CHILD_FOCUS, &DialogStyleEditor::OnChildFocus, this);

	Bind(wxEVT_CHECKBOX, &DialogStyleEditor::OnCommandPreviewUpdate, this);
	Bind(wxEVT_COMBOBOX, &DialogStyleEditor::OnCommandPreviewUpdate, this);
	Bind(wxEVT_SPINCTRL, &DialogStyleEditor::OnCommandPreviewUpdate, this);

	previewButton->Bind(EVT_COLOR, &DialogStyleEditor::OnPreviewColourChange, this);
	FontName->Bind(wxEVT_TEXT_ENTER, &DialogStyleEditor::OnCommandPreviewUpdate, this);
	PreviewText->Bind(wxEVT_TEXT, &DialogStyleEditor::OnPreviewTextChange, this);

	Bind(wxEVT_BUTTON, std::bind(&DialogStyleEditor::Apply, this, true, true), wxID_OK);
	Bind(wxEVT_BUTTON, std::bind(&DialogStyleEditor::Apply, this, true, false), wxID_APPLY);
	Bind(wxEVT_BUTTON, std::bind(&DialogStyleEditor::Apply, this, false, true), wxID_CANCEL);
	Bind(wxEVT_BUTTON, std::bind(&HelpButton::OpenPage, "Style Editor"), wxID_HELP);

	for (auto const& elem : colorButton)
		elem->Bind(EVT_COLOR, &DialogStyleEditor::OnSetColor, this);
}
Esempio n. 10
0
DialogTranslation::DialogTranslation(agi::Context *c)
: wxDialog(c->parent, -1, _("Translation Assistant"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX)
, c(c)
, file_change_connection(c->ass->AddCommitListener(&DialogTranslation::OnExternalCommit, this))
, active_line_connection(c->selectionController->AddActiveLineListener(&DialogTranslation::OnActiveLineChanged, this))
, active_line(c->selectionController->GetActiveLine())
, line_count(count_if(c->ass->Line.begin(), c->ass->Line.end(), cast<AssDialogue*>()))
, line_number(count_if(c->ass->Line.begin(), c->ass->Line.iterator_to(*active_line), cast<AssDialogue*>()) + 1)
{
	SetIcon(GETICON(translation_toolbutton_16));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);

	wxSizer *translation_sizer = new wxBoxSizer(wxVERTICAL);
	{
		wxSizer *original_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Original"));

		line_number_display = new wxStaticText(this, -1, "");
		original_box->Add(line_number_display, 0, wxBOTTOM, 5);

		original_text = new ScintillaTextCtrl(this, -1, "", wxDefaultPosition, wxSize(320, 80));
		original_text->SetWrapMode(wxSTC_WRAP_WORD);
		original_text->SetMarginWidth(1, 0);
		original_text->StyleSetForeground(1, wxColour(10, 60, 200));
		original_text->SetReadOnly(true);
		original_box->Add(original_text, 1, wxEXPAND, 0);

		translation_sizer->Add(original_box, 1, wxEXPAND, 0);
	}

	{
		translated_text = new SubsTextEditCtrl(this, wxSize(320, 80), 0, nullptr);
		translated_text->SetWrapMode(wxSTC_WRAP_WORD);
		translated_text->SetMarginWidth(1, 0);
		translated_text->SetFocus();
		translated_text->Bind(wxEVT_CHAR_HOOK, &DialogTranslation::OnKeyDown, this);

		wxSizer *translated_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Translation"));
		translated_box->Add(translated_text, 1, wxEXPAND, 0);
		translation_sizer->Add(translated_box, 1, wxTOP|wxEXPAND, 5);
	}
	main_sizer->Add(translation_sizer, 1, wxALL | wxEXPAND, 5);

	wxSizer *right_box = new wxBoxSizer(wxHORIZONTAL);
	{
		wxSizer *hotkey_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Keys"));

		wxSizer *hotkey_grid = new wxGridSizer(2, 0, 5);
		add_hotkey(hotkey_grid, this, "tool/translation_assistant/commit", _("Accept changes"));
		add_hotkey(hotkey_grid, this, "tool/translation_assistant/preview", _("Preview changes"));
		add_hotkey(hotkey_grid, this, "tool/translation_assistant/prev", _("Previous line"));
		add_hotkey(hotkey_grid, this, "tool/translation_assistant/next", _("Next line"));
		add_hotkey(hotkey_grid, this, "tool/translation_assistant/insert_original", _("Insert original"));
		add_hotkey(hotkey_grid, this, "video/play/line", _("Play video"));
		add_hotkey(hotkey_grid, this, "audio/play/selection", _("Play audio"));
		add_hotkey(hotkey_grid, this, "edit/line/delete", _("Delete line"));
		hotkey_box->Add(hotkey_grid, 0, wxEXPAND, 0);

		seek_video = new wxCheckBox(this, -1, _("Enable &preview"));
		seek_video->SetValue(true);
		hotkey_box->Add(seek_video, 0, wxTOP, 5);

		right_box->Add(hotkey_box, 1, wxRIGHT | wxEXPAND, 5);
	}

	{
		wxStaticBoxSizer *actions_box = new wxStaticBoxSizer(wxVERTICAL, this, _("Actions"));

		wxButton *play_audio = new wxButton(this, -1, _("Play &Audio"));
		play_audio->Enable(c->audioController->IsAudioOpen());
		play_audio->Bind(wxEVT_BUTTON, &DialogTranslation::OnPlayAudioButton, this);
		actions_box->Add(play_audio, 0, wxALL, 5);

		wxButton *play_video = new wxButton(this, -1, _("Play &Video"));
		play_video->Enable(c->videoController->IsLoaded());
		play_video->Bind(wxEVT_BUTTON, &DialogTranslation::OnPlayVideoButton, this);
		actions_box->Add(play_video, 0, wxLEFT | wxRIGHT | wxBOTTOM, 5);

		right_box->Add(actions_box, 0);
	}
	main_sizer->Add(right_box, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);

	{
		auto standard_buttons = new wxStdDialogButtonSizer();
		standard_buttons->AddButton(new wxButton(this, wxID_CANCEL));
		standard_buttons->AddButton(new HelpButton(this, "Translation Assistant"));
		standard_buttons->Realize();
		main_sizer->Add(standard_buttons, 0, wxALIGN_RIGHT | wxLEFT | wxBOTTOM | wxRIGHT, 5);
	}

	SetSizerAndFit(main_sizer);

	persist = agi::util::make_unique<PersistLocation>(this, "Tool/Translation Assistant");

	Bind(wxEVT_KEY_DOWN, &DialogTranslation::OnKeyDown, this);

	blocks = active_line->ParseTags();
	if (bad_block(blocks[0])) {
		if (!NextBlock())
			throw NothingToTranslate(from_wx(_("There is nothing to translate in the file.")));
	}
	else
		UpdateDisplay();
}
Esempio n. 11
0
DialogSpellChecker::DialogSpellChecker(agi::Context *context)
: wxDialog(context->parent, -1, _("Spell Checker"))
, context(context)
, spellchecker(SpellCheckerFactory::GetSpellChecker())
{
	SetIcon(GETICON(spellcheck_toolbutton_16));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);

	auto current_word_sizer = new wxFlexGridSizer(2, 5, 5);
	main_sizer->Add(current_word_sizer, wxSizerFlags().Expand().Border(wxALL, 5));

	wxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
	main_sizer->Add(bottom_sizer, wxSizerFlags().Expand().Border(~wxTOP & wxALL, 5));

	wxSizer *bottom_left_sizer = new wxBoxSizer(wxVERTICAL);
	bottom_sizer->Add(bottom_left_sizer, wxSizerFlags().Expand().Border(wxRIGHT, 5));

	wxSizer *actions_sizer = new wxBoxSizer(wxVERTICAL);
	bottom_sizer->Add(actions_sizer, wxSizerFlags().Expand());

	// Misspelled word and currently selected correction
	current_word_sizer->AddGrowableCol(1, 1);
	current_word_sizer->Add(new wxStaticText(this, -1, _("Misspelled word:")), 0, wxALIGN_CENTER_VERTICAL);
	current_word_sizer->Add(orig_word = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY), wxSizerFlags(1).Expand());
	current_word_sizer->Add(new wxStaticText(this, -1, _("Replace with:")), 0, wxALIGN_CENTER_VERTICAL);
	current_word_sizer->Add(replace_word = new wxTextCtrl(this, -1, ""), wxSizerFlags(1).Expand());

	replace_word->Bind(wxEVT_TEXT, [=](wxCommandEvent&) {
		remove_button->Enable(spellchecker->CanRemoveWord(from_wx(replace_word->GetValue())));
	});

	// List of suggested corrections
	suggest_list = new wxListBox(this, -1, wxDefaultPosition, wxSize(300, 150));
	suggest_list->Bind(wxEVT_LISTBOX, &DialogSpellChecker::OnChangeSuggestion, this);
	suggest_list->Bind(wxEVT_LISTBOX_DCLICK, &DialogSpellChecker::OnReplace, this);
	bottom_left_sizer->Add(suggest_list, wxSizerFlags(1).Expand());

	// List of supported spellchecker languages
	{
		if (!spellchecker.get()) {
			wxMessageBox("No spellchecker available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
			throw agi::UserCancelException("No spellchecker available");
		}

		dictionary_lang_codes = to_wx(spellchecker->GetLanguageList());
		if (dictionary_lang_codes.empty()) {
			wxMessageBox("No spellchecker dictionaries available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
			throw agi::UserCancelException("No spellchecker dictionaries available");
		}

		wxArrayString language_names(dictionary_lang_codes);
		for (size_t i = 0; i < dictionary_lang_codes.size(); ++i) {
			if (const wxLanguageInfo *info = wxLocale::FindLanguageInfo(dictionary_lang_codes[i]))
				language_names[i] = info->Description;
		}

		language = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, language_names, wxCB_DROPDOWN | wxCB_READONLY);
		wxString cur_lang = to_wx(OPT_GET("Tool/Spell Checker/Language")->GetString());
		int cur_lang_index = dictionary_lang_codes.Index(cur_lang);
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = dictionary_lang_codes.Index("en");
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = dictionary_lang_codes.Index("en_US");
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = 0;
		language->SetSelection(cur_lang_index);
		language->Bind(wxEVT_COMBOBOX, &DialogSpellChecker::OnChangeLanguage, this);

		bottom_left_sizer->Add(language, wxSizerFlags().Expand().Border(wxTOP, 5));
	}

	{
		wxSizerFlags button_flags = wxSizerFlags().Expand().Bottom().Border(wxBOTTOM, 5);

		auto make_checkbox = [&](wxString const& text, const char *opt) {
			auto checkbox = new wxCheckBox(this, -1, text);
			actions_sizer->Add(checkbox, button_flags);
			checkbox->SetValue(OPT_GET(opt)->GetBool());
			checkbox->Bind(wxEVT_CHECKBOX,
				[=](wxCommandEvent &evt) { OPT_SET(opt)->SetBool(!!evt.GetInt()); });
		};

		make_checkbox(_("&Skip Comments"), "Tool/Spell Checker/Skip Comments");
		make_checkbox(_("Ignore &UPPERCASE words"), "Tool/Spell Checker/Skip Uppercase");

		wxButton *button;

		actions_sizer->Add(button = new wxButton(this, -1, _("&Replace")), button_flags);
		button->Bind(wxEVT_BUTTON, &DialogSpellChecker::OnReplace, this);

		actions_sizer->Add(button = new wxButton(this, -1, _("Replace &all")), button_flags);
		button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			auto_replace[from_wx(orig_word->GetValue())] = from_wx(replace_word->GetValue());
			Replace();
			FindNext();
		});

		actions_sizer->Add(button = new wxButton(this, -1, _("&Ignore")), button_flags);
		button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) { FindNext(); });

		actions_sizer->Add(button = new wxButton(this, -1, _("Ignore a&ll")), button_flags);
		button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			auto_ignore.insert(from_wx(orig_word->GetValue()));
			FindNext();
		});

		actions_sizer->Add(add_button = new wxButton(this, -1, _("Add to &dictionary")), button_flags);
		add_button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			spellchecker->AddWord(from_wx(orig_word->GetValue()));
			FindNext();
		});

		actions_sizer->Add(remove_button = new wxButton(this, -1, _("Remove fro&m dictionary")), button_flags);
		remove_button->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
			spellchecker->RemoveWord(from_wx(replace_word->GetValue()));
			SetWord(from_wx(orig_word->GetValue()));
		});

		actions_sizer->Add(new HelpButton(this, "Spell Checker"), button_flags);

		actions_sizer->Add(new wxButton(this, wxID_CANCEL), button_flags.Border(0));
	}

	SetSizerAndFit(main_sizer);
	CenterOnParent();

	if (FindNext())
		Show();
}
Esempio n. 12
0
DialogExport::DialogExport(agi::Context *c)
: wxDialog(c->parent, -1, _("Export"), wxDefaultPosition, wxSize(200, 100), wxCAPTION | wxCLOSE_BOX)
, c(c)
, exporter(new AssExporter(c))
{
	SetIcon(GETICON(export_menu_16));
	SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);

	std::vector<std::string> filters = exporter->GetAllFilterNames();
	filter_list = new wxCheckListBox(this, -1, wxDefaultPosition, wxSize(200, 100), to_wx(filters));
	filter_list->Bind(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, [=](wxCommandEvent&) { RefreshOptions(); });
	filter_list->Bind(wxEVT_COMMAND_LISTBOX_SELECTED, &DialogExport::OnChange, this);

	// Get selected filters
	std::string selected = c->ass->GetScriptInfo("Export filters");
	boost::char_separator<char> sep("|");
	for (auto const& token : boost::tokenizer<boost::char_separator<char>>(selected, sep)) {
		auto it = find(begin(filters), end(filters), token);
		if (it != end(filters))
			filter_list->Check(distance(begin(filters), it));
	}

	wxButton *btn_up = new wxButton(this, -1, _("Move &Up"), wxDefaultPosition, wxSize(90, -1));
	wxButton *btn_down = new wxButton(this, -1, _("Move &Down"), wxDefaultPosition, wxSize(90, -1));
	wxButton *btn_all = new wxButton(this, -1, _("Select &All"), wxDefaultPosition, wxSize(80, -1));
	wxButton *btn_none = new wxButton(this, -1, _("Select &None"), wxDefaultPosition, wxSize(80, -1));

	btn_up->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent&) { swap(filter_list, filter_list->GetSelection() - 1, 0); });
	btn_down->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent&) { swap(filter_list, filter_list->GetSelection() - 1, 0); });
	btn_all->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent&) { SetAll(true); });
	btn_none->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent&) { SetAll(false); });

	wxSizer *top_buttons = new wxBoxSizer(wxHORIZONTAL);
	top_buttons->Add(btn_up, wxSizerFlags(1).Expand());
	top_buttons->Add(btn_down, wxSizerFlags(1).Expand().Border(wxRIGHT));
	top_buttons->Add(btn_all, wxSizerFlags(1).Expand());
	top_buttons->Add(btn_none, wxSizerFlags(1).Expand());

	filter_description = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxSize(200, 60), wxTE_MULTILINE | wxTE_READONLY);

	// Charset dropdown list
	wxStaticText *charset_list_label = new wxStaticText(this, -1, _("Text encoding:"));
	charset_list = new wxChoice(this, -1, wxDefaultPosition, wxDefaultSize, agi::charset::GetEncodingsList<wxArrayString>());
	wxSizer *charset_list_sizer = new wxBoxSizer(wxHORIZONTAL);
	charset_list_sizer->Add(charset_list_label, wxSizerFlags().Center().Border(wxRIGHT));
	charset_list_sizer->Add(charset_list, wxSizerFlags(1).Expand());
	if (!charset_list->SetStringSelection(to_wx(c->ass->GetScriptInfo("Export Encoding"))))
		charset_list->SetStringSelection("Unicode (UTF-8)");

	wxSizer *top_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Filters"));
	top_sizer->Add(filter_list, wxSizerFlags(1).Expand());
	top_sizer->Add(top_buttons, wxSizerFlags(0).Expand());
	top_sizer->Add(filter_description, wxSizerFlags(0).Expand().Border(wxTOP));
	top_sizer->Add(charset_list_sizer, wxSizerFlags(0).Expand().Border(wxTOP));

	wxStdDialogButtonSizer *btn_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP);
	btn_sizer->GetAffirmativeButton()->SetLabelText(_("Export..."));
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogExport::OnProcess, this, wxID_OK);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&HelpButton::OpenPage, "Export"), wxID_HELP);

	wxSizer *horz_sizer = new wxBoxSizer(wxHORIZONTAL);
	opt_sizer = new wxBoxSizer(wxVERTICAL);
	exporter->DrawSettings(this, opt_sizer);
	horz_sizer->Add(top_sizer, wxSizerFlags().Expand().Border(wxALL & ~wxRIGHT));
	horz_sizer->Add(opt_sizer, wxSizerFlags(1).Expand().Border(wxALL & ~wxLEFT));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
	main_sizer->Add(horz_sizer, wxSizerFlags(1).Expand());
	main_sizer->Add(btn_sizer, wxSizerFlags().Expand().Border(wxALL & ~wxTOP));
	SetSizerAndFit(main_sizer);
	RefreshOptions();
	CenterOnParent();
}
Esempio n. 13
0
DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Context *c, AssStyleStorage *store, wxString const& new_name)
: wxDialog (parent, -1, _("Style Editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, c(c)
, is_new(false)
, style(style)
, store(store)
{
	if (new_name.size()) {
		is_new = true;
		style = this->style = new AssStyle(*style);
		style->name = new_name;
	}
	else if (!style) {
		is_new = true;
		style = this->style = new AssStyle;
	}

	work.reset(new AssStyle(*style));

	SetIcon(GETICON(style_toolbutton_16));

	// Prepare control values
	wxString EncodingValue = AegiIntegerToString(style->encoding);
	wxString alignValues[9] = { "7", "8", "9", "4", "5", "6", "1", "2", "3" };
	wxArrayString fontList = wxFontEnumerator::GetFacenames();
	fontList.Sort();

	// Encoding options
	wxArrayString encodingStrings;
	AssStyle::GetEncodings(encodingStrings);

	// Create sizers
	wxSizer *NameSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Style Name"));
	wxSizer *FontSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Font"));
	wxSizer *ColorsSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Colors"));
	wxSizer *MarginSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Margins"));
	wxSizer *OutlineBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Outline"));
	wxSizer *MiscBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Miscellaneous"));
	wxSizer *PreviewBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Preview"));

	// Create controls
	StyleName = new wxTextCtrl(this, -1, style->name);
	FontName = new wxComboBox(this, -1, style->font, wxDefaultPosition, wxSize(150, -1), 0, 0, wxCB_DROPDOWN);
	FontSize =  num_text_ctrl(this, style->fontsize, wxSize(50, -1));
	BoxBold = new wxCheckBox(this, -1, _("&Bold"));
	BoxItalic = new wxCheckBox(this, -1, _("&Italic"));
	BoxUnderline = new wxCheckBox(this, -1, _("&Underline"));
	BoxStrikeout = new wxCheckBox(this, -1, _("&Strikeout"));
	colorButton[0] = new ColourButton(this, -1, wxSize(55, 16), style->primary);
	colorButton[1] = new ColourButton(this, -1, wxSize(55, 16), style->secondary);
	colorButton[2] = new ColourButton(this, -1, wxSize(55, 16), style->outline);
	colorButton[3] = new ColourButton(this, -1, wxSize(55, 16), style->shadow);
	colorAlpha[0] = spin_ctrl(this, style->primary.a, 255);
	colorAlpha[1] = spin_ctrl(this, style->secondary.a, 255);
	colorAlpha[2] = spin_ctrl(this, style->outline.a, 255);
	colorAlpha[3] = spin_ctrl(this, style->shadow.a, 255);
	for (int i = 0; i < 3; i++)
		margin[i] = spin_ctrl(this, style->Margin[i], 9999);
	Alignment = new wxRadioBox(this, -1, _("Alignment"), wxDefaultPosition, wxDefaultSize, 9, alignValues, 3, wxRA_SPECIFY_COLS);
	Outline = num_text_ctrl(this, style->outline_w, wxSize(50, -1));
	Shadow = num_text_ctrl(this, style->shadow_w, wxSize(50, -1));
	OutlineType = new wxCheckBox(this, -1, _("&Opaque box"));
	ScaleX = num_text_ctrl(this, style->scalex);
	ScaleY = num_text_ctrl(this, style->scaley);
	Angle = num_text_ctrl(this, style->angle);
	Spacing = num_text_ctrl(this, style->spacing);
	Encoding = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, encodingStrings, wxCB_READONLY);

	// Set control tooltips
	StyleName->SetToolTip(_("Style name"));
	FontName->SetToolTip(_("Font face"));
	FontSize->SetToolTip(_("Font size"));
	colorButton[0]->SetToolTip(_("Choose primary color"));
	colorButton[1]->SetToolTip(_("Choose secondary color"));
	colorButton[2]->SetToolTip(_("Choose outline color"));
	colorButton[3]->SetToolTip(_("Choose shadow color"));
	for (int i=0;i<4;i++) colorAlpha[i]->SetToolTip(_("Set opacity, from 0 (opaque) to 255 (transparent)"));
	margin[0]->SetToolTip(_("Distance from left edge, in pixels"));
	margin[1]->SetToolTip(_("Distance from right edge, in pixels"));
	margin[2]->SetToolTip(_("Distance from top/bottom edge, in pixels"));
	OutlineType->SetToolTip(_("When selected, display an opaque box behind the subtitles instead of an outline around the text"));
	Outline->SetToolTip(_("Outline width, in pixels"));
	Shadow->SetToolTip(_("Shadow distance, in pixels"));
	ScaleX->SetToolTip(_("Scale X, in percentage"));
	ScaleY->SetToolTip(_("Scale Y, in percentage"));
	Angle->SetToolTip(_("Angle to rotate in Z axis, in degrees"));
	Encoding->SetToolTip(_("Encoding, only useful in unicode if the font doesn't have the proper unicode mapping"));
	Spacing->SetToolTip(_("Character spacing, in pixels"));
	Alignment->SetToolTip(_("Alignment in screen, in numpad style"));

	// Set up controls
	BoxBold->SetValue(style->bold);
	BoxItalic->SetValue(style->italic);
	BoxUnderline->SetValue(style->underline);
	BoxStrikeout->SetValue(style->strikeout);
	OutlineType->SetValue(style->borderstyle == 3);
	Alignment->SetSelection(AlignToControl(style->alignment));
	// Fill font face list box
	FontName->Freeze();
	FontName->Append(fontList);
	FontName->SetValue(style->font);
	FontName->Thaw();

	// Set encoding value
	bool found = false;
	for (size_t i=0;i<encodingStrings.Count();i++) {
		if (encodingStrings[i].StartsWith(EncodingValue)) {
			Encoding->Select(i);
			found = true;
			break;
		}
	}
	if (!found) Encoding->Select(0);

	// Style name sizer
	NameSizer->Add(StyleName, 1, wxALL, 0);

	// Font sizer
	wxSizer *FontSizerTop = new wxBoxSizer(wxHORIZONTAL);
	wxSizer *FontSizerBottom = new wxBoxSizer(wxHORIZONTAL);
	FontSizerTop->Add(FontName, 1, wxALL, 0);
	FontSizerTop->Add(FontSize, 0, wxLEFT, 5);
	FontSizerBottom->AddStretchSpacer(1);
	FontSizerBottom->Add(BoxBold, 0, 0, 0);
	FontSizerBottom->Add(BoxItalic, 0, wxLEFT, 5);
	FontSizerBottom->Add(BoxUnderline, 0, wxLEFT, 5);
	FontSizerBottom->Add(BoxStrikeout, 0, wxLEFT, 5);
	FontSizerBottom->AddStretchSpacer(1);
	FontSizer->Add(FontSizerTop, 1, wxALL | wxEXPAND, 0);
	FontSizer->Add(FontSizerBottom, 1, wxTOP | wxEXPAND, 5);

	// Colors sizer
	wxSizer *ColorSizer[4];
	wxString colorLabels[] = { _("Primary"), _("Secondary"), _("Outline"), _("Shadow") };
	ColorsSizer->AddStretchSpacer(1);
	for (int i=0;i<4;i++) {
		ColorSizer[i] = new wxBoxSizer(wxVERTICAL);
		ColorSizer[i]->Add(new wxStaticText(this, -1, colorLabels[i]), 0, wxBOTTOM | wxALIGN_CENTER, 5);
		ColorSizer[i]->Add(colorButton[i], 0, wxBOTTOM | wxALIGN_CENTER, 5);
		ColorSizer[i]->Add(colorAlpha[i], 0, wxALIGN_CENTER, 0);
		ColorsSizer->Add(ColorSizer[i], 0, wxLEFT, i?5:0);
	}
	ColorsSizer->AddStretchSpacer(1);

	// Margins
	wxString marginLabels[] = { _("Left"), _("Right"), _("Vert") };
	MarginSizer->AddStretchSpacer(1);
	wxSizer *marginSubSizer[3];
	for (int i=0;i<3;i++) {
		marginSubSizer[i] = new wxBoxSizer(wxVERTICAL);
		marginSubSizer[i]->AddStretchSpacer(1);
		marginSubSizer[i]->Add(new wxStaticText(this, -1, marginLabels[i]), 0, wxCENTER, 0);
		marginSubSizer[i]->Add(margin[i], 0, wxTOP | wxCENTER, 5);
		marginSubSizer[i]->AddStretchSpacer(1);
		MarginSizer->Add(marginSubSizer[i], 0, wxEXPAND | wxLEFT, i?5:0);
	}
	MarginSizer->AddStretchSpacer(1);

	// Margins+Alignment
	wxSizer *MarginAlign = new wxBoxSizer(wxHORIZONTAL);
	MarginAlign->Add(MarginSizer, 1, wxLEFT | wxEXPAND, 0);
	MarginAlign->Add(Alignment, 0, wxLEFT | wxEXPAND, 5);

	// Outline
	add_with_label(OutlineBox, this, _("Outline:"), Outline);
	add_with_label(OutlineBox, this, _("Shadow:"), Shadow);
	OutlineBox->Add(OutlineType, 0, wxLEFT | wxALIGN_CENTER, 5);

	// Misc
	wxFlexGridSizer *MiscBoxTop = new wxFlexGridSizer(2, 4, 5, 5);
	add_with_label(MiscBoxTop, this, _("Scale X%:"), ScaleX);
	add_with_label(MiscBoxTop, this, _("Scale Y%:"), ScaleY);
	add_with_label(MiscBoxTop, this, _("Rotation:"), Angle);
	add_with_label(MiscBoxTop, this, _("Spacing:"), Spacing);

	wxSizer *MiscBoxBottom = new wxBoxSizer(wxHORIZONTAL);
	add_with_label(MiscBoxBottom, this, _("Encoding:"), Encoding);

	MiscBox->Add(MiscBoxTop, wxSizerFlags().Expand().Center());
	MiscBox->Add(MiscBoxBottom, wxSizerFlags().Expand().Center().Border(wxTOP));

	// Preview
	SubsPreview = nullptr;
	PreviewText = nullptr;
	ColourButton *previewButton = 0;
	if (!SubtitlesProviderFactory::GetClasses().empty()) {
		PreviewText = new wxTextCtrl(this, -1, lagi_wxString(OPT_GET("Tool/Style Editor/Preview Text")->GetString()));
		previewButton = new ColourButton(this, -1, wxSize(45, 16), OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());
		SubsPreview = new SubtitlesPreview(this, wxSize(100, 60), wxSUNKEN_BORDER, OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());

		SubsPreview->SetToolTip(_("Preview of current style"));
		SubsPreview->SetStyle(*style);
		SubsPreview->SetText(PreviewText->GetValue());
		PreviewText->SetToolTip(_("Text to be used for the preview"));
		previewButton->SetToolTip(_("Color of preview background"));

		wxSizer *PreviewBottomSizer = new wxBoxSizer(wxHORIZONTAL);
		PreviewBottomSizer->Add(PreviewText, 1, wxEXPAND | wxRIGHT, 5);
		PreviewBottomSizer->Add(previewButton, 0, wxEXPAND, 0);
		PreviewBox->Add(SubsPreview, 1, wxEXPAND | wxBOTTOM, 5);
		PreviewBox->Add(PreviewBottomSizer, 0, wxEXPAND | wxBOTTOM, 0);
	}
	else {
		wxStaticText *NoSP = new wxStaticText(this, -1, _("No subtitle providers available. Cannot preview subs."));
		PreviewBox->AddStretchSpacer();
		PreviewBox->Add(NoSP, 1, wxEXPAND|wxLEFT|wxRIGHT, 8);
		PreviewBox->AddStretchSpacer();
	}

	// Buttons
	wxStdDialogButtonSizer *ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxAPPLY | wxHELP);

	// Left side sizer
	wxSizer *LeftSizer = new wxBoxSizer(wxVERTICAL);
	LeftSizer->Add(NameSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(FontSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(ColorsSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(MarginAlign, 0, wxBOTTOM | wxEXPAND, 0);

	// Right side sizer
	wxSizer *RightSizer = new wxBoxSizer(wxVERTICAL);
	RightSizer->Add(OutlineBox, wxSizerFlags().Expand().Border(wxBOTTOM));
	RightSizer->Add(MiscBox, wxSizerFlags().Expand().Border(wxBOTTOM));
	RightSizer->Add(PreviewBox, wxSizerFlags(1).Expand());

	// Controls Sizer
	wxSizer *ControlSizer = new wxBoxSizer(wxHORIZONTAL);
	ControlSizer->Add(LeftSizer, 0, wxEXPAND, 0);
	ControlSizer->Add(RightSizer, 1, wxLEFT | wxEXPAND, 5);

	// General Layout
	wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(ControlSizer, 1, wxALL | wxALIGN_CENTER | wxEXPAND, 5);
	MainSizer->Add(ButtonSizer, 0, wxBOTTOM | wxEXPAND, 5);

	SetSizerAndFit(MainSizer);

	// Force the style name text field to scroll based on its final size, rather
	// than its initial size
	StyleName->SetInsertionPoint(0);
	StyleName->SetInsertionPoint(-1);

	persist.reset(new PersistLocation(this, "Tool/Style Editor", true));

	Bind(wxEVT_CHILD_FOCUS, &DialogStyleEditor::OnChildFocus, this);

	if (PreviewText) {
		Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
		Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
		Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &DialogStyleEditor::OnCommandPreviewUpdate, this);

		previewButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyleEditor::OnPreviewColourChange, this);
		FontName->Bind(wxEVT_COMMAND_TEXT_ENTER, &DialogStyleEditor::OnCommandPreviewUpdate, this);
		PreviewText->Bind(wxEVT_COMMAND_TEXT_UPDATED, &DialogStyleEditor::OnPreviewTextChange, this);
	}

	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, true, true), wxID_OK);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, true, false), wxID_APPLY);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, false, true), wxID_CANCEL);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&HelpButton::OpenPage, "Style Editor"), wxID_HELP);

	for (int i = 0; i < 4; ++i)
		colorButton[i]->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::OnSetColor, this, i + 1, std::placeholders::_1));
}