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
23 // - Split out windows/classes defined here into their own files [DONE]
27 // - Fix bug in Glyphpoints when dragging on an empty canvas or loading a font
28 // - Fix scrolling, zooming, settings (ini)
29 // - Fix problem with character window disappearing when bringing up the tool
33 // Uncomment this for debugging...
35 #define DEBUGFOO // Various tool debugging...
36 //#define DEBUGTP // Toolpalette debugging...
38 #include "mainwindow.h"
39 #include "charwindow.h"
40 #include "editwindow.h"
42 #include "previewfiledialog.h"
46 MainWindow::MainWindow()
48 Global::charWnd = new CharWindow(this);
49 editWnd = new EditWindow(this);
50 setCentralWidget(editWnd);
52 setWindowIcon(QIcon(":/res/ttedit.png"));
53 setWindowTitle("TTEdit! - Untitled");
60 scaleIndicator = new QLabel("Scale: 100%");
61 statusBar()->addPermanentWidget(scaleIndicator);
62 statusBar()->showMessage(tr("Ready"));
66 // connect(textEdit->document(), SIGNAL(contentsChanged()),
67 // this, SLOT(documentWasModified()));
69 // setCurrentFile("");
70 setUnifiedTitleAndToolBarOnMac(true);
72 Global::charWnd->show();
77 // Consolidates action creation from a multi-step process to a single-step one.
79 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString
80 statustip, QIcon icon, QKeySequence key, bool checkable/*= false*/)
82 QAction * action = new QAction(icon, name, this);
83 action->setToolTip(tooltip);
84 action->setStatusTip(statustip);
85 action->setShortcut(key);
86 action->setCheckable(checkable);
93 // This is essentially the same as the previous function, but this allows more
94 // than one key sequence to be added as key shortcuts.
96 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString
97 statustip, QIcon icon, QKeySequence key1, QKeySequence key2, bool
100 QAction * action = new QAction(icon, name, this);
101 action->setToolTip(tooltip);
102 action->setStatusTip(statustip);
103 QList<QKeySequence> keyList;
104 keyList.append(key1);
105 keyList.append(key2);
106 action->setShortcuts(keyList);
107 action->setCheckable(checkable);
113 void MainWindow::CreateActions(void)
115 newGlyphAct = CreateAction("&New Glyph", "New Glyph", "Create a new glyph", QIcon(), QKeySequence());
116 openFileAct = CreateAction("&Open File", "Open File", "Open a glyph file", QIcon(), QKeySequence("ctrl+o"));
117 saveFileAct = CreateAction("&Save File", "Save File", "Save a glyph file", QIcon(), QKeySequence("ctrl+s"));
118 quitAct = CreateAction("&Quit", "Quit", "Exits from the TTEdit application", QIcon(), QKeySequence("ctrl+q"));
119 zoomInAct = CreateAction("Zoom In", "Zoom In", "Zoom into the canvas", QIcon(), QKeySequence("+"), QKeySequence("="));
120 zoomOutAct = CreateAction("Zoom Out", "Zoom Out", "Zoom out of the canvas", QIcon(), QKeySequence("-"));
122 connect(newGlyphAct, SIGNAL(triggered()), this, SLOT(NewGlyph()));
123 connect(openFileAct, SIGNAL(triggered()), this, SLOT(OpenFile()));
124 connect(saveFileAct, SIGNAL(triggered()), this, SLOT(SaveFile()));
125 connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));
126 connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomIn()));
127 connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOut()));
131 void MainWindow::CreateMenus(void)
133 QMenu * menu = menuBar()->addMenu(tr("&File"));
134 menu->addAction(newGlyphAct);
135 menu->addAction(openFileAct);
136 menu->addAction(saveFileAct);
137 menu->addSeparator();
138 menu->addAction(quitAct);
139 // menu->addAction(fileSaveAsAct);
140 // menu->addAction(fileCloseAct);
141 menu = menuBar()->addMenu(tr("&View"));
142 menu->addAction(zoomInAct);
143 menu->addAction(zoomOutAct);
147 void MainWindow::CreateToolbars(void)
152 void MainWindow::closeEvent(QCloseEvent * event)
155 event->accept(); // ignore() if can't close for some reason
159 void MainWindow::NewGlyph(void)
161 editWnd->pts.Clear();
162 Global::charWnd->MakePathFromPoints(&(editWnd->pts));
163 Global::charWnd->update();
165 // editWnd->polyFirstPoint = true;
167 setWindowTitle("TTEdit! - Untitled");
172 void MainWindow::OpenFile(void)
175 filename = QFileDialog::getOpenFileName(this, tr("Open Glyph File"),
176 "./", tr("Glyph files (*.glyph)"));
178 PreviewFileDialog * pfd = new PreviewFileDialog(this, tr("Open Glyph File"),
179 "./", tr("Glyph files (*.glyph)"));
180 pfd->setAcceptMode(QFileDialog::AcceptOpen);
182 if (pfd->exec() == false)
185 filename = pfd->selectedFiles().at(0);
187 FILE * file = fopen(filename.toUtf8().data(), "r");
189 //need to pop an error box here...
193 editWnd->pts.LoadGlyphFromFile(file);
196 Global::charWnd->MakePathFromPoints(&(editWnd->pts));
197 Global::charWnd->update();
199 setWindowTitle(QString("TTEdit! - %1").arg(filename));
204 void MainWindow::SaveFile(void)
206 if (filename.isEmpty())
207 filename = QFileDialog::getSaveFileName(this, tr("Save Glyph File"),
208 "./", tr("Glyph files (*.glyph)"));
210 FILE * file = fopen(filename.toUtf8().data(), "w");
212 //need to pop an error box here...
216 editWnd->pts.SaveGlyphToFile(file);
218 setWindowTitle(QString("TTEdit! - %1").arg(filename));
219 statusBar()->showMessage(tr("File saved."));
224 void MainWindow::ZoomIn(void)
226 if (Global::zoom == 4.0)
229 // Adjust the origin by the width/height by 1/4 (half of the scaled size).
230 // Also, need to adjust for the current zoom level...
231 Vector adjustment = (Global::screenSize / Global::zoom) * 0.25;
232 Global::origin += adjustment;
236 scaleIndicator->setText(QString("Scale: %1%").arg(Global::zoom * 100.0));
241 void MainWindow::ZoomOut(void)
243 if (Global::zoom == 0.25)
248 // Adjust the origin by the width/height by 1/4 (half of the scaled size).
249 // Also, need to adjust for the current zoom level...
250 Vector adjustment = (Global::screenSize / Global::zoom) * 0.25;
251 Global::origin -= adjustment;
253 scaleIndicator->setText(QString("Scale: %1%").arg(Global::zoom * 100.0));
258 void MainWindow::ReadSettings(void)
260 QSettings settings("Underground Software", "TTEdit");
261 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
262 QSize size = settings.value("size", QSize(400, 400)).toSize();
265 pos = settings.value("charWndPos", QPoint(0, 0)).toPoint();
266 size = settings.value("charWndSize", QSize(200, 200)).toSize();
267 Global::charWnd->resize(size);
268 Global::charWnd->move(pos);
272 void MainWindow::WriteSettings(void)
274 QSettings settings("Underground Software", "TTEdit");
275 settings.setValue("pos", pos());
276 settings.setValue("size", size());
277 settings.setValue("charWndPos", Global::charWnd->pos());
278 settings.setValue("charWndSize", Global::charWnd->size());
285 IMPLEMENT_APP(TTEditApp) // Run the main application loop
287 bool TTEditApp::OnInit()
289 wxLog * logTarget = new wxLogStderr();//fopen("!ttedit_log.txt", "wb"));
290 wxLog::SetActiveTarget(logTarget);
295 // Initialize all the top-level window members to NULL.
299 for(int i=0; i<8; i++)
302 //Shouldn't we check to see if it was successful? This just assumes
305 mainFrame = new TTEditFrame(NULL, _("TTEdit"), wxPoint(155, 165), wxSize(300, 300),
306 wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE);
307 // wxMINIMIZE_BOX | wxRESIZE_BOX | wxMAXIMIZE_BOX | | wxSYSTEM_MENU | wxCAPTION);
309 // charWin = new CharWindow(NULL);//, _T("Own3d W1nd0w"), wxDefaultPosition, wxDefaultSize);
310 charWin = new CharWindow(mainFrame, _("Own3d W1nd0w"), wxDefaultPosition, wxDefaultSize,
311 wxCAPTION | wxRESIZE_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
313 toolPalette = new ToolWindow(mainFrame, _(""), wxDefaultPosition, wxDefaultSize,
314 wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
319 int TTEditApp::OnExit()
324 for(int i=0; i<8; i++)
332 // OS dependent method of creating cursor (works for Win32 and GTK+)
334 #define CREATE_CURSOR(storage, name, hsx, hsy) \
335 wxBitmap name##_bitmap(name##_xpm); \
336 wxImage name##_image = name##_bitmap.ConvertToImage(); \
337 name##_image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, hsx); \
338 name##_image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hsy); \
339 storage = new wxCursor(name##_image);
341 void TTEditApp::CreateResources(void)
343 // This is a sucky way to create cursors, but at least it's cross-platform...
344 // NOTE: Need to fix hotspots on a few... !!! FIX !!! [DONE]
346 CREATE_CURSOR(cur[0], cur1, 1, 1);
347 CREATE_CURSOR(cur[1], cur2, 1, 1);
348 CREATE_CURSOR(cur[2], cur3, 11, 11); // Prolly won't need this soon (scroll)...
349 CREATE_CURSOR(cur[3], cur4, 15, 13); // Prolly won't need this soon (zoom)...
350 CREATE_CURSOR(cur[4], cur5, 1, 1);
351 CREATE_CURSOR(cur[5], cur6, 1, 1);
352 CREATE_CURSOR(cur[6], cur7, 1, 1);
353 CREATE_CURSOR(cur[7], cur8, 1, 1);
357 BEGIN_EVENT_TABLE(TTEditFrame, wxFrame)
358 EVT_MENU(IDM_OPEN, TTEditFrame::OnOpen)
359 EVT_MENU(IDM_EXIT, TTEditFrame::OnExit)
360 EVT_MENU(IDM_ABOUT, TTEditFrame::OnAbout)
361 EVT_MENU(ID_TBCHARWIN, TTEditFrame::OnCharWindow)
362 EVT_CLOSE(TTEditFrame::OnCloseWindow)
365 TTEditFrame::TTEditFrame(wxFrame * parent, const wxString &title, const wxPoint &pos,
366 const wxSize &size, long style): wxFrame(parent, -1, title, pos, size, style), app(wxGetApp()), mainWindow(NULL)
368 // Initialize child subwindow members (and hopefully avoid subtle bugs)
369 // mainWindow = NULL;
371 SetIcon(wxICON(ttedit));
372 // CreateStatusBar(2); // Create 2 panes
373 int widths[2] = { -1, 120 };
374 wxStatusBar * sb = CreateStatusBar(2, 0); // Create 2 panes
375 sb->SetStatusWidths(2, widths);
376 wxToolBar * tb = CreateToolBar();
382 wxBitmap tool1(tool1_xpm);
383 wxBitmap tool2(tool2_xpm);
384 wxBitmap tool3(tool3_xpm);
386 tb->AddTool(ID_TBLEFT, _("Prev char"), tool1, _("Go to prev char"), wxITEM_NORMAL);
387 tb->AddTool(ID_TBRIGHT, _("Next char"), tool2, _("Go to next char"), wxITEM_NORMAL);
388 tb->AddTool(ID_TBCHARWIN, _("Char Wnd"), tool3, _("Toggle char window"), wxITEM_CHECK);
392 // Create a menu bar for the frame
393 menuBar = new wxMenuBar;
394 wxMenu * menu1 = new wxMenu;
395 menu1->Append(IDM_NEW, _("&New\tCtrl+N"), _("Create a new font."));
396 menu1->Append(IDM_OPEN, _("&Open...\tCtrl+O"), _("Opens an existing font."));
397 menu1->Append(IDM_SAVE, _("&Save\tCtrl+S"), _("Save the current font."));
398 menu1->Append(IDM_SAVEAS, _("Save &As..."), _("Save the current font under a different name."));
399 menu1->AppendSeparator();
400 menu1->Append(IDM_EXIT, _("E&xit\tAlt+X"), _("Quits the TTEdit program."));
401 menuBar->Append(menu1, _("&File"));
402 wxMenu * menu2 = new wxMenu;
403 menu2->Append(IDM_HELPTOPICS, _("&Help Topics"), _("Displays the Help contents and index."));
404 menu2->AppendSeparator();
405 menu2->Append(IDM_ABOUT, _("&About TTEdit"), _("Displays information about TTEdit."));
406 menuBar->Append(menu2, _("&Help"));
409 // Create child subwindows
410 mainWindow = new TTEditWindow(this);
412 Centre(wxBOTH); // Centre frame on the screen
413 Show(true); // Show the frame
416 TTEditFrame::~TTEditFrame()
420 void TTEditFrame::OnOpen(wxCommandEvent &e)
422 wxFileDialog fd(this, _("Choose a font to load"), _(""), _(""), _("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN);
424 if (fd.ShowModal() != wxID_OK)
427 // Hmm. The font object is causing a massive crash... (gdb says it's in "Load")
428 if (app.font.Load((char *)fd.GetPath().c_str()) != true)
430 wxMessageDialog dlg(NULL, _("Load font failed!"), _("Houston, we have a problem..."), wxOK | wxICON_ERROR);
434 //Huzzah! It works! Now just need scaling, scrolling, etc...
435 // pts = app.font.GetGlyphPoints(45);
438 void TTEditFrame::OnAbout(wxCommandEvent &e)
440 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);
444 void TTEditFrame::OnExit(wxCommandEvent &e)
446 app.toolPalette->Destroy();
450 void TTEditFrame::OnCharWindow(wxCommandEvent &e)
452 app.charWin->Show(e.IsChecked() ? true : false);
458 void TTEditFrame::OnCloseWindow(wxCloseEvent &e)
460 app.toolPalette->Destroy();