2 // MAINWINDOW.CPP - The TrueType Editor
4 // (C) 2004 Underground Software
6 // JLH = James L. Hammons <jlhamm@acm.org>
9 // --- ---------- -------------------------------------------------------------
10 // JLH 04/10/2002 Created this file
11 // JLH 05/10/2004 Translated file from ASM to CPP
12 // JLH 05/14/2004 Added rudimentary editing capability to tool palette tools
13 // JLH 11/18/2006 Initial port to Linux
14 // JLH 08/27/2008 Fixed tool palette focus problems
15 // JLH 08/28/2008 Split out classes defined here into separate files
16 // JLH 03/05/2009 Initial conversion from wxWidgets to Qt
21 // - Fix problem with tool palette not getting focus 1st time it's called up [DONE]
22 // - Split out windows/classes defined here into their own files [DONE]
26 // - Fix bug in Glyphpoints when dragging on an empty canvas or loading a font
27 // - Fix scrolling, zooming, settings (ini)
28 // - Fix problem with character window disappearing when bringing up the tool
32 // Uncomment this for debugging...
34 #define DEBUGFOO // Various tool debugging...
35 //#define DEBUGTP // Toolpalette debugging...
37 #include "mainwindow.h"
38 #include "charwindow.h"
39 #include "editwindow.h"
43 MainWindow::MainWindow()
45 ((TTEdit *)qApp)->charWnd = new CharWindow(this);
46 editWnd = new EditWindow(this);
47 setCentralWidget(editWnd);
48 setWindowIcon(QIcon(":/res/ttedit.png"));
49 setWindowTitle("TTEdit!");
53 newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
54 newAct->setShortcuts(QKeySequence::New);
55 newAct->setStatusTip(tr("Create a new file"));
56 connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
58 openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
59 openAct->setShortcuts(QKeySequence::Open);
60 openAct->setStatusTip(tr("Open an existing file"));
61 connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
63 aboutQtAct = new QAction(tr("About &Qt"), this);
64 aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
65 connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
68 fileMenu = menuBar()->addMenu(tr("&File"));
69 fileMenu->addAction(newAct);
70 fileMenu->addAction(openAct);
71 fileMenu->addAction(saveAct);
72 fileMenu->addAction(saveAsAct);
73 fileMenu->addSeparator();
74 fileMenu->addAction(exitAct);
76 editMenu = menuBar()->addMenu(tr("&Edit"));
77 editMenu->addAction(cutAct);
78 editMenu->addAction(copyAct);
79 editMenu->addAction(pasteAct);
81 menuBar()->addSeparator();
83 helpMenu = menuBar()->addMenu(tr("&Help"));
84 helpMenu->addAction(aboutAct);
85 helpMenu->addAction(aboutQtAct);
88 fileToolBar = addToolBar(tr("File"));
89 fileToolBar->addAction(newAct);
90 fileToolBar->addAction(openAct);
91 fileToolBar->addAction(saveAct);
93 editToolBar = addToolBar(tr("Edit"));
94 editToolBar->addAction(cutAct);
95 editToolBar->addAction(copyAct);
96 editToolBar->addAction(pasteAct);
104 statusBar()->showMessage(tr("Ready"));
108 // connect(textEdit->document(), SIGNAL(contentsChanged()),
109 // this, SLOT(documentWasModified()));
111 // setCurrentFile("");
112 setUnifiedTitleAndToolBarOnMac(true);
114 ((TTEdit *)qApp)->charWnd->show();//eh?
119 // Consolidates action creation from a multi-step process to a single-step one.
121 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString statustip,
122 QIcon icon, QKeySequence key, bool checkable/*= false*/)
124 QAction * action = new QAction(icon, name, this);
125 action->setToolTip(tooltip);
126 action->setStatusTip(statustip);
127 action->setShortcut(key);
128 action->setCheckable(checkable);
135 // This is essentially the same as the previous function, but this allows more
136 // than one key sequence to be added as key shortcuts.
138 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString statustip,
139 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
141 QAction * action = new QAction(icon, name, this);
142 action->setToolTip(tooltip);
143 action->setStatusTip(statustip);
144 QList<QKeySequence> keyList;
145 keyList.append(key1);
146 keyList.append(key2);
147 action->setShortcuts(keyList);
148 action->setCheckable(checkable);
154 void MainWindow::CreateActions(void)
156 newGlyphAct = CreateAction("&New Glyph", "New Glyph", "Create a new glyph", QIcon(), QKeySequence());
157 openFileAct = CreateAction("&Open File", "Open File", "Open a glyph file", QIcon(), QKeySequence());
158 saveFileAct = CreateAction("&Save File", "Save File", "Save a glyph file", QIcon(), QKeySequence());
160 connect(newGlyphAct, SIGNAL(triggered()), this, SLOT(NewGlyph()));
161 connect(openFileAct, SIGNAL(triggered()), this, SLOT(OpenFile()));
162 connect(saveFileAct, SIGNAL(triggered()), this, SLOT(SaveFile()));
166 void MainWindow::CreateMenus(void)
168 QMenu * menu = menuBar()->addMenu(tr("&File"));
169 menu->addAction(newGlyphAct);
170 menu->addAction(openFileAct);
171 menu->addAction(saveFileAct);
172 // menu->addAction(fileSaveAsAct);
173 // menu->addAction(fileCloseAct);
177 void MainWindow::CreateToolbars(void)
182 void MainWindow::closeEvent(QCloseEvent * event)
185 event->accept(); // ignore() if can't close for some reason
189 void MainWindow::NewGlyph(void)
191 editWnd->pts.Clear();
192 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&(editWnd->pts));
193 ((TTEdit *)qApp)->charWnd->update();
198 void MainWindow::OpenFile(void)
200 QString filename = QFileDialog::getOpenFileName(this, tr("Open Glyph File"),
201 "./", tr("Glyph files (*.glyph)"));
202 FILE * file = fopen(filename.toAscii().data(), "r");
204 //need to pop an error box here...
208 editWnd->pts.LoadGlyphFromFile(file);
211 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&(editWnd->pts));
212 ((TTEdit *)qApp)->charWnd->update();
217 void MainWindow::SaveFile(void)
219 QString filename = QFileDialog::getSaveFileName(this, tr("Save Glyph File"),
220 "./", tr("Glyph files (*.glyph)"));
221 FILE * file = fopen(filename.toAscii().data(), "w");
223 //need to pop an error box here...
227 editWnd->pts.SaveGlyphToFile(file);
232 void MainWindow::ReadSettings(void)
234 QSettings settings("Underground Software", "TTEdit");
235 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
236 QSize size = settings.value("size", QSize(400, 400)).toSize();
239 pos = settings.value("charWndPos", QPoint(0, 0)).toPoint();
240 size = settings.value("charWndSize", QSize(200, 200)).toSize();
241 ((TTEdit *)qApp)->charWnd->resize(size);
242 ((TTEdit *)qApp)->charWnd->move(pos);
246 void MainWindow::WriteSettings(void)
248 QSettings settings("Underground Software", "TTEdit");
249 settings.setValue("pos", pos());
250 settings.setValue("size", size());
251 settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos());
252 settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size());
258 #include "charwindow.h"
259 #include "toolwindow.h"
260 #include "editwindow.h"
261 #include "tte_res.h" // Resource IDs
268 #include "res/cur1.xpm"
269 #include "res/cur2.xpm"
270 #include "res/cur3.xpm"
271 #include "res/cur4.xpm"
272 #include "res/cur5.xpm"
273 #include "res/cur6.xpm"
274 #include "res/cur7.xpm"
275 #include "res/cur8.xpm"
276 #include "res/ttedit.xpm" // *nix only, but small enough to not matter
277 #include "res/tool1.xpm"
278 #include "res/tool2.xpm"
279 #include "res/tool3.xpm"
282 IMPLEMENT_APP(TTEditApp) // Run the main application loop
284 bool TTEditApp::OnInit()
286 wxLog * logTarget = new wxLogStderr();//fopen("!ttedit_log.txt", "wb"));
287 wxLog::SetActiveTarget(logTarget);
292 // Initialize all the top-level window members to NULL.
296 for(int i=0; i<8; i++)
299 //Shouldn't we check to see if it was successful? This just assumes
302 mainFrame = new TTEditFrame(NULL, _("TTEdit"), wxPoint(155, 165), wxSize(300, 300),
303 wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE);
304 // wxMINIMIZE_BOX | wxRESIZE_BOX | wxMAXIMIZE_BOX | | wxSYSTEM_MENU | wxCAPTION);
306 // charWin = new CharWindow(NULL);//, _T("Own3d W1nd0w"), wxDefaultPosition, wxDefaultSize);
307 charWin = new CharWindow(mainFrame, _("Own3d W1nd0w"), wxDefaultPosition, wxDefaultSize,
308 wxCAPTION | wxRESIZE_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
310 toolPalette = new ToolWindow(mainFrame, _(""), wxDefaultPosition, wxDefaultSize,
311 wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
316 int TTEditApp::OnExit()
321 for(int i=0; i<8; i++)
329 // OS dependent method of creating cursor (works for Win32 and GTK+)
331 #define CREATE_CURSOR(storage, name, hsx, hsy) \
332 wxBitmap name##_bitmap(name##_xpm); \
333 wxImage name##_image = name##_bitmap.ConvertToImage(); \
334 name##_image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, hsx); \
335 name##_image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hsy); \
336 storage = new wxCursor(name##_image);
338 void TTEditApp::CreateResources(void)
340 // This is a sucky way to create cursors, but at least it's cross-platform...
341 // NOTE: Need to fix hotspots on a few... !!! FIX !!! [DONE]
343 CREATE_CURSOR(cur[0], cur1, 1, 1);
344 CREATE_CURSOR(cur[1], cur2, 1, 1);
345 CREATE_CURSOR(cur[2], cur3, 11, 11); // Prolly won't need this soon (scroll)...
346 CREATE_CURSOR(cur[3], cur4, 15, 13); // Prolly won't need this soon (zoom)...
347 CREATE_CURSOR(cur[4], cur5, 1, 1);
348 CREATE_CURSOR(cur[5], cur6, 1, 1);
349 CREATE_CURSOR(cur[6], cur7, 1, 1);
350 CREATE_CURSOR(cur[7], cur8, 1, 1);
354 BEGIN_EVENT_TABLE(TTEditFrame, wxFrame)
355 EVT_MENU(IDM_OPEN, TTEditFrame::OnOpen)
356 EVT_MENU(IDM_EXIT, TTEditFrame::OnExit)
357 EVT_MENU(IDM_ABOUT, TTEditFrame::OnAbout)
358 EVT_MENU(ID_TBCHARWIN, TTEditFrame::OnCharWindow)
359 EVT_CLOSE(TTEditFrame::OnCloseWindow)
362 TTEditFrame::TTEditFrame(wxFrame * parent, const wxString &title, const wxPoint &pos,
363 const wxSize &size, long style): wxFrame(parent, -1, title, pos, size, style), app(wxGetApp()), mainWindow(NULL)
365 // Initialize child subwindow members (and hopefully avoid subtle bugs)
366 // mainWindow = NULL;
368 SetIcon(wxICON(ttedit));
369 // CreateStatusBar(2); // Create 2 panes
370 int widths[2] = { -1, 120 };
371 wxStatusBar * sb = CreateStatusBar(2, 0); // Create 2 panes
372 sb->SetStatusWidths(2, widths);
373 wxToolBar * tb = CreateToolBar();
379 wxBitmap tool1(tool1_xpm);
380 wxBitmap tool2(tool2_xpm);
381 wxBitmap tool3(tool3_xpm);
383 tb->AddTool(ID_TBLEFT, _("Prev char"), tool1, _("Go to prev char"), wxITEM_NORMAL);
384 tb->AddTool(ID_TBRIGHT, _("Next char"), tool2, _("Go to next char"), wxITEM_NORMAL);
385 tb->AddTool(ID_TBCHARWIN, _("Char Wnd"), tool3, _("Toggle char window"), wxITEM_CHECK);
389 // Create a menu bar for the frame
390 menuBar = new wxMenuBar;
391 wxMenu * menu1 = new wxMenu;
392 menu1->Append(IDM_NEW, _("&New\tCtrl+N"), _("Create a new font."));
393 menu1->Append(IDM_OPEN, _("&Open...\tCtrl+O"), _("Opens an existing font."));
394 menu1->Append(IDM_SAVE, _("&Save\tCtrl+S"), _("Save the current font."));
395 menu1->Append(IDM_SAVEAS, _("Save &As..."), _("Save the current font under a different name."));
396 menu1->AppendSeparator();
397 menu1->Append(IDM_EXIT, _("E&xit\tAlt+X"), _("Quits the TTEdit program."));
398 menuBar->Append(menu1, _("&File"));
399 wxMenu * menu2 = new wxMenu;
400 menu2->Append(IDM_HELPTOPICS, _("&Help Topics"), _("Displays the Help contents and index."));
401 menu2->AppendSeparator();
402 menu2->Append(IDM_ABOUT, _("&About TTEdit"), _("Displays information about TTEdit."));
403 menuBar->Append(menu2, _("&Help"));
406 // Create child subwindows
407 mainWindow = new TTEditWindow(this);
409 Centre(wxBOTH); // Centre frame on the screen
410 Show(true); // Show the frame
413 TTEditFrame::~TTEditFrame()
417 void TTEditFrame::OnOpen(wxCommandEvent &e)
419 wxFileDialog fd(this, _("Choose a font to load"), _(""), _(""), _("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN);
421 if (fd.ShowModal() != wxID_OK)
424 // Hmm. The font object is causing a massive crash... (gdb says it's in "Load")
425 if (app.font.Load((char *)fd.GetPath().c_str()) != true)
427 wxMessageDialog dlg(NULL, _("Load font failed!"), _("Houston, we have a problem..."), wxOK | wxICON_ERROR);
431 //Huzzah! It works! Now just need scaling, scrolling, etc...
432 // pts = app.font.GetGlyphPoints(45);
435 void TTEditFrame::OnAbout(wxCommandEvent &e)
437 wxMessageDialog dlg(NULL, _("TrueType Edit v1.0.1\n\nA handy tool for editing TrueType fonts!\nby James \"Shamus\" Hammons\n(C) 2006 Underground Software"), _("About TrueType Edit"), wxOK | wxICON_INFORMATION);
441 void TTEditFrame::OnExit(wxCommandEvent &e)
443 app.toolPalette->Destroy();
447 void TTEditFrame::OnCharWindow(wxCommandEvent &e)
449 app.charWin->Show(e.IsChecked() ? true : false);
455 void TTEditFrame::OnCloseWindow(wxCloseEvent &e)
457 app.toolPalette->Destroy();