Gui.cpp
Go to the documentation of this file.00001 #include "Gui.h" 00002 #include "OpenGLCanvas.h" 00003 #include "ImageCanvas.h" 00004 #include "RenderThread.h" 00005 00006 #include <milton.h> 00007 #include <QtGui> 00008 00009 #include <fstream> 00010 #include <typeinfo> 00011 #include <iostream> 00012 using namespace std; 00013 00014 void Gui::_init(const std::string &title) { 00015 QPalette plastique; 00016 QApplication::setStyle("plastique"); 00017 00018 QColor brightText, base, highlight, button, mid, 00019 text, windowText, buttonText, window, 00020 highlightedText; 00021 00022 highlightedText.setRgb(255,255,255); 00023 base.setRgb(255,255,255); 00024 highlight.setRgb(157, 187, 227); 00025 button.setRgb(240,240,240); 00026 mid.setRgb(75,75,75); 00027 brightText.setRgb(0,0,0); 00028 text.setRgb(0,0,0); 00029 windowText.setRgb(0,0,0); 00030 buttonText.setRgb(0,0,0); 00031 window.setRgb(255,255,255); 00032 00033 plastique.setBrush(QPalette::HighlightedText, highlightedText); 00034 plastique.setBrush(QPalette::BrightText, brightText); 00035 plastique.setBrush(QPalette::Base, base); 00036 plastique.setBrush(QPalette::Highlight, highlight); 00037 plastique.setBrush(QPalette::Button, button); 00038 plastique.setBrush(QPalette::Mid, mid); 00039 plastique.setBrush(QPalette::Text, text); 00040 plastique.setBrush(QPalette::WindowText, windowText); 00041 plastique.setBrush(QPalette::ButtonText, buttonText); 00042 plastique.setBrush(QPalette::Window, window); 00043 00044 QApplication::setPalette(plastique); 00045 00046 setWindowTitle(QString(title.c_str())); 00047 setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks); 00048 00049 QMenu *file = menuBar()->addMenu(QString("&File")); 00050 QMenu *options = menuBar()->addMenu(QString("&Options")); 00051 00052 m_lastSaved = "/map/gfx0/users/tfischer/mlt/data/renders"; 00053 00054 /* FILE */ 00055 file->addAction(QString("&Load Scene"), this, SLOT(loadPressed())); 00056 file->addAction(QString("&Save Render"), this, SLOT(savePressed())); 00057 file->addSeparator(); 00058 00059 file->addAction(QString("&Quit"), qApp, SLOT(quit())); 00060 00061 /* OPTIONS */ 00062 options->addAction(QString("Render"), this, SLOT(renderPressed())); 00063 options->addSeparator(); 00064 00065 m_enableAccelPreview = options->addAction(QString("Preview Mesh kd-Trees"), this, SLOT(enableAccelPreviewChanged())); 00066 m_enableDefaultLighting = options->addAction(QString("Enable Default Lighting"), this, SLOT(enableDefaultLightingChanged())); 00067 00068 options->addSeparator(); 00069 00070 m_enableAccelPreview->setCheckable(true); 00071 m_enableDefaultLighting->setCheckable(true); 00072 00073 m_enableAccelPreview->setChecked(ResourceManager::getValue<bool>("enableAccelPreview", false)); 00074 m_enableDefaultLighting->setChecked(ResourceManager::getValue<bool>("enableDefaultLighting", true)); 00075 00076 00077 ASSERT(m_enableDefaultLighting->isChecked() == ResourceManager::getValue<bool>("enableDefaultLighting")); 00078 00079 m_wire = options->addAction(QString("Wireframe"), this, SLOT(drawModeChanged())); 00080 QAction *action = options->addAction(QString("Solid"), this, SLOT(drawModeChanged())); 00081 m_wire->setCheckable(true); 00082 action->setCheckable(true); 00083 00084 QActionGroup *actionGroup = new QActionGroup(this); 00085 actionGroup->setExclusive(true); 00086 actionGroup->addAction(m_wire); 00087 actionGroup->addAction(action); 00088 00089 m_wire->setChecked(false); 00090 action->setChecked(true); 00091 00092 layout()->setSizeConstraint(QLayout::SetFixedSize); 00093 } 00094 00095 /*bool Gui::loadScene(const char *sceneFile, ParseData &data) { 00096 MiltonJSONSceneLoader loader; 00097 00098 if (!loader.parse(sceneFile, data)) { 00099 cerr << "Parse error: " << data.error << endl; 00100 QMessageBox::warning(this, "Warning", 00101 QString("Error loading scenefile (%1): %2").arg( 00102 sceneFile, QString(data.error.c_str()))); 00103 return false; 00104 } 00105 00106 return true; 00107 }*/ 00108 00109 void Gui::addCanvas(Canvas *canvas, const char* title) { 00110 // All dockwidgets must go into same area if you want them to be tabbed 00111 Qt::DockWidgetArea area = Qt::RightDockWidgetArea; 00112 00113 setUpdatesEnabled(false); 00114 00115 CanvasContainer *container = new CanvasContainer(canvas, title); 00116 addDockWidget(area, container); 00117 if (!m_canvases.isEmpty()) 00118 tabifyDockWidget(m_canvases.top(), container); 00119 00120 m_canvases.push(container); 00121 00122 setUpdatesEnabled(true); 00123 00124 // Notify canvas when mesh properties are modified 00125 00126 if (canvas->supportsOpenGL()) { 00127 OpenGLCanvas *openGLCanvas = NULL; 00128 00129 try { 00130 openGLCanvas = dynamic_cast<OpenGLCanvas*>(canvas); 00131 } catch(std::bad_cast &) { } 00132 00133 if (openGLCanvas) { 00134 connect(this, SIGNAL(drawModeChanged(int)), openGLCanvas, 00135 SLOT(setDrawMode(int))); 00136 } 00137 } else { 00138 ImageCanvas *imageCanvas = NULL; 00139 00140 try { 00141 imageCanvas = dynamic_cast<ImageCanvas*>(canvas); 00142 } catch(std::bad_cast &) { } 00143 00144 if (imageCanvas) { 00145 connect(this, SIGNAL(render()), imageCanvas, SLOT(render())); 00146 } 00147 } 00148 } 00149 00150 void Gui::addCanvas(Canvas* canvas) { 00151 addCanvas(canvas, "Canvas"); 00152 } 00153 00154 void Gui::drawModeChanged() { 00155 emit drawModeChanged(!((int)m_wire->isChecked())); 00156 } 00157 00158 void Gui::loadPressed() { 00159 QMessageBox::warning(this, "Warning", 00160 QString("scene loading currently unsupported")); 00161 00162 return; 00163 00164 #if 0 00165 const QString &fileName = QFileDialog::getOpenFileName( 00166 this, 00167 "Choose a scenefile to open", 00168 "/map/gfx0/users/mjacobs/cs197/src/gui/scenes"); 00169 00170 if (fileName.isEmpty()) 00171 return; 00172 00173 const char *sceneFile = fileName.toAscii().data(); 00174 00175 /* Set the busy cursor for the app */ 00176 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 00177 00178 ParseData data(true); 00179 00180 loadScene(sceneFile, data); 00181 00182 /* Set it back to the normal cursor */ 00183 QApplication::restoreOverrideCursor(); 00184 #endif 00185 } 00186 00187 void Gui::savePressed() { 00188 const QString &fileName = QFileDialog::getSaveFileName( 00189 this, 00190 "Choose a filename to save to", 00191 m_lastSaved.c_str(), 00192 "Images (*.png *.jpg *.tiff)"); 00193 00194 if (fileName.isEmpty()) 00195 return; 00196 00197 // TODO: on Windows, use '\' as separator 00198 m_lastSaved = fileName.left(fileName.lastIndexOf('/')).toAscii().data(); 00199 00200 Canvas *active = _getActiveCanvas("Select the canvas you would like to save:"); 00201 00202 if (active) { 00203 bool success = active->save(fileName.toAscii().data()); 00204 00205 if (!success) 00206 QMessageBox::warning(this, "Error", QString("Could not save to file '%1'").arg(fileName)); 00207 } 00208 } 00209 00210 void Gui::renderPressed() { 00211 foreach(CanvasContainer *container, m_canvases) { 00212 if (container != NULL) { 00213 Canvas *canvas = container->getCanvas(); 00214 ASSERT(canvas); 00215 00216 if (!canvas->supportsOpenGL()) { 00217 ImageCanvas *imageCanvas = dynamic_cast<ImageCanvas*>(canvas); 00218 ASSERT(imageCanvas); 00219 00220 Renderer *renderer = imageCanvas->getRenderer(); 00221 00222 if (renderer) { 00223 memset(imageCanvas->getData(), 0, 00224 imageCanvas->getWidth() * imageCanvas->getHeight() * 00225 sizeof(struct Rgba32)); 00226 00227 imageCanvas->update(); 00228 00229 // TODO: take care of memory leak here 00230 RenderThread *thread = new RenderThread(renderer); 00231 thread->start(); 00232 } 00233 } 00234 } 00235 } 00236 } 00237 00238 void Gui::enableAccelPreviewChanged() { 00239 bool enabled = m_enableAccelPreview->isChecked(); 00240 ResourceManager::insert<bool>("enableAccelPreview", enabled); 00241 ASSERT(ResourceManager::getValue<bool>("enableAccelPreview") == enabled); 00242 00243 _redrawAll(); 00244 } 00245 00246 void Gui::enableDefaultLightingChanged() { 00247 bool enabled = m_enableDefaultLighting->isChecked(); 00248 ResourceManager::insert<bool>("enableDefaultLighting", enabled); 00249 ASSERT(ResourceManager::getValue<bool>("enableDefaultLighting") == enabled); 00250 00251 _redrawAll(); 00252 } 00253 00254 void Gui::_redrawAll() { 00255 foreach(CanvasContainer *container, m_canvases) { 00256 if (container) { 00257 Canvas *canvas = container->getCanvas(); 00258 00259 if (canvas) 00260 canvas->redraw(); 00261 } 00262 } 00263 } 00264 00265 void Gui::selectComboBox(int index) { 00266 m_selectedCombo = index; 00267 } 00268 00269 Canvas *Gui::_getActiveCanvas(const char *text) { 00270 Canvas *visible = NULL; 00271 00272 QComboBox *available = new QComboBox(this); 00273 foreach(CanvasContainer *container, m_canvases) { 00274 if (container != NULL) { 00275 available->addItem(container->getTitle()); 00276 visible = container->getCanvas(); 00277 } 00278 } 00279 00280 if (available->count() <= 1 && visible) 00281 return visible; 00282 00283 connect(available, SIGNAL(currentIndexChanged(int)), this, SLOT(selectComboBox(int))); 00284 00285 QDialog *d = new QDialog(this); 00286 d->setModal(true); 00287 QGridLayout *l = new QGridLayout(d); 00288 QLabel *label = new QLabel(QString(text), this); 00289 l->addWidget(label, 0, 0); 00290 l->addWidget(available, 1, 0); 00291 QPushButton *okay = new QPushButton(tr("Okay"), this); 00292 QPushButton *cancel = new QPushButton(tr("Cancel"), this); 00293 00294 l->addWidget(okay, 2, 0); 00295 l->addWidget(cancel, 2, 1); 00296 00297 d->setLayout(l); 00298 00299 connect(okay, SIGNAL(released()), d, SLOT(accept())); 00300 connect(cancel, SIGNAL(released()), d, SLOT(reject())); 00301 00302 m_selectedCombo = 0; 00303 int res = d->exec(); 00304 00305 if (res == QDialog::Rejected) 00306 return NULL; 00307 00308 int i = 0; 00309 foreach(CanvasContainer *container, m_canvases) { 00310 if (container != NULL) { 00311 if (i++ == m_selectedCombo) { 00312 visible = container->getCanvas(); 00313 break; 00314 } 00315 } 00316 } 00317 00318 return visible; 00319 } 00320 00321 00322 // -------------------------- 00323 // CanvasContainer 00324 // -------------------------- 00325 00326 CanvasContainer::CanvasContainer(Canvas* canvas, const char* title) 00327 : QDockWidget(tr(title)), m_canvas(canvas), 00328 m_title(title ? title : "Canvas") 00329 { 00330 setupContainer(); 00331 } 00332 00333 CanvasContainer::~CanvasContainer() 00334 { } 00335 00336 void CanvasContainer::setupContainer() { 00337 QWidget *widget = m_canvas->getQWidget(); 00338 assert(widget); 00339 00340 setWidget(widget); 00341 00342 if (layout()) 00343 layout()->setSizeConstraint(QLayout::SetFixedSize); 00344 00345 setFixedSize(sizeHint()); 00346 setContentsMargins(0, 0, 0, 0); 00347 } 00348 00349 void CanvasContainer::synchronizeSize(int, int) { 00350 bool floating = isFloating(); 00351 setFloating(!floating); 00352 setFloating(floating); 00353 00354 if (layout()) 00355 layout()->setSizeConstraint(QLayout::SetFixedSize); 00356 00357 setFixedSize(sizeHint()); 00358 setContentsMargins(0, 0, 0, 0); 00359 } 00360 00361 QSize CanvasContainer::sizeHint() const { 00362 return QSize(m_canvas->getWidth(), m_canvas->getHeight()); 00363 } 00364 00365 QSize CanvasContainer::minimumSize() const { 00366 return sizeHint(); 00367 } 00368 00369 QSize CanvasContainer::maximumSize() const { 00370 return sizeHint(); 00371 } 00372 00373 Canvas *CanvasContainer::getCanvas() const { 00374 return m_canvas; 00375 } 00376 00377 char *CanvasContainer::getTitle() const { 00378 return m_title.toAscii().data(); 00379 } 00380
Generated on 28 Feb 2009 for Milton by
1.5.6