/* * Copyright (c) 2007, ai-chan * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the ASSDraw3 Team nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY AI-CHAN ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL AI-CHAN BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /////////////////////////////////////////////////////////////////////////////// // Name: assdraw.cpp // Purpose: ASSDraw main source file // Author: ai-chan // Created: 08/26/06 // Copyright: (c) ai-chan // Licence: 3-clause BSD /////////////////////////////////////////////////////////////////////////////// #include "assdraw.hpp" #include "enums.hpp" #include "include_once.hpp" #include #include #include #include #include //DEFINE_EVENT_TYPE(wxEVT_SETTINGS_CHANGED) // initialize wxWidget to accept our App class IMPLEMENT_APP(ASSDrawApp) BEGIN_EVENT_TABLE(ASSDrawFrame, wxFrame) EVT_TOOL(TB_CLEAR, ASSDrawFrame::OnSelect_Clear) EVT_TOOL(TB_PREVIEW, ASSDrawFrame::OnSelect_Preview) //EVT_TOOL(TB_EDITSRC, ASSDrawFrame::OnSelect_EditSrc) EVT_TOOL(TB_TRANSFORM, ASSDrawFrame::OnSelect_Transform) EVT_TOOL_RANGE(MODE_ARR, MODE_DEL, ASSDrawFrame::OnChoose_Mode) EVT_TOOL_RANGE(DRAG_DWG, DRAG_BOTH, ASSDrawFrame::OnChoose_DragMode) EVT_TOOL_RCLICKED(wxID_ANY, ASSDrawFrame::OnToolRClick) EVT_COMMAND(wxID_ANY, wxEVT_SETTINGS_CHANGED, ASSDrawFrame::OnSettingsChanged) EVT_MENU_RANGE(MENU_TB_ALL, MENU_TB_BGIMG, ASSDrawFrame::OnChoose_TBarRClickMenu) #if wxUSE_MENUS EVT_MENU(MENU_CLEAR, ASSDrawFrame::OnSelect_Clear) EVT_MENU(MENU_PREVIEW, ASSDrawFrame::OnSelect_Preview) EVT_MENU(MENU_TRANSFORM, ASSDrawFrame::OnSelect_Transform) EVT_MENU(MENU_LIBRARY, ASSDrawFrame::OnSelect_Library) EVT_MENU(MENU_SETTINGS, ASSDrawFrame::OnSelect_Settings) EVT_MENU(MENU_RESETPERSPECTIVE, ASSDrawFrame::OnSelect_ResetPerspective) EVT_MENU(MENU_HELP, ASSDrawFrame::OnSelect_Help) EVT_MENU(wxID_ABOUT, ASSDrawFrame::OnSelect_About) EVT_MENU(MENU_UNDO, ASSDrawFrame::OnSelect_Undo) EVT_MENU(MENU_REDO, ASSDrawFrame::OnSelect_Redo) EVT_MENU(MENU_PASTE, ASSDrawFrame::OnSelect_Paste) EVT_MENU(MENU_BGIMG_REMOVE, ASSDrawFrame::OnSelect_RemoveBG) EVT_MENU(MENU_BGIMG_ALPHA, ASSDrawFrame::OnSelect_AlphaBG) EVT_MENU_RANGE(MODE_ARR, MODE_NUT_BILINEAR, ASSDrawFrame::OnChoose_Mode) EVT_MENU_RANGE(DRAG_DWG, DRAG_BOTH, ASSDrawFrame::OnChoose_DragMode) EVT_MENU_RANGE(MENU_REPOS_TOPLEFT, MENU_REPOS_BOTRIGHT, ASSDrawFrame::OnChoose_Recenter) EVT_MENU_RANGE(MENU_REPOS_BGTOPLEFT, MENU_REPOS_BGBOTRIGHT, ASSDrawFrame::OnChoose_RecenterToBG) #endif //wxUSE_MENUS EVT_CLOSE(ASSDrawFrame::OnClose) END_EVENT_TABLE() // ---------------------------------------------------------------------------- // the application class: ASSDrawApp // ---------------------------------------------------------------------------- // 'Main program' equivalent: the program execution "starts" here bool ASSDrawApp::OnInit() { // create the main application window ASSDrawFrame * assdrawframe = new ASSDrawFrame( this, TITLE, wxDefaultPosition, wxSize(640, 480) ); SetTopWindow(assdrawframe); return TRUE; } // ---------------------------------------------------------------------------- // main frame: ASSDrawFrame // ---------------------------------------------------------------------------- // constructor ASSDrawFrame::ASSDrawFrame( wxApp *app, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(NULL, wxID_ANY, title, pos, size, style) { m_app = app; m_mgr.SetManagedWindow(this); m_mgr.SetFlags(m_mgr.GetFlags() | wxAUI_MGR_ALLOW_ACTIVE_PANE); // set the frame icon SetIcon(wxICON(appico)); // Create status bar for the frame #if wxUSE_STATUSBAR CreateStatusBar(3); int statwidths[] = { 64, -1, 64 }; GetStatusBar()->SetStatusWidths(3, statwidths); SetStatusBarPane(1); #endif // wxUSE_STATUSBAR InitializeDefaultSettings(); // load config configfile = wxFileName(::wxGetCwd(), _T("ASSDraw3.cfg")).GetFullPath(); if (!::wxFileExists(configfile)) configfile = wxFileName(wxStandardPaths::Get().GetUserConfigDir(), _T("ASSDraw3.cfg")).GetFullPath(); bool firsttime = !::wxFileExists(configfile); if (firsttime) wxFileOutputStream(configfile).Close(); wxFileInputStream cfgf(configfile); config = new wxFileConfig(cfgf); // nullify transformdlg transformdlg = NULL; Maximize(true); Show(true); // to get the right client size, must call Show() first // config LoadSettings(); // THE CANVAS m_canvas = new ASSDrawCanvas( this , this ); // shapes library shapelib = new ASSDrawShapeLibrary(this, this); // source text ctrl srctxtctrl = new ASSDrawSrcTxtCtrl(this, this); // settings /* settingsdlg = NULL; wxString settingsdllfile = wxFileName(::wxGetCwd(), "settings.dll").GetFullPath(); if (::wxFileExists(settingsdllfile)) { wxDynamicLibrary settingsdll(settingsdllfile); wxString symbol("CreateASSDrawSettingsDialogInstance"); if (settingsdll.IsLoaded() && settingsdll.HasSymbol(symbol)) { typedef ASSDrawSettingsDialog* (*FuncType)(wxWindow*,ASSDrawFrame*,int); FuncType func = (FuncType) settingsdll.GetSymbol(symbol); //wxDYNLIB_FUNCTION(ASSDrawSettingsDialog, CreateASSDrawSettingsDialogInstance, settingsdll) //ASSDrawSettingsDialog* test = func(NULL,this,971231); //test->Reparent(this); //test->Init(); //SetTitle(settingsdllfile); //settingsdlg = func(NULL,this, 809131); //settingsdlg->Init(); //m_mgr.AddPane(settingsdlg, wxAuiPaneInfo().Name(wxT("settings")).Caption(wxT("Settings")).Right().Layer(3).Position(0).CloseButton(true).BestSize(wxSize(240, 480)).MinSize(wxSize(200, 200))); } } */ settingsdlg = new ASSDrawSettingsDialog(this, this); settingsdlg->Init(); SetMenus(); SetToolBars(); SetPanes(); // config config->SetPath(_T("info")); wxString version; config->Read("version", &version); config->SetPath(".."); default_perspective = m_mgr.SavePerspective(); // back up default perspective config->SetPath("perspective"); wxString perspective; if (config->Read("perspective", &perspective) && version == VERSION) m_mgr.LoadPerspective(perspective, false); config->SetPath(".."); config->SetPath("library"); int n = 0; config->Read("n", &n); for (int i = 0; i < n; i++) { wxString libcmds; config->Read(wxString::Format("%d",i), &libcmds); shapelib->AddShapePreview(libcmds); } config->SetPath(".."); m_mgr.Update(); m_canvas->SetFocus(); m_canvas->Show(); wxSize clientsize = m_canvas->GetClientSize(); m_canvas->ChangeZoomLevelTo(DEFAULT_SCALE, wxPoint(clientsize.x / 2, clientsize.y / 2)); m_canvas->MoveCanvasOriginTo(clientsize.x / 2, clientsize.y / 2); UpdateASSCommandStringToSrcTxtCtrl(m_canvas->GenerateASS()); UpdateFrameUI(); ApplySettings(); #ifdef BETAVERSION wxDateTime expire(15, wxDateTime::Dec, 2007, 0, 0, 0); wxDateTime now = wxDateTime::Now(); if (now.IsLaterThan(expire)) { wxMessageDialog expired(this, "Thank you for trying ASSDraw3. This beta version has expired. Please visit http://malakith.net/aegisub/index.php?topic=912.0 to get the latest release. Visit now?", wxT("Beta version"), wxYES_NO | wxICON_INFORMATION); if (expired.ShowModal() == wxID_YES) ::wxLaunchDefaultBrowser(wxString("http://malakith.net/aegisub/index.php?topic=912.0")); Close(); } SetTitle(wxString::Format("%s beta %d (expires %s)", TITLE, BETAVERSION, expire.FormatDate().c_str())); #endif if (firsttime) _About(); else if (!behaviors.nosplashscreen) _About(3); helpcontroller.SetParentWindow(this); helpcontroller.Initialize(wxFileName(::wxGetCwd(), "ASSDraw3.chm").GetFullPath()); } void ASSDrawFrame::SetToolBars() { drawtbar = new wxToolBar(this, wxID_ANY, __DPDS__ , wxTB_FLAT | wxTB_TEXT | wxTB_NODIVIDER | wxTB_HORIZONTAL); drawtbar->AddTool(TB_CLEAR, _T("Clear"), wxBITMAP(new_), wxNullBitmap, wxITEM_NORMAL, "", TIPS_CLEAR); //tbar->AddTool(TB_EDITSRC, _T("Source"), wxBITMAP(src_), wxNullBitmap, wxITEM_NORMAL, "", TIPS_EDITSRC); drawtbar->AddCheckTool(TB_PREVIEW, _T("Preview"), wxBITMAP(preview_), wxNullBitmap, "", TIPS_PREVIEW); //drawtbar->AddTool(TB_TRANSFORM, _T("Transform"), wxBITMAP(rot_), wxNullBitmap, wxITEM_NORMAL, "", TIPS_TRANSFORM); zoomslider = new wxSlider(drawtbar, TB_ZOOMSLIDER, 1000, 100, 5000, __DPDS__ ); //zoomslider->SetSize(280, zoomslider->GetSize().y); zoomslider->Connect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(ASSDrawFrame::OnZoomSliderChanged), NULL, this); zoomslider->Connect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(ASSDrawFrame::OnZoomSliderChanged), NULL, this); zoomslider->Connect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(ASSDrawFrame::OnZoomSliderChanged), NULL, this); zoomslider->Connect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(ASSDrawFrame::OnZoomSliderChanged), NULL, this); zoomslider->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(ASSDrawFrame::OnZoomSliderChanged), NULL, this); zoomslider->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(ASSDrawFrame::OnZoomSliderChanged), NULL, this); drawtbar->AddControl(zoomslider); drawtbar->Realize(); m_mgr.AddPane(drawtbar, wxAuiPaneInfo().Name(wxT("drawtbar")).Caption(TBNAME_DRAW). ToolbarPane().Top().Position(0).Dockable(true).LeftDockable(false).RightDockable(false)); modetbar = new wxToolBar(this, wxID_ANY, __DPDS__ , wxTB_FLAT | wxTB_TEXT | wxTB_NODIVIDER | wxTB_HORIZONTAL); modetbar->AddRadioTool(MODE_ARR, _T("Drag"), wxBITMAP(arr_), wxNullBitmap, "", TIPS_ARR); modetbar->AddRadioTool(MODE_M, _T("Move"), wxBITMAP(m_), wxNullBitmap, "", TIPS_M); //modetbar->AddRadioTool(MODE_N, _T("Move*"), wxBITMAP(n_), wxNullBitmap, "", TIPS_N); modetbar->AddRadioTool(MODE_L, _T("Line"), wxBITMAP(l_), wxNullBitmap, "", TIPS_L); modetbar->AddRadioTool(MODE_B, _T("Bezier"), wxBITMAP(b_), wxNullBitmap, "", TIPS_B); //modetbar->AddRadioTool(MODE_S, _T("Spline"), wxBITMAP(s_), wxNullBitmap, "", TIPS_S); //modetbar->AddRadioTool(MODE_P, _T("Extend"), wxBITMAP(p_), wxNullBitmap, "", TIPS_P); //modetbar->AddRadioTool(MODE_C, _T("Close"), wxBITMAP(c_), wxNullBitmap, "", TIPS_C); modetbar->AddRadioTool(MODE_DEL, _T("Delete"), wxBITMAP(del_), wxNullBitmap, "", TIPS_DEL); modetbar->AddRadioTool(MODE_SCALEROTATE, _T("Scale/Rotate"), wxBITMAP(sc_rot_), wxNullBitmap, "", TIPS_SCALEROTATE); modetbar->AddRadioTool(MODE_NUT_BILINEAR, _T("Bilinear"), wxBITMAP(nut_), wxNullBitmap, "", TIPS_NUTB); //modetbar->AddRadioTool(MODE_NUT_PERSPECTIVE, _T("NUT:P"), wxBITMAP(arr_), wxNullBitmap, "", ""); modetbar->Realize(); m_mgr.AddPane(modetbar, wxAuiPaneInfo().Name(wxT("modetbar")).Caption(TBNAME_MODE). ToolbarPane().Top().Position(1).Dockable(true).LeftDockable(false).RightDockable(false)); bgimgtbar = new wxToolBar(this, wxID_ANY, __DPDS__ , wxTB_FLAT | wxTB_TEXT | wxTB_NODIVIDER | wxTB_HORIZONTAL); bgimgtbar->SetToolBitmapSize(wxSize(24,15)); bgimgtbar->AddCheckTool(DRAG_DWG, _T("Pan drawing"), wxBITMAP(pan_shp), wxNullBitmap, "", TIPS_DWG); bgimgtbar->AddCheckTool(DRAG_BGIMG, _T("Pan background"), wxBITMAP(pan_bg), wxNullBitmap, "", TIPS_BGIMG); //bgimgtbar->AddRadioTool(DRAG_BOTH, _T("Pan both"), wxBITMAP(pan_both), wxNullBitmap, "", TIPS_BOTH); bgimgtbar->Realize(); m_mgr.AddPane(bgimgtbar, wxAuiPaneInfo().Name(wxT("bgimgtbar")).Caption(TBNAME_BGIMG). ToolbarPane().Top().Position(2).Dockable(true).LeftDockable(false).RightDockable(false)); } void ASSDrawFrame::SetMenus() { #if wxUSE_MENUS drawMenu = new wxMenu; drawMenu->Append(MENU_CLEAR, _T("&Clear\tCtrl+N"), TIPS_CLEAR); //drawMenu->Append(MENU_EDITSRC, _T("&Source"), TIPS_EDITSRC); drawMenu->Append(MENU_PREVIEW, _T("&Preview\tCtrl+P"), TIPS_PREVIEW, wxITEM_CHECK); drawMenu->Append(MENU_TRANSFORM, _T("&Transform"), TIPS_TRANSFORM); drawMenu->Append(MENU_PASTE, _T("&Paste\tCtrl+V"), TIPS_PASTE); drawMenu->AppendSeparator(); drawMenu->Append(MENU_UNDO, _T("&Undo\tCtrl+Z"), TIPS_UNDO); drawMenu->Append(MENU_REDO, _T("&Redo\tCtrl+Y"), TIPS_REDO); drawMenu->Enable(MENU_UNDO, false); drawMenu->Enable(MENU_REDO, false); modeMenu = new wxMenu; modeMenu->Append(MODE_ARR, _T("D&rag\tF1"), TIPS_ARR, wxITEM_RADIO); modeMenu->Append(MODE_M, _T("Draw &M\tF2"), TIPS_M, wxITEM_RADIO); modeMenu->Append(MODE_L, _T("Draw &L\tF3"), TIPS_L, wxITEM_RADIO); modeMenu->Append(MODE_B, _T("Draw &B\tF4"), TIPS_B, wxITEM_RADIO); modeMenu->Append(MODE_DEL, _T("&Delete\tF5"), TIPS_DEL, wxITEM_RADIO); modeMenu->Append(MODE_SCALEROTATE, _T("&Scale/Rotate\tF6"), TIPS_NUTB, wxITEM_RADIO); modeMenu->Append(MODE_NUT_BILINEAR, _T("&Bilinear transformation\tF7"), TIPS_SCALEROTATE, wxITEM_RADIO); bgimgMenu = new wxMenu; bgimgMenu->Append(DRAG_DWG, _T("Pan/Zoom &Drawing\tShift+F1"), TIPS_DWG, wxITEM_CHECK); bgimgMenu->Append(DRAG_BGIMG, _T("Pan/Zoom Back&ground\tShift+F2"), TIPS_BGIMG, wxITEM_CHECK); bgimgMenu->AppendSeparator(); bgimgMenu->Append(MENU_BGIMG_ALPHA, _T("Set background image opacity"), ""); wxMenu* reposbgMenu = new wxMenu; reposbgMenu->Append( MENU_REPOS_BGTOPLEFT, "Top left\tCtrl+Shift+7" ); reposbgMenu->Append( MENU_REPOS_BGTOPRIGHT, "Top right\tCtrl+Shift+9" ); reposbgMenu->Append( MENU_REPOS_BGCENTER, "&Center\tCtrl+Shift+5" ); reposbgMenu->Append( MENU_REPOS_BGBOTLEFT, "Bottom left\tCtrl+Shift+1" ); reposbgMenu->Append( MENU_REPOS_BGBOTRIGHT, "Bottom right\tCtrl+Shift+3" ); bgimgMenu->Append(MENU_BGIMG_RECENTER, _T("Reposition [&0, 0]"), reposbgMenu); bgimgMenu->Append(MENU_BGIMG_REMOVE, _T("Remove background\tShift+Del"), ""); wxMenu* reposMenu = new wxMenu; reposMenu->Append( MENU_REPOS_TOPLEFT, "Top left\tCtrl+7" ); reposMenu->Append( MENU_REPOS_TOPRIGHT, "Top right\tCtrl+9" ); reposMenu->Append( MENU_REPOS_CENTER, "&Center\tCtrl+5" ); reposMenu->Append( MENU_REPOS_BOTLEFT, "Bottom left\tCtrl+1" ); reposMenu->Append( MENU_REPOS_BOTRIGHT, "Bottom right\tCtrl+3" ); tbarMenu = new wxMenu; tbarMenu->AppendCheckItem(MENU_TB_DRAW, TBNAME_DRAW); tbarMenu->AppendCheckItem(MENU_TB_MODE, TBNAME_MODE); tbarMenu->AppendCheckItem(MENU_TB_BGIMG, TBNAME_BGIMG); tbarMenu->AppendSeparator(); tbarMenu->Append(MENU_TB_ALL, "Show all"); tbarMenu->Append(MENU_TB_NONE, "Hide all"); tbarMenu->Append(MENU_TB_DOCK, "Dock all"); tbarMenu->Append(MENU_TB_UNDOCK, "Undock all"); viewMenu = new wxMenu; viewMenu->Append(MENU_LIBRARY, _T("&Library"), TIPS_LIBRARY, wxITEM_CHECK); if (settingsdlg) viewMenu->Append(MENU_SETTINGS, _T("&Settings"), "", wxITEM_CHECK); viewMenu->Append(MENU_TBAR, _T("&Toolbars"), tbarMenu); viewMenu->Append(MENU_RECENTER, _T("Reposition [&0, 0]"), reposMenu); viewMenu->AppendSeparator(); viewMenu->Append(MENU_RESETPERSPECTIVE, _T("&Reset workspace")); wxMenu* helpMenu = new wxMenu; helpMenu->Append(MENU_HELP, _T("&Manual")); helpMenu->Append(wxID_ABOUT, _T("&About")); wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(drawMenu, _T("&Canvas")); menuBar->Append(modeMenu, _T("&Mode")); menuBar->Append(bgimgMenu, _T("&Background")); menuBar->Append(viewMenu, _T("&Workspace")); menuBar->Append(helpMenu, _T("&Help")); SetMenuBar(menuBar); #endif // wxUSE_MENUS } void ASSDrawFrame::SetPanes() { m_mgr.AddPane(shapelib, wxAuiPaneInfo().Name(wxT("library")).Caption(wxT("Shapes Library")). Right().Layer(2).Position(0).CloseButton(true).BestSize(wxSize(120, 480)).MinSize(wxSize(100, 200))); m_mgr.AddPane(m_canvas, wxAuiPaneInfo().Name(wxT("canvas")).CenterPane()); m_mgr.AddPane(srctxtctrl, wxAuiPaneInfo().Name(wxT("commands")).Caption(wxT("Drawing commands")). Bottom().Layer(1).CloseButton(false).BestSize(wxSize(320, 48))); if (settingsdlg) m_mgr.AddPane(settingsdlg, wxAuiPaneInfo().Name(wxT("settings")).Caption(wxT("Settings")). Right().Layer(3).Position(0).CloseButton(true).BestSize(wxSize(240, 480)).MinSize(wxSize(200, 200)).Show(false)); } ASSDrawFrame::~ASSDrawFrame() { config->SetPath("info"); config->Write("assdraw3.exe", wxStandardPaths::Get().GetExecutablePath()); config->Write("version", VERSION); config->SetPath(".."); SaveSettings(); config->SetPath("perspective"); config->Write("perspective", m_mgr.SavePerspective()); config->SetPath(".."); config->DeleteGroup("library"); config->SetPath("library"); typedef std::vector< ASSDrawShapePreview *> PrevVec; PrevVec shapes = shapelib->GetShapePreviews(); int n = shapes.size(); config->Write("n", n); for (int i = 0; i < n; i++) config->Write(wxString::Format("%d",i), shapes[i]->GenerateASS()); config->SetPath(".."); wxFileOutputStream cfgf(configfile); config->Save(cfgf); delete config; if (settingsdlg) settingsdlg->Destroy(); // we need this since wxPropertyGrid must be Clear()ed before deleting m_mgr.UnInit(); } void ASSDrawFrame::_Clear() { wxMessageDialog msgb(this, _T("Clear the canvas and create a new drawing?"), _T("Confirmation"), wxOK | wxCANCEL | wxICON_QUESTION ); if (msgb.ShowModal() == wxID_OK) { m_canvas->RefreshUndocmds(); m_canvas->AddUndo("Clear canvas"); m_canvas->ResetEngine(true); wxSize siz = m_canvas->GetClientSize(); m_canvas->ChangeZoomLevelTo(DEFAULT_SCALE, wxPoint(siz.x / 2, siz.y / 2)); m_canvas->MoveCanvasOriginTo(siz.x / 2, siz.y / 2); UpdateUndoRedoMenu(); m_canvas->RefreshDisplay(); } } void ASSDrawFrame::_Preview() { m_canvas->SetPreviewMode( !m_canvas->IsPreviewMode() ); UpdateFrameUI(); m_canvas->RefreshDisplay(); } void ASSDrawFrame::_ToggleLibrary() { m_mgr.GetPane(shapelib).Show(!m_mgr.GetPane(shapelib).IsShown()); m_mgr.Update(); UpdateFrameUI(); } void ASSDrawFrame::_ToggleSettings() { if (settingsdlg == NULL) return; m_mgr.GetPane(settingsdlg).Show(!m_mgr.GetPane(settingsdlg).IsShown()); m_mgr.Update(); UpdateFrameUI(); } void ASSDrawFrame::_ResetPerspective() { m_mgr.LoadPerspective(default_perspective, false); UpdateFrameUI(); m_mgr.Update(); DRAGMODE bck = m_canvas->GetDragMode(); if (m_canvas->HasBackgroundImage()) m_canvas->SetDragMode(DRAGMODE(true, true)); wxSize clientsize = m_canvas->GetClientSize(); m_canvas->ChangeZoomLevelTo(DEFAULT_SCALE, wxPoint(clientsize.x / 2, clientsize.y / 2)); m_canvas->MoveCanvasOriginTo(clientsize.x / 2, clientsize.y / 2); m_canvas->SetDragMode(bck); UpdateFrameUI(); } void ASSDrawFrame::_Transform() { if (transformdlg == NULL) transformdlg = new ASSDrawTransformDlg( this ); if (transformdlg->ShowModal() == wxID_OK) { m_canvas->Transform( transformdlg->xformvals.f1, transformdlg->xformvals.f2, transformdlg->xformvals.f3, transformdlg->xformvals.f4, transformdlg->xformvals.f5, transformdlg->xformvals.f6, transformdlg->xformvals.f7, transformdlg->xformvals.f8 ); m_canvas->AddUndo("Transform"); m_canvas->RefreshDisplay(); UpdateUndoRedoMenu(); } } void ASSDrawFrame::_Paste() { if (wxTheClipboard->Open()) { if (wxTheClipboard->IsSupported( wxDF_BITMAP )) { wxBitmapDataObject data; wxTheClipboard->GetData( data ); m_canvas->SetBackgroundImage( data.GetBitmap().ConvertToImage() ); //m_canvas->AskUserForBackgroundAlpha(); } else if (wxTheClipboard->IsSupported( wxDF_TEXT )) { wxTextDataObject data; wxTheClipboard->GetData( data ); UpdateASSCommandStringToSrcTxtCtrl( data.GetText() ); } wxTheClipboard->Close(); } } void ASSDrawFrame::OnChoose_Recenter(wxCommandEvent& event) { int x = 0, y = 0; wxSize f = m_canvas->GetClientSize(); switch (event.GetId()) { case MENU_REPOS_TOPLEFT: x = 0, y = 0; break; case MENU_REPOS_TOPRIGHT: x = f.x, y = 0; break; case MENU_REPOS_CENTER: x = f.x / 2, y = f.y / 2; break; case MENU_REPOS_BOTLEFT: x = 0, y = f.y; break; case MENU_REPOS_BOTRIGHT: x = f.x, y = f.y; break; } m_canvas->MoveCanvasOriginTo(x, y); m_canvas->RefreshDisplay(); } void ASSDrawFrame::OnChoose_RecenterToBG(wxCommandEvent& event) { unsigned w, h; wxRealPoint disp; double scale; if (m_canvas->GetBackgroundInfo(w, h, disp, scale)) { int x = 0, y = 0; int lx = (int)disp.x, ty = (int)disp.y; int rx = lx + (int)(w * scale); int by = ty + (int)(h * scale); switch (event.GetId()) { case MENU_REPOS_BGTOPLEFT: x = lx, y = ty; break; case MENU_REPOS_BGTOPRIGHT: x = rx, y = ty; break; case MENU_REPOS_BGCENTER: x = (rx + lx) / 2, y = (by + ty) / 2; break; case MENU_REPOS_BGBOTLEFT: x = lx, y = by; break; case MENU_REPOS_BGBOTRIGHT: x = rx, y = by; break; } m_canvas->MoveCanvasDrawing(x - m_canvas->GetOriginX(), y - m_canvas->GetOriginY()); m_canvas->RefreshDisplay(); } } void ASSDrawFrame::_Help() { helpcontroller.DisplayContents(); } void ASSDrawFrame::_About(unsigned timeout) { ASSDrawAboutDlg *aboutdlg = new ASSDrawAboutDlg( this, timeout ); aboutdlg->ShowModal(); aboutdlg->Destroy(); } void ASSDrawFrame::OnChoose_Mode(wxCommandEvent& event) { m_canvas->SetDrawMode( (MODE) event.GetId() ); UpdateFrameUI(); } void ASSDrawFrame::OnChoose_DragMode(wxCommandEvent& event) { DRAGMODE dm = m_canvas->GetDragMode(); switch (event.GetId()) { case DRAG_DWG: dm.drawing = !dm.drawing; break; case DRAG_BGIMG: dm.bgimg = !dm.bgimg; break; } m_canvas->SetDragMode( dm ); UpdateFrameUI(); } void ASSDrawFrame::OnZoomSliderChanged(wxScrollEvent &event) { double zoom = (double) event.GetPosition() / 100.0; m_canvas->ChangeZoomLevelTo(zoom, wxPoint((int) m_canvas->GetOriginX(), (int) m_canvas->GetOriginY())); } void ASSDrawFrame::OnToolRClick(wxCommandEvent& event) { int id = event.GetId(); if (drawtbar->FindById(id) != NULL || modetbar->FindById(id) != NULL || bgimgtbar->FindById(id) != NULL) { PopupMenu(tbarMenu); } } void ASSDrawFrame::OnChoose_TBarRClickMenu(wxCommandEvent& event) { int id = event.GetId(); wxToolBar* tbar[3] = { drawtbar, modetbar, bgimgtbar }; bool tb[3] = { false, false, false }; bool show[2] = { false, true }; bool dock[2] = { false, true }; switch (id) { case MENU_TB_ALL: tb[0] = true, tb[1] = true, tb[2] = true; show[0] = true, show[1] = true; break; case MENU_TB_NONE: tb[0] = true, tb[1] = true, tb[2] = true; show[0] = true, show[1] = false; break; case MENU_TB_DOCK: tb[0] = true, tb[1] = true, tb[2] = true; dock[0] = true, dock[1] = true; break; case MENU_TB_UNDOCK: tb[0] = true, tb[1] = true, tb[2] = true; dock[0] = true, dock[1] = false; break; case MENU_TB_DRAW: tb[0] = true; show[0] = true, show[1] = !m_mgr.GetPane(tbar[0]).IsShown(); break; case MENU_TB_MODE: tb[1] = true; show[0] = true, show[1] = !m_mgr.GetPane(tbar[1]).IsShown(); break; case MENU_TB_BGIMG: tb[2] = true; show[0] = true, show[1] = !m_mgr.GetPane(tbar[2]).IsShown(); break; } for (int i = 0; i < 3; i++) { if (tb[i]) { if (show[0]) m_mgr.GetPane(tbar[i]).Show(show[1]); if (dock[0]) if (dock[1]) m_mgr.GetPane(tbar[i]).Dock(); else m_mgr.GetPane(tbar[i]).Float(); } } m_mgr.Update(); UpdateFrameUI(); } void ASSDrawFrame::UpdateASSCommandStringFromSrcTxtCtrl(wxString cmds) { m_canvas->ParseASS(cmds, true); m_canvas->RefreshDisplay(); } void ASSDrawFrame::UpdateASSCommandStringToSrcTxtCtrl(wxString cmd) { if (behaviors.capitalizecmds) cmd.UpperCase(); else cmd.LowerCase(); srctxtctrl->ChangeValue(cmd); //srctxtctrl->AppendText(cmd); } void ASSDrawFrame::UndoOrRedo(bool isundo) { if (isundo) m_canvas->Undo(); else m_canvas->Redo(); UpdateUndoRedoMenu(); UpdateFrameUI(); } void ASSDrawFrame::UpdateUndoRedoMenu() { wxString nextUndo = m_canvas->GetTopUndo(); if (nextUndo.IsSameAs("")) { drawMenu->SetLabel(MENU_UNDO, "Undo\tCtrl+Z"); drawMenu->Enable(MENU_UNDO, false); } else { drawMenu->SetLabel(MENU_UNDO, wxString::Format("Undo: %s\tCtrl+Z", nextUndo.c_str())); drawMenu->Enable(MENU_UNDO, true); } wxString nextRedo = m_canvas->GetTopRedo(); if (nextRedo.IsSameAs("")) { drawMenu->SetLabel(MENU_REDO, "Redo\tCtrl+Y"); drawMenu->Enable(MENU_REDO, false); } else { drawMenu->SetLabel(MENU_REDO, wxString::Format("Redo: %s\tCtrl+Y", nextRedo.c_str())); drawMenu->Enable(MENU_REDO, true); } } void ASSDrawFrame::UpdateFrameUI(unsigned level) { bool hasbg = m_canvas->HasBackgroundImage(); int zoom = (int) round(m_canvas->GetScale() * 100.0); switch (level) { case 0: // all drawtbar->ToggleTool(TB_PREVIEW, m_canvas->IsPreviewMode()); modetbar->ToggleTool(m_canvas->GetDrawMode(), true); #if wxUSE_MENUS drawMenu->Check(MENU_PREVIEW, m_canvas->IsPreviewMode()); modeMenu->Check(m_canvas->GetDrawMode(), true); #endif case 2: // bgimg & toolbars //bgimgtbar->ToggleTool(m_canvas->GetDragMode(), true); bgimgtbar->ToggleTool(DRAG_DWG, m_canvas->GetDragMode().drawing); bgimgtbar->ToggleTool(DRAG_BGIMG, m_canvas->GetDragMode().bgimg); bgimgtbar->EnableTool(DRAG_BGIMG, hasbg); //m_mgr.GetPane(bgimgtbar).Show(hasbg); m_mgr.Update(); #if wxUSE_MENUS viewMenu->Check(MENU_LIBRARY, m_mgr.GetPane(shapelib).IsShown()); if (settingsdlg) viewMenu->Check(MENU_SETTINGS, m_mgr.GetPane(settingsdlg).IsShown()); //bgimgMenu->Check(m_canvas->GetDragMode(), true); bgimgMenu->Check(DRAG_DWG, m_canvas->GetDragMode().drawing); bgimgMenu->Check(DRAG_BGIMG, m_canvas->GetDragMode().bgimg); bgimgMenu->Enable(DRAG_BGIMG, hasbg); bgimgMenu->Enable(DRAG_BOTH, hasbg); bgimgMenu->Enable(MENU_BGIMG_ALPHA, hasbg); bgimgMenu->Enable(MENU_BGIMG_RECENTER, hasbg); bgimgMenu->Enable(MENU_BGIMG_REMOVE, hasbg); tbarMenu->Check(MENU_TB_DRAW, m_mgr.GetPane(drawtbar).IsShown()); tbarMenu->Check(MENU_TB_MODE, m_mgr.GetPane(modetbar).IsShown()); tbarMenu->Check(MENU_TB_BGIMG, m_mgr.GetPane(bgimgtbar).IsShown()); #endif case 3: // zoom slider zoomslider->SetValue(zoom); SetStatusText( wxString::Format("%d%%", zoom), 2 ); zoomslider->Enable(m_canvas->GetDragMode().drawing && m_canvas->CanZoom()); } } void ASSDrawFrame::OnClose(wxCloseEvent &event) { if (event.CanVeto() && behaviors.confirmquit) { if (wxMessageDialog(this, wxT("Do you want to close ASSDraw3 now?"), wxT("Confirmation"), wxOK | wxCANCEL).ShowModal() == wxID_OK) Destroy(); else event.Veto(); } else Destroy(); }