]> Shamusworld >> Repos - ttedit/blob - src/mainwindow.cpp
Added preview window to file loading dialog. :-)
[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
22 //   [DONE]
23 // - Split out windows/classes defined here into their own files [DONE]
24 //
25 // STILL TO BE DONE:
26 //
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
30 //   palette
31 //
32
33 // Uncomment this for debugging...
34 #define DEBUG
35 #define DEBUGFOO                        // Various tool debugging...
36 //#define DEBUGTP                               // Toolpalette debugging...
37
38 #include "mainwindow.h"
39 #include "charwindow.h"
40 #include "editwindow.h"
41 #include "global.h"
42 #include "previewfiledialog.h"
43 #include "ttedit.h"
44
45
46 MainWindow::MainWindow()
47 {
48         Global::charWnd = new CharWindow(this);
49         editWnd = new EditWindow(this);
50         setCentralWidget(editWnd);
51         editWnd->setFocus();
52         setWindowIcon(QIcon(":/res/ttedit.png"));
53         setWindowTitle("TTEdit! - Untitled");
54
55         CreateActions();
56         CreateMenus();
57         CreateToolbars();
58
59         //      Create status bar
60         scaleIndicator = new QLabel("Scale: 100%");
61         statusBar()->addPermanentWidget(scaleIndicator);
62         statusBar()->showMessage(tr("Ready"));
63
64         ReadSettings();
65
66 //      connect(textEdit->document(), SIGNAL(contentsChanged()),
67 //                      this, SLOT(documentWasModified()));
68
69 //      setCurrentFile("");
70         setUnifiedTitleAndToolBarOnMac(true);
71
72         Global::charWnd->show();
73 }
74
75
76 //
77 // Consolidates action creation from a multi-step process to a single-step one.
78 //
79 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString
80         statustip, QIcon icon, QKeySequence key, bool checkable/*= false*/)
81 {
82         QAction * action = new QAction(icon, name, this);
83         action->setToolTip(tooltip);
84         action->setStatusTip(statustip);
85         action->setShortcut(key);
86         action->setCheckable(checkable);
87
88         return action;
89 }
90
91
92 //
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.
95 //
96 QAction * MainWindow::CreateAction(QString name, QString tooltip, QString
97         statustip, QIcon icon, QKeySequence key1, QKeySequence key2, bool
98         checkable/*= false*/)
99 {
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);
108
109         return action;
110 }
111
112
113 void MainWindow::CreateActions(void)
114 {
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("-"));
121
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()));
128 }
129
130
131 void MainWindow::CreateMenus(void)
132 {
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);
144 }
145
146
147 void MainWindow::CreateToolbars(void)
148 {
149 }
150
151
152 void MainWindow::closeEvent(QCloseEvent * event)
153 {
154         WriteSettings();
155         event->accept(); // ignore() if can't close for some reason
156 }
157
158
159 void MainWindow::NewGlyph(void)
160 {
161         editWnd->pts.Clear();
162         Global::charWnd->MakePathFromPoints(&(editWnd->pts));
163         Global::charWnd->update();
164         filename.clear();
165 //      editWnd->polyFirstPoint = true;
166         editWnd->update();
167         setWindowTitle("TTEdit! - Untitled");
168         editWnd->setFocus();
169 }
170
171
172 void MainWindow::OpenFile(void)
173 {
174 #if 0
175         filename = QFileDialog::getOpenFileName(this, tr("Open Glyph File"),
176                 "./", tr("Glyph files (*.glyph)"));
177 #else
178         PreviewFileDialog * pfd = new PreviewFileDialog(this, tr("Open Glyph File"),
179                 "./", tr("Glyph files (*.glyph)"));
180         pfd->setAcceptMode(QFileDialog::AcceptOpen);
181
182         if (pfd->exec() == false)
183                 return;
184
185         filename = pfd->selectedFiles().at(0);
186 #endif
187         FILE * file = fopen(filename.toUtf8().data(), "r");
188
189         //need to pop an error box here...
190         if (file == 0)
191                 return;
192
193         editWnd->pts.LoadGlyphFromFile(file);
194         fclose(file);
195
196         Global::charWnd->MakePathFromPoints(&(editWnd->pts));
197         Global::charWnd->update();
198         editWnd->update();
199         setWindowTitle(QString("TTEdit! - %1").arg(filename));
200         editWnd->setFocus();
201 }
202
203
204 void MainWindow::SaveFile(void)
205 {
206         if (filename.isEmpty())
207                 filename = QFileDialog::getSaveFileName(this, tr("Save Glyph File"),
208                 "./", tr("Glyph files (*.glyph)"));
209
210         FILE * file = fopen(filename.toUtf8().data(), "w");
211
212         //need to pop an error box here...
213         if (file == 0)
214                 return;
215
216         editWnd->pts.SaveGlyphToFile(file);
217         fclose(file);
218         setWindowTitle(QString("TTEdit! - %1").arg(filename));
219         statusBar()->showMessage(tr("File saved."));
220         editWnd->setFocus();
221 }
222
223
224 void MainWindow::ZoomIn(void)
225 {
226         if (Global::zoom == 4.0)
227                 return;
228
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;
233
234         Global::zoom *= 2.0;
235
236         scaleIndicator->setText(QString("Scale: %1%").arg(Global::zoom * 100.0));
237         editWnd->update();
238 }
239
240
241 void MainWindow::ZoomOut(void)
242 {
243         if (Global::zoom == 0.25)
244                 return;
245
246         Global::zoom *= 0.5;
247
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;
252
253         scaleIndicator->setText(QString("Scale: %1%").arg(Global::zoom * 100.0));
254         editWnd->update();
255 }
256
257
258 void MainWindow::ReadSettings(void)
259 {
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();
263         resize(size);
264         move(pos);
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);
269 }
270
271
272 void MainWindow::WriteSettings(void)
273 {
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());
279 }
280
281
282 #if 0
283
284
285 IMPLEMENT_APP(TTEditApp)                                                // Run the main application loop
286
287 bool TTEditApp::OnInit()
288 {
289         wxLog * logTarget = new wxLogStderr();//fopen("!ttedit_log.txt", "wb"));
290         wxLog::SetActiveTarget(logTarget);
291 #ifdef DEBUG
292         OpenDebugLog();
293 #endif
294
295         // Initialize all the top-level window members to NULL.
296         mainFrame = NULL;
297         charWin = NULL;
298         toolPalette = NULL;
299         for(int i=0; i<8; i++)
300                 cur[i] = NULL;
301
302 //Shouldn't we check to see if it was successful? This just assumes
303         CreateResources();
304
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);
308
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);
312
313         toolPalette = new ToolWindow(mainFrame, _(""), wxDefaultPosition, wxDefaultSize,
314                 wxBORDER_NONE | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT);
315
316         return true;
317 }
318
319 int TTEditApp::OnExit()
320 {
321 #ifdef DEBUG
322         CloseDebugLog();
323 #endif
324         for(int i=0; i<8; i++)
325                 if (cur[i])
326                         delete cur[i];
327
328         return 0;
329 }
330
331 //
332 // OS dependent method of creating cursor (works for Win32 and GTK+)
333 //
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);
340
341 void TTEditApp::CreateResources(void)
342 {
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]
345
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);
354 }
355
356
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)
363 END_EVENT_TABLE()
364
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)
367 {
368         // Initialize child subwindow members (and hopefully avoid subtle bugs)
369 //      mainWindow = NULL;
370
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();
377
378         if (tb != NULL)
379         {
380                 // Create buttons
381
382                 wxBitmap tool1(tool1_xpm);
383                 wxBitmap tool2(tool2_xpm);
384                 wxBitmap tool3(tool3_xpm);
385
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);
389                 tb->Realize();
390         }
391
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"));
407         SetMenuBar(menuBar);
408
409         // Create child subwindows
410         mainWindow = new TTEditWindow(this);
411
412         Centre(wxBOTH);                                                         // Centre frame on the screen
413         Show(true);                                                                     // Show the frame
414 }
415
416 TTEditFrame::~TTEditFrame()
417 {
418 }
419
420 void TTEditFrame::OnOpen(wxCommandEvent &e)
421 {
422         wxFileDialog fd(this, _("Choose a font to load"), _(""), _(""), _("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN);
423
424         if (fd.ShowModal() != wxID_OK)
425             return;
426
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)
429         {
430                 wxMessageDialog dlg(NULL, _("Load font failed!"), _("Houston, we have a problem..."), wxOK | wxICON_ERROR);
431                 dlg.ShowModal();
432         }
433
434 //Huzzah! It works! Now just need scaling, scrolling, etc...
435 //      pts = app.font.GetGlyphPoints(45);
436 }
437
438 void TTEditFrame::OnAbout(wxCommandEvent &e)
439 {
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);
441         dlg.ShowModal();
442 }
443
444 void TTEditFrame::OnExit(wxCommandEvent &e)
445 {
446         app.toolPalette->Destroy();
447         this->Destroy();
448 }
449
450 void TTEditFrame::OnCharWindow(wxCommandEvent &e)
451 {
452         app.charWin->Show(e.IsChecked() ? true : false);
453
454         if (e.IsChecked())
455                 Raise();
456 }
457
458 void TTEditFrame::OnCloseWindow(wxCloseEvent &e)
459 {
460         app.toolPalette->Destroy();
461         this->Destroy();
462 }
463 #endif