]> Shamusworld >> Repos - ttedit/blob - src/mainwindow.cpp
dea9087af7bf9496ed81a93fd60475091567f55e
[ttedit] / src / mainwindow.cpp
1 //
2 // MAINWINDOW.CPP - The TrueType Editor
3 // by James L. Hammons
4 // (C) 2004 Underground Software
5 //
6 // JLH = James L. Hammons <jlhamm@acm.org>
7 //
8 // Who  When        What
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
17 //
18
19 // FIXED:
20 //
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]
23 //
24 // STILL TO BE DONE:
25 //
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
29 //   palette
30 //
31
32 // Uncomment this for debugging...
33 #define DEBUG
34 #define DEBUGFOO                        // Various tool debugging...
35 //#define DEBUGTP                               // Toolpalette debugging...
36
37 #include "mainwindow.h"
38 #include "charwindow.h"
39 #include "editwindow.h"
40 #include "ttedit.h"
41
42
43 MainWindow::MainWindow()
44 {
45         ((TTEdit *)qApp)->charWnd = new CharWindow(this);
46         editWnd = new EditWindow(this);
47         setCentralWidget(editWnd);
48         editWnd->setFocus();
49         setWindowIcon(QIcon(":/res/ttedit.png"));
50         setWindowTitle("TTEdit!");
51
52 #if 0
53 //      createActions();
54         newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
55         newAct->setShortcuts(QKeySequence::New);
56         newAct->setStatusTip(tr("Create a new file"));
57         connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
58
59         openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
60         openAct->setShortcuts(QKeySequence::Open);
61         openAct->setStatusTip(tr("Open an existing file"));
62         connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
63
64         aboutQtAct = new QAction(tr("About &Qt"), this);
65         aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
66         connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
67
68 //      createMenus();
69         fileMenu = menuBar()->addMenu(tr("&File"));
70         fileMenu->addAction(newAct);
71         fileMenu->addAction(openAct);
72         fileMenu->addAction(saveAct);
73         fileMenu->addAction(saveAsAct);
74         fileMenu->addSeparator();
75         fileMenu->addAction(exitAct);
76
77         editMenu = menuBar()->addMenu(tr("&Edit"));
78         editMenu->addAction(cutAct);
79         editMenu->addAction(copyAct);
80         editMenu->addAction(pasteAct);
81
82         menuBar()->addSeparator();
83
84         helpMenu = menuBar()->addMenu(tr("&Help"));
85         helpMenu->addAction(aboutAct);
86         helpMenu->addAction(aboutQtAct);
87
88 //      createToolBars();
89         fileToolBar = addToolBar(tr("File"));
90         fileToolBar->addAction(newAct);
91         fileToolBar->addAction(openAct);
92         fileToolBar->addAction(saveAct);
93
94         editToolBar = addToolBar(tr("Edit"));
95         editToolBar->addAction(cutAct);
96         editToolBar->addAction(copyAct);
97         editToolBar->addAction(pasteAct);
98 #else
99         CreateActions();
100         CreateMenus();
101         CreateToolbars();
102 #endif
103
104         //      Create status bar
105         statusBar()->showMessage(tr("Ready"));
106
107         ReadSettings();
108
109 //      connect(textEdit->document(), SIGNAL(contentsChanged()),
110 //                      this, SLOT(documentWasModified()));
111
112 //      setCurrentFile("");
113         setUnifiedTitleAndToolBarOnMac(true);
114
115         ((TTEdit *)qApp)->charWnd->show();//eh?
116 }
117
118
119 //
120 // Consolidates action creation from a multi-step process to a single-step one.
121 //
122 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString statustip,
123         QIcon icon, QKeySequence key, bool checkable/*= false*/)
124 {
125         QAction * action = new QAction(icon, name, this);
126         action->setToolTip(tooltip);
127         action->setStatusTip(statustip);
128         action->setShortcut(key);
129         action->setCheckable(checkable);
130
131         return action;
132 }
133
134
135 //
136 // This is essentially the same as the previous function, but this allows more
137 // than one key sequence to be added as key shortcuts.
138 //
139 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString statustip,
140         QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
141 {
142         QAction * action = new QAction(icon, name, this);
143         action->setToolTip(tooltip);
144         action->setStatusTip(statustip);
145         QList<QKeySequence> keyList;
146         keyList.append(key1);
147         keyList.append(key2);
148         action->setShortcuts(keyList);
149         action->setCheckable(checkable);
150
151         return action;
152 }
153
154
155 void MainWindow::CreateActions(void)
156 {
157         newGlyphAct = CreateAction("&New Glyph", "New Glyph", "Create a new glyph", QIcon(), QKeySequence());
158         openFileAct = CreateAction("&Open File", "Open File", "Open a glyph file", QIcon(), QKeySequence());
159         saveFileAct = CreateAction("&Save File", "Save File", "Save a glyph file", QIcon(), QKeySequence());
160
161         connect(newGlyphAct, SIGNAL(triggered()), this, SLOT(NewGlyph()));
162         connect(openFileAct, SIGNAL(triggered()), this, SLOT(OpenFile()));
163         connect(saveFileAct, SIGNAL(triggered()), this, SLOT(SaveFile()));
164 }
165
166
167 void MainWindow::CreateMenus(void)
168 {
169         QMenu * menu = menuBar()->addMenu(tr("&File"));
170         menu->addAction(newGlyphAct);
171         menu->addAction(openFileAct);
172         menu->addAction(saveFileAct);
173 //      menu->addAction(fileSaveAsAct);
174 //      menu->addAction(fileCloseAct);
175 }
176
177
178 void MainWindow::CreateToolbars(void)
179 {
180 }
181
182
183 void MainWindow::closeEvent(QCloseEvent * event)
184 {
185         WriteSettings();
186         event->accept(); // ignore() if can't close for some reason
187 }
188
189
190 void MainWindow::NewGlyph(void)
191 {
192         editWnd->pts.Clear();
193         ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&(editWnd->pts));
194         ((TTEdit *)qApp)->charWnd->update();
195 //      editWnd->polyFirstPoint = true;
196         editWnd->update();
197 }
198
199
200 void MainWindow::OpenFile(void)
201 {
202         QString filename = QFileDialog::getOpenFileName(this, tr("Open Glyph File"),
203                 "./", tr("Glyph files (*.glyph)"));
204         FILE * file = fopen(filename.toUtf8().data(), "r");
205
206         //need to pop an error box here...
207         if (file == 0)
208                 return;
209
210         editWnd->pts.LoadGlyphFromFile(file);
211         fclose(file);
212
213         ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&(editWnd->pts));
214         ((TTEdit *)qApp)->charWnd->update();
215         editWnd->update();
216 }
217
218
219 void MainWindow::SaveFile(void)
220 {
221         QString filename = QFileDialog::getSaveFileName(this, tr("Save Glyph File"),
222                 "./", tr("Glyph files (*.glyph)"));
223         FILE * file = fopen(filename.toUtf8().data(), "w");
224
225         //need to pop an error box here...
226         if (file == 0)
227                 return;
228
229         editWnd->pts.SaveGlyphToFile(file);
230         fclose(file);
231 }
232
233
234 void MainWindow::ReadSettings(void)
235 {
236         QSettings settings("Underground Software", "TTEdit");
237         QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
238         QSize size = settings.value("size", QSize(400, 400)).toSize();
239         resize(size);
240         move(pos);
241         pos = settings.value("charWndPos", QPoint(0, 0)).toPoint();
242         size = settings.value("charWndSize", QSize(200, 200)).toSize();
243         ((TTEdit *)qApp)->charWnd->resize(size);
244         ((TTEdit *)qApp)->charWnd->move(pos);
245 }
246
247
248 void MainWindow::WriteSettings(void)
249 {
250         QSettings settings("Underground Software", "TTEdit");
251         settings.setValue("pos", pos());
252         settings.setValue("size", size());
253         settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos());
254         settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size());
255 }
256
257
258 #if 0
259
260
261 IMPLEMENT_APP(TTEditApp)                                                // Run the main application loop
262
263 bool TTEditApp::OnInit()
264 {
265         wxLog * logTarget = new wxLogStderr();//fopen("!ttedit_log.txt", "wb"));
266         wxLog::SetActiveTarget(logTarget);
267 #ifdef DEBUG
268         OpenDebugLog();
269 #endif
270
271         // Initialize all the top-level window members to NULL.
272         mainFrame = NULL;
273         charWin = NULL;
274         toolPalette = NULL;
275         for(int i=0; i<8; i++)
276                 cur[i] = NULL;
277
278 //Shouldn't we check to see if it was successful? This just assumes
279         CreateResources();
280
281         mainFrame = new TTEditFrame(NULL, _("TTEdit"), wxPoint(155, 165), wxSize(300, 300),
282                 wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE);
283 //              wxMINIMIZE_BOX | wxRESIZE_BOX | wxMAXIMIZE_BOX | | wxSYSTEM_MENU | wxCAPTION);
284
285 //      charWin = new CharWindow(NULL);//, _T("Own3d W1nd0w"), wxDefaultPosition, wxDefaultSize);
286         charWin = new CharWindow(mainFrame, _("Own3d W1nd0w"), wxDefaultPosition, wxDefaultSize,
287                 wxCAPTION | wxRESIZE_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
288
289         toolPalette = new ToolWindow(mainFrame, _(""), wxDefaultPosition, wxDefaultSize,
290                 wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
291
292         return true;
293 }
294
295 int TTEditApp::OnExit()
296 {
297 #ifdef DEBUG
298         CloseDebugLog();
299 #endif
300         for(int i=0; i<8; i++)
301                 if (cur[i])
302                         delete cur[i];
303
304         return 0;
305 }
306
307 //
308 // OS dependent method of creating cursor (works for Win32 and GTK+)
309 //
310 #define CREATE_CURSOR(storage, name, hsx, hsy) \
311         wxBitmap name##_bitmap(name##_xpm); \
312         wxImage name##_image = name##_bitmap.ConvertToImage(); \
313         name##_image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, hsx); \
314         name##_image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hsy); \
315         storage = new wxCursor(name##_image);
316
317 void TTEditApp::CreateResources(void)
318 {
319         // This is a sucky way to create cursors, but at least it's cross-platform...
320         // NOTE: Need to fix hotspots on a few... !!! FIX !!! [DONE]
321
322         CREATE_CURSOR(cur[0], cur1, 1, 1);
323         CREATE_CURSOR(cur[1], cur2, 1, 1);
324         CREATE_CURSOR(cur[2], cur3, 11, 11);    // Prolly won't need this soon (scroll)...
325         CREATE_CURSOR(cur[3], cur4, 15, 13);    // Prolly won't need this soon (zoom)...
326         CREATE_CURSOR(cur[4], cur5, 1, 1);
327         CREATE_CURSOR(cur[5], cur6, 1, 1);
328         CREATE_CURSOR(cur[6], cur7, 1, 1);
329         CREATE_CURSOR(cur[7], cur8, 1, 1);
330 }
331
332
333 BEGIN_EVENT_TABLE(TTEditFrame, wxFrame)
334         EVT_MENU(IDM_OPEN, TTEditFrame::OnOpen)
335         EVT_MENU(IDM_EXIT, TTEditFrame::OnExit)
336         EVT_MENU(IDM_ABOUT, TTEditFrame::OnAbout)
337         EVT_MENU(ID_TBCHARWIN, TTEditFrame::OnCharWindow)
338         EVT_CLOSE(TTEditFrame::OnCloseWindow)
339 END_EVENT_TABLE()
340
341 TTEditFrame::TTEditFrame(wxFrame * parent, const wxString &title, const wxPoint &pos,
342         const wxSize &size, long style): wxFrame(parent, -1, title, pos, size, style), app(wxGetApp()), mainWindow(NULL)
343 {
344         // Initialize child subwindow members (and hopefully avoid subtle bugs)
345 //      mainWindow = NULL;
346
347         SetIcon(wxICON(ttedit));
348 //      CreateStatusBar(2);                                                     // Create 2 panes
349         int widths[2] = { -1, 120 };
350         wxStatusBar * sb = CreateStatusBar(2, 0);       // Create 2 panes
351         sb->SetStatusWidths(2, widths);
352         wxToolBar * tb = CreateToolBar();
353
354         if (tb != NULL)
355         {
356                 // Create buttons
357
358                 wxBitmap tool1(tool1_xpm);
359                 wxBitmap tool2(tool2_xpm);
360                 wxBitmap tool3(tool3_xpm);
361
362                 tb->AddTool(ID_TBLEFT, _("Prev char"), tool1, _("Go to prev char"), wxITEM_NORMAL);
363                 tb->AddTool(ID_TBRIGHT, _("Next char"), tool2, _("Go to next char"), wxITEM_NORMAL);
364                 tb->AddTool(ID_TBCHARWIN, _("Char Wnd"), tool3, _("Toggle char window"), wxITEM_CHECK);
365                 tb->Realize();
366         }
367
368         // Create a menu bar for the frame
369         menuBar = new wxMenuBar;
370         wxMenu * menu1 = new wxMenu;
371         menu1->Append(IDM_NEW, _("&New\tCtrl+N"), _("Create a new font."));
372         menu1->Append(IDM_OPEN, _("&Open...\tCtrl+O"), _("Opens an existing font."));
373         menu1->Append(IDM_SAVE, _("&Save\tCtrl+S"), _("Save the current font."));
374         menu1->Append(IDM_SAVEAS, _("Save &As..."), _("Save the current font under a different name."));
375         menu1->AppendSeparator();
376         menu1->Append(IDM_EXIT, _("E&xit\tAlt+X"), _("Quits the TTEdit program."));
377         menuBar->Append(menu1, _("&File"));
378         wxMenu * menu2 = new wxMenu;
379         menu2->Append(IDM_HELPTOPICS, _("&Help Topics"), _("Displays the Help contents and index."));
380         menu2->AppendSeparator();
381         menu2->Append(IDM_ABOUT, _("&About TTEdit"), _("Displays information about TTEdit."));
382         menuBar->Append(menu2, _("&Help"));
383         SetMenuBar(menuBar);
384
385         // Create child subwindows
386         mainWindow = new TTEditWindow(this);
387
388         Centre(wxBOTH);                                                         // Centre frame on the screen
389         Show(true);                                                                     // Show the frame
390 }
391
392 TTEditFrame::~TTEditFrame()
393 {
394 }
395
396 void TTEditFrame::OnOpen(wxCommandEvent &e)
397 {
398         wxFileDialog fd(this, _("Choose a font to load"), _(""), _(""), _("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN);
399
400         if (fd.ShowModal() != wxID_OK)
401             return;
402
403 // Hmm. The font object is causing a massive crash... (gdb says it's in "Load")
404         if (app.font.Load((char *)fd.GetPath().c_str()) != true)
405         {
406                 wxMessageDialog dlg(NULL, _("Load font failed!"), _("Houston, we have a problem..."), wxOK | wxICON_ERROR);
407                 dlg.ShowModal();
408         }
409
410 //Huzzah! It works! Now just need scaling, scrolling, etc...
411 //      pts = app.font.GetGlyphPoints(45);
412 }
413
414 void TTEditFrame::OnAbout(wxCommandEvent &e)
415 {
416         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);
417         dlg.ShowModal();
418 }
419
420 void TTEditFrame::OnExit(wxCommandEvent &e)
421 {
422         app.toolPalette->Destroy();
423         this->Destroy();
424 }
425
426 void TTEditFrame::OnCharWindow(wxCommandEvent &e)
427 {
428         app.charWin->Show(e.IsChecked() ? true : false);
429
430         if (e.IsChecked())
431                 Raise();
432 }
433
434 void TTEditFrame::OnCloseWindow(wxCloseEvent &e)
435 {
436         app.toolPalette->Destroy();
437         this->Destroy();
438 }
439 #endif