blob: 5f5746b6325bcf60e9015c62289cfc2e8e0ee124 [file] [log] [blame]
Robert Phillipsa6d2d702017-09-01 12:17:03 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include <QtWidgets>
9
10#include "MainWindow.h"
11
Robert Phillips5fccf9d2017-09-05 15:10:12 -040012MainWindow::MainWindow() {
Robert Phillipsa6d2d702017-09-01 12:17:03 -040013 this->createActions();
14 this->createStatusBar();
Robert Phillips5fccf9d2017-09-05 15:10:12 -040015 this->createDockWindows();
16
17 this->setWindowTitle("MDB Viz");
18
Robert Phillipsa6d2d702017-09-01 12:17:03 -040019 this->readSettings();
20 this->setUnifiedTitleAndToolBarOnMac(true);
21}
22
23void MainWindow::openFile() {
24 QString fileName = QFileDialog::getOpenFileName(this);
25 if (!fileName.isEmpty()) {
26 this->loadFile(fileName);
27 }
28}
29
Robert Phillips5fccf9d2017-09-05 15:10:12 -040030void MainWindow::setupOpListWidget() {
31 fOpListWidget->clear();
32
Robert Phillips276066b2017-09-06 17:17:44 -040033 QTreeWidgetItem* item = nullptr;
34 SkTDArray<QTreeWidgetItem*> parents;
35
Robert Phillipsdeaf5682017-09-06 13:07:21 -040036 for (int i = 0; i < fModel.numOps(); i++) {
Robert Phillips276066b2017-09-06 17:17:44 -040037 item = new QTreeWidgetItem();
Robert Phillips5fccf9d2017-09-05 15:10:12 -040038
Robert Phillips276066b2017-09-06 17:17:44 -040039 item->setText(0, QString::number(i));
40 item->setData(0, Qt::UserRole, i);
41 item->setText(1, fModel.getOpName(i));
Robert Phillips5fccf9d2017-09-05 15:10:12 -040042
Robert Phillips276066b2017-09-06 17:17:44 -040043 if (fModel.isHierarchyPop(i)) {
44 parents.pop();
45 }
46
47 if (parents.isEmpty()) {
48 fOpListWidget->addTopLevelItem(item);
49 } else {
50 parents.top()->addChild(item);
51 }
52
53 if (fModel.isHierarchyPush(i)) {
54 *parents.push() = item;
55 }
Robert Phillips5fccf9d2017-09-05 15:10:12 -040056 }
Robert Phillipsdeaf5682017-09-06 13:07:21 -040057
Robert Phillips276066b2017-09-06 17:17:44 -040058 fOpListWidget->setCurrentItem(item);
59 fOpListWidget->expandToDepth(100);
Robert Phillipsdeaf5682017-09-06 13:07:21 -040060}
61
62void MainWindow::presentCurrentRenderState() {
63 fImage = QImage((uchar*)fModel.getPixels(), fModel.width(), fModel.height(),
64 QImage::Format_RGBA8888);
65 fImageLabel->setPixmap(QPixmap::fromImage(fImage));
Robert Phillips5fccf9d2017-09-05 15:10:12 -040066}
67
Robert Phillipsa6d2d702017-09-01 12:17:03 -040068void MainWindow::loadFile(const QString &fileName) {
69 QFile file(fileName);
70 if (!file.open(QFile::ReadOnly | QFile::Text)) {
71 QMessageBox::warning(this, tr("MDB Viz"),
72 tr("Cannot read file %1:\n%2.")
73 .arg(QDir::toNativeSeparators(fileName), file.errorString()));
74 return;
75 }
76
77 QTextStream in(&file);
78#ifndef QT_NO_CURSOR
79 QApplication::setOverrideCursor(Qt::WaitCursor);
80#endif
81
82 std::string str = file.fileName().toLocal8Bit().constData();
83
Robert Phillipsdeaf5682017-09-06 13:07:21 -040084 Model::ErrorCode err = fModel.load(str.c_str());
85 if (Model::ErrorCode::kOK != err) {
86 this->statusBar()->showMessage(Model::ErrorString(err));
Robert Phillipsa6d2d702017-09-01 12:17:03 -040087 return;
88 }
Robert Phillips5fccf9d2017-09-05 15:10:12 -040089
90 this->setupOpListWidget();
Robert Phillipsdeaf5682017-09-06 13:07:21 -040091 this->presentCurrentRenderState();
Robert Phillipsa6d2d702017-09-01 12:17:03 -040092
93#ifndef QT_NO_CURSOR
94 QApplication::restoreOverrideCursor();
95#endif
96}
97
Robert Phillips5fccf9d2017-09-05 15:10:12 -040098
99void MainWindow::about() {
100 QMessageBox::about(this, "About MDB Viz", "Visualize MDB");
101}
102
Robert Phillipsa6d2d702017-09-01 12:17:03 -0400103void MainWindow::createActions() {
104
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400105 // File menu
106 QMenu* fileMenu = this->menuBar()->addMenu(tr("&File"));
107 QToolBar* fileToolBar = this->addToolBar(tr("File"));
Robert Phillipsa6d2d702017-09-01 12:17:03 -0400108
109 const QIcon openIcon = QIcon::fromTheme("document-open", QIcon(":/images/open.png"));
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400110 QAction* openAct = new QAction(openIcon, tr("&Open..."), this);
Robert Phillipsa6d2d702017-09-01 12:17:03 -0400111 openAct->setShortcuts(QKeySequence::Open);
112 openAct->setStatusTip(tr("Open an existing file"));
113 connect(openAct, &QAction::triggered, this, &MainWindow::openFile);
114 fileMenu->addAction(openAct);
115 fileToolBar->addAction(openAct);
116
117 fileMenu->addSeparator();
118
119 const QIcon exitIcon = QIcon::fromTheme("application-exit");
120 QAction *exitAct = fileMenu->addAction(exitIcon, tr("E&xit"), this, &QWidget::close);
121 exitAct->setShortcuts(QKeySequence::Quit);
122 exitAct->setStatusTip(tr("Exit the application"));
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400123
124 // View menu
125 fViewMenu = this->menuBar()->addMenu(tr("&View"));
126
127 // Help menu
128 this->menuBar()->addSeparator();
129
130 QMenu* helpMenu = this->menuBar()->addMenu(tr("&Help"));
131
132 QAction *aboutAct = helpMenu->addAction(tr("&About"), this, &MainWindow::about);
133 aboutAct->setStatusTip(tr("Show the application's About box"));
Robert Phillipsa6d2d702017-09-01 12:17:03 -0400134}
135
Robert Phillips276066b2017-09-06 17:17:44 -0400136void MainWindow::onCurrentItemChanged(QTreeWidgetItem* cur, QTreeWidgetItem* /* prev */) {
137 int currentRow = cur->data(0, Qt::UserRole).toInt();
Robert Phillipsdeaf5682017-09-06 13:07:21 -0400138 fModel.setCurOp(currentRow);
139 this->presentCurrentRenderState();
140}
141
Robert Phillipsa6d2d702017-09-01 12:17:03 -0400142void MainWindow::createStatusBar() {
143 this->statusBar()->showMessage(tr("Ready"));
144}
145
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400146void MainWindow::createDockWindows() {
147
148 // Op List Window
149 {
150 QDockWidget* opListDock = new QDockWidget("Ops", this);
151 opListDock->setAllowedAreas(Qt::LeftDockWidgetArea);
152
Robert Phillips276066b2017-09-06 17:17:44 -0400153 fOpListWidget = new QTreeWidget(opListDock);
154
155 QTreeWidgetItem* headerItem = new QTreeWidgetItem;
156 headerItem->setText(0, "Index");
157 headerItem->setText(1, "Op Name");
158 fOpListWidget->setHeaderItem(headerItem);
159
160 fOpListWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
161 fOpListWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400162
163 opListDock->setWidget(fOpListWidget);
164 this->addDockWidget(Qt::LeftDockWidgetArea, opListDock);
165
166 fViewMenu->addAction(opListDock->toggleViewAction());
Robert Phillipsdeaf5682017-09-06 13:07:21 -0400167
Robert Phillips276066b2017-09-06 17:17:44 -0400168 connect(fOpListWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
169 this, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400170 }
171
172 // Main canvas Window
173 {
174 QDockWidget* mainCanvasDock = new QDockWidget("Main Canvas", this);
175 mainCanvasDock->setAllowedAreas(Qt::RightDockWidgetArea);
176
177 fImageLabel = new QLabel(mainCanvasDock);
178
Robert Phillips276066b2017-09-06 17:17:44 -0400179 fImage = QImage(1024, 1024, QImage::Format_RGBA8888);
180 fImage.fill(0);
181 fImageLabel->setPixmap(QPixmap::fromImage(fImage));
182
Robert Phillips5fccf9d2017-09-05 15:10:12 -0400183 mainCanvasDock->setWidget(fImageLabel);
184 this->addDockWidget(Qt::RightDockWidgetArea, mainCanvasDock);
185
186 fViewMenu->addAction(mainCanvasDock->toggleViewAction());
187 }
188}
189
Robert Phillipsa6d2d702017-09-01 12:17:03 -0400190void MainWindow::readSettings() {
191 QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
192 const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
193 if (geometry.isEmpty()) {
194 const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
195 resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
196 move((availableGeometry.width() - width()) / 2,
197 (availableGeometry.height() - height()) / 2);
198 } else {
199 this->restoreGeometry(geometry);
200 }
201}
202
203void MainWindow::writeSettings() {
204 QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
205 settings.setValue("geometry", this->saveGeometry());
206}