forked from mia/Aegisub
e7f2dc00f7
Originally committed to SVN as r3184.
793 lines
28 KiB
C++
793 lines
28 KiB
C++
/*
|
|
* 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 <wx/clipbrd.h>
|
|
#include <wx/wfstream.h>
|
|
#include <wx/filename.h>
|
|
#include <wx/dynlib.h>
|
|
#include <wx/stdpaths.h>
|
|
|
|
#if !defined(__WINDOWS__)
|
|
#include "xpm/res.h"
|
|
#endif
|
|
|
|
/////////////
|
|
// Libraries
|
|
#ifdef __VISUALC__
|
|
#pragma comment(lib, "Vfw32.lib")
|
|
#pragma comment(lib, "comctl32.lib")
|
|
#pragma comment(lib, "rpcrt4.lib")
|
|
#pragma comment(lib, "winmm.lib")
|
|
#pragma comment(lib, "advapi32.lib")
|
|
#pragma comment(lib, "wsock32.lib")
|
|
#ifdef __WXDEBUG__
|
|
#pragma comment(lib, "wxmsw28ud_propgrid.lib")
|
|
#else
|
|
#pragma comment(lib, "wxmsw28u_propgrid.lib")
|
|
#endif
|
|
#endif
|
|
|
|
|
|
//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 _T("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);
|
|
#ifndef __UNIX__
|
|
m_mgr.SetFlags(m_mgr.GetFlags() | wxAUI_MGR_ALLOW_ACTIVE_PANE);
|
|
#else
|
|
m_mgr.SetFlags(wxAUI_MGR_ALLOW_FLOATING | wxAUI_MGR_ALLOW_ACTIVE_PANE | wxAUI_MGR_RECTANGLE_HINT);
|
|
#endif
|
|
|
|
// 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(), _T("settings.dll")).GetFullPath();
|
|
|
|
if (::wxFileExists(settingsdllfile))
|
|
{
|
|
wxDynamicLibrary settingsdll(settingsdllfile);
|
|
wxString symbol(_T("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(_T("settings")).Caption(_T("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(_T("version"), &version);
|
|
config->SetPath(_T(".."));
|
|
|
|
default_perspective = m_mgr.SavePerspective(); // back up default perspective
|
|
config->SetPath(_T("perspective"));
|
|
wxString perspective;
|
|
if (config->Read(_T("perspective"), &perspective) && version == VERSION) m_mgr.LoadPerspective(perspective, false);
|
|
config->SetPath(_T(".."));
|
|
|
|
config->SetPath(_T("library"));
|
|
int n = 0;
|
|
config->Read(_T("n"), &n);
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
wxString libcmds;
|
|
config->Read(wxString::Format(_T("%d"),i), &libcmds);
|
|
shapelib->AddShapePreview(libcmds);
|
|
}
|
|
config->SetPath(_T(".."));
|
|
|
|
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, _T("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?"), _T("Beta version"), wxYES_NO | wxICON_INFORMATION);
|
|
if (expired.ShowModal() == wxID_YES)
|
|
::wxLaunchDefaultBrowser(wxString(_T("http://malakith.net/aegisub/index.php?topic=912.0")));
|
|
Close();
|
|
}
|
|
SetTitle(wxString::Format(_T("%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(), _T("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, _T(""), TIPS_CLEAR);
|
|
//tbar->AddTool(TB_EDITSRC, _T("Source"), wxBITMAP(src_), wxNullBitmap, wxITEM_NORMAL, _T(""), TIPS_EDITSRC);
|
|
drawtbar->AddCheckTool(TB_PREVIEW, _T("Preview"), wxBITMAP(preview_), wxNullBitmap, _T(""), TIPS_PREVIEW);
|
|
//drawtbar->AddTool(TB_TRANSFORM, _T("Transform"), wxBITMAP(rot_), wxNullBitmap, wxITEM_NORMAL, _T(""), 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(_T("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, _T(""), TIPS_ARR);
|
|
modetbar->AddRadioTool(MODE_M, _T("Move"), wxBITMAP(m_), wxNullBitmap, _T(""), TIPS_M);
|
|
//modetbar->AddRadioTool(MODE_N, _T("Move*"), wxBITMAP(n_), wxNullBitmap, _T(""), TIPS_N);
|
|
modetbar->AddRadioTool(MODE_L, _T("Line"), wxBITMAP(l_), wxNullBitmap, _T(""), TIPS_L);
|
|
modetbar->AddRadioTool(MODE_B, _T("Bezier"), wxBITMAP(b_), wxNullBitmap, _T(""), TIPS_B);
|
|
//modetbar->AddRadioTool(MODE_S, _T("Spline"), wxBITMAP(s_), wxNullBitmap, _T(""), TIPS_S);
|
|
//modetbar->AddRadioTool(MODE_P, _T("Extend"), wxBITMAP(p_), wxNullBitmap, _T(""), TIPS_P);
|
|
//modetbar->AddRadioTool(MODE_C, _T("Close"), wxBITMAP(c_), wxNullBitmap, _T(""), TIPS_C);
|
|
modetbar->AddRadioTool(MODE_DEL, _T("Delete"), wxBITMAP(del_), wxNullBitmap, _T(""), TIPS_DEL);
|
|
modetbar->AddRadioTool(MODE_SCALEROTATE, _T("Scale/Rotate"), wxBITMAP(sc_rot_), wxNullBitmap, _T(""), TIPS_SCALEROTATE);
|
|
modetbar->AddRadioTool(MODE_NUT_BILINEAR, _T("Bilinear"), wxBITMAP(nut_), wxNullBitmap, _T(""), TIPS_NUTB);
|
|
//modetbar->AddRadioTool(MODE_NUT_PERSPECTIVE, _T("NUT:P"), wxBITMAP(arr_), wxNullBitmap, _T(""), _T(""));
|
|
modetbar->Realize();
|
|
|
|
m_mgr.AddPane(modetbar, wxAuiPaneInfo().Name(_T("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, _T(""), TIPS_DWG);
|
|
bgimgtbar->AddCheckTool(DRAG_BGIMG, _T("Pan background"), wxBITMAP(pan_bg), wxNullBitmap, _T(""), TIPS_BGIMG);
|
|
//bgimgtbar->AddRadioTool(DRAG_BOTH, _T("Pan both"), wxBITMAP(pan_both), wxNullBitmap, _T(""), TIPS_BOTH);
|
|
bgimgtbar->Realize();
|
|
|
|
m_mgr.AddPane(bgimgtbar, wxAuiPaneInfo().Name(_T("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"), _T(""));
|
|
wxMenu* reposbgMenu = new wxMenu;
|
|
reposbgMenu->Append( MENU_REPOS_BGTOPLEFT, _T("Top left\tCtrl+Shift+7") );
|
|
reposbgMenu->Append( MENU_REPOS_BGTOPRIGHT, _T("Top right\tCtrl+Shift+9") );
|
|
reposbgMenu->Append( MENU_REPOS_BGCENTER, _T("&Center\tCtrl+Shift+5") );
|
|
reposbgMenu->Append( MENU_REPOS_BGBOTLEFT, _T("Bottom left\tCtrl+Shift+1") );
|
|
reposbgMenu->Append( MENU_REPOS_BGBOTRIGHT, _T("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"), _T(""));
|
|
|
|
wxMenu* reposMenu = new wxMenu;
|
|
reposMenu->Append( MENU_REPOS_TOPLEFT, _T("Top left\tCtrl+7") );
|
|
reposMenu->Append( MENU_REPOS_TOPRIGHT, _T("Top right\tCtrl+9") );
|
|
reposMenu->Append( MENU_REPOS_CENTER, _T("&Center\tCtrl+5") );
|
|
reposMenu->Append( MENU_REPOS_BOTLEFT, _T("Bottom left\tCtrl+1") );
|
|
reposMenu->Append( MENU_REPOS_BOTRIGHT, _T("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, _T("Show all"));
|
|
tbarMenu->Append(MENU_TB_NONE, _T("Hide all"));
|
|
tbarMenu->Append(MENU_TB_DOCK, _T("Dock all"));
|
|
tbarMenu->Append(MENU_TB_UNDOCK, _T("Undock all"));
|
|
|
|
viewMenu = new wxMenu;
|
|
viewMenu->Append(MENU_LIBRARY, _T("&Library"), TIPS_LIBRARY, wxITEM_CHECK);
|
|
if (settingsdlg)
|
|
viewMenu->Append(MENU_SETTINGS, _T("&Settings"), _T(""), 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(_T("library")).Caption(_T("Shapes Library")).
|
|
Right().Layer(2).Position(0).CloseButton(true).BestSize(wxSize(120, 480)).MinSize(wxSize(100, 200)));
|
|
|
|
m_mgr.AddPane(m_canvas, wxAuiPaneInfo().Name(_T("canvas")).CenterPane());
|
|
|
|
m_mgr.AddPane(srctxtctrl, wxAuiPaneInfo().Name(_T("commands")).Caption(_T("Drawing commands")).
|
|
Bottom().Layer(1).CloseButton(false).BestSize(wxSize(320, 48)));
|
|
|
|
if (settingsdlg)
|
|
m_mgr.AddPane(settingsdlg, wxAuiPaneInfo().Name(_T("settings")).Caption(_T("Settings")).
|
|
Right().Layer(3).Position(0).CloseButton(true).BestSize(wxSize(240, 480)).MinSize(wxSize(200, 200)).Show(false));
|
|
}
|
|
|
|
ASSDrawFrame::~ASSDrawFrame()
|
|
{
|
|
config->SetPath(_T("info"));
|
|
config->Write(_T("assdraw3.exe"), wxStandardPaths::Get().GetExecutablePath());
|
|
config->Write(_T("version"), VERSION);
|
|
config->SetPath(_T(".."));
|
|
|
|
SaveSettings();
|
|
|
|
config->SetPath(_T("perspective"));
|
|
config->Write(_T("perspective"), m_mgr.SavePerspective());
|
|
config->SetPath(_T(".."));
|
|
|
|
config->DeleteGroup(_T("library"));
|
|
config->SetPath(_T("library"));
|
|
typedef std::vector< ASSDrawShapePreview *> PrevVec;
|
|
PrevVec shapes = shapelib->GetShapePreviews();
|
|
int n = shapes.size();
|
|
config->Write(_T("n"), n);
|
|
for (int i = 0; i < n; i++)
|
|
config->Write(wxString::Format(_T("%d"),i), shapes[i]->GenerateASS());
|
|
config->SetPath(_T(".."));
|
|
|
|
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(_T("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(_T("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(_T("")))
|
|
{
|
|
drawMenu->SetLabel(MENU_UNDO, _T("Undo\tCtrl+Z"));
|
|
drawMenu->Enable(MENU_UNDO, false);
|
|
}
|
|
else
|
|
{
|
|
drawMenu->SetLabel(MENU_UNDO, wxString::Format(_T("Undo: %s\tCtrl+Z"), nextUndo.c_str()));
|
|
drawMenu->Enable(MENU_UNDO, true);
|
|
}
|
|
wxString nextRedo = m_canvas->GetTopRedo();
|
|
if (nextRedo.IsSameAs(_T("")))
|
|
{
|
|
drawMenu->SetLabel(MENU_REDO, _T("Redo\tCtrl+Y"));
|
|
drawMenu->Enable(MENU_REDO, false);
|
|
}
|
|
else
|
|
{
|
|
drawMenu->SetLabel(MENU_REDO, wxString::Format(_T("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) ((m_canvas->GetScale() * 100.0)+0.5);
|
|
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(_T("%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, _T("Do you want to close ASSDraw3 now?"), _T("Confirmation"), wxOK | wxCANCEL).ShowModal() == wxID_OK)
|
|
Destroy();
|
|
else
|
|
event.Veto();
|
|
}
|
|
else
|
|
Destroy();
|
|
}
|