editor.cpp

Go to the documentation of this file.
00001 
00002 //            Copyright (C) 2004-2007 by The Allacrost Project
00003 //                         All Rights Reserved
00004 //
00005 // This code is licensed under the GNU GPL version 2. It is free software 
00006 // and you may modify it and/or redistribute it under the terms of this license.
00007 // See http://www.gnu.org/copyleft/gpl.html for details.
00009 
00010 /*!****************************************************************************
00011  * \file    editor.cpp
00012  * \author  Philip Vorsilak, gorzuate@allacrost.org
00013  * \brief   Source file for editor's main window and user interface.
00014  *****************************************************************************/
00015 
00016 #include "editor.h"
00017 
00018 using namespace hoa_script;
00019 using namespace hoa_utils;
00020 using namespace hoa_editor;
00021 using namespace hoa_video;
00022 using namespace std;
00023 
00024 Editor::Editor() : Q3MainWindow(0, 0, Qt::WDestructiveClose)
00025 {
00026   // create the statusbar
00027   _stat_bar = new QStatusBar(this);
00028   
00029   // file menu creation
00030   _file_menu = new Q3PopupMenu(this);
00031   connect(_file_menu, SIGNAL(aboutToShow()), this, SLOT(_FileMenuSetup()));
00032   menuBar()->insertItem("&File", _file_menu);
00033 
00034   // view menu creation
00035   _view_menu = new Q3PopupMenu(this);
00036   menuBar()->insertItem("&View", _view_menu);
00037   _grid_id = _view_menu->insertItem("&Grid", this, SLOT(_ViewToggleGrid()));
00038   _view_menu->insertSeparator();
00039   _ll_id = _view_menu->insertItem("&Lower Tile Layer", this, SLOT(_ViewToggleLL()));
00040   _ml_id = _view_menu->insertItem("&Middle Tile Layer", this, SLOT(_ViewToggleML()));
00041   _ul_id = _view_menu->insertItem("&Upper Tile Layer", this, SLOT(_ViewToggleUL()));
00042   _view_menu->setCheckable(true);
00043 
00044   // tile menu creation
00045   _tiles_menu = new Q3PopupMenu(this);
00046   menuBar()->insertItem("&Tiles", _tiles_menu);
00047   _tiles_menu->insertItem("&Fill current layer", this, SLOT(_TileLayerFill()));
00048   _tiles_menu->insertItem("&Clear current layer", this, SLOT(_TileLayerClear()));
00049   _tiles_menu->insertSeparator();
00050   // store id's for setting and removing checks
00051   int paint_mode_id = _tiles_menu->insertItem("&Paint mode", this, SLOT(_TileModePaint()));
00052   _mode_ids.insert(std::pair<TILE_MODE_TYPE,int>(PAINT_TILE,paint_mode_id));
00053   int move_mode_id = _tiles_menu->insertItem("&Move mode", this, SLOT(_TileModeMove()));
00054   _mode_ids.insert(std::pair<TILE_MODE_TYPE,int>(MOVE_TILE,move_mode_id));
00055   int delete_mode_id = _tiles_menu->insertItem("&Delete mode", this, SLOT(_TileModeDelete()));
00056   _mode_ids.insert(std::pair<TILE_MODE_TYPE,int>(DELETE_TILE,delete_mode_id));
00057   _tiles_menu->insertSeparator();
00058   int edit_ll_id = _tiles_menu->insertItem("Edit &lower layer", this, SLOT(_TileEditLL()));
00059   _layer_ids.insert(std::pair<LAYER_TYPE,int>(LOWER_LAYER,edit_ll_id));
00060   int edit_ml_id = _tiles_menu->insertItem("Edit &middle layer", this, SLOT(_TileEditML()));
00061   _layer_ids.insert(std::pair<LAYER_TYPE,int>(MIDDLE_LAYER,edit_ml_id));
00062   int edit_ul_id = _tiles_menu->insertItem("Edit &upper layer", this, SLOT(_TileEditUL()));
00063   _layer_ids.insert(std::pair<LAYER_TYPE,int>(UPPER_LAYER,edit_ul_id));
00064   
00065   // map menu creation
00066   _map_menu = new Q3PopupMenu(this);
00067   menuBar()->insertItem("&Map",_map_menu);
00068   _map_menu->insertItem("Set background &music...", this, SLOT(_MapSelectMusic()));
00069 
00070   // help menu creation
00071   _help_menu = new Q3PopupMenu(this);
00072   menuBar()->insertSeparator();
00073   menuBar()->insertItem("&Help", _help_menu);
00074   _help_menu->insertItem("&Help", this, SLOT(_HelpHelp()), Qt::Key_F1);
00075   _help_menu->insertItem("&About", this, SLOT(_HelpAbout()));
00076   _help_menu->insertItem("About &Qt", this, SLOT(_HelpAboutQt()));
00077 
00078   // initialize viewing items
00079   _grid_on = true;
00080   _ll_on = true;
00081   _ml_on = false;
00082   _ul_on = false;
00083   _view_menu->setItemChecked(_grid_id, _grid_on);
00084   _view_menu->setItemChecked(_ll_id,   _ll_on);
00085   _view_menu->setItemChecked(_ml_id,   _ml_on);
00086   _view_menu->setItemChecked(_ul_id,   _ul_on);
00087 
00088   // create the main widget and layout
00089   _ed_widget = new QWidget(this);
00090   _ed_layout = new Q3VBoxLayout(_ed_widget);
00091   _ed_scrollview = NULL;
00092   _ed_tabs = NULL;
00093   setCentralWidget(_ed_widget);
00094   resize(600, 400);
00095 
00096   // set the window icon
00097   setWindowIcon(QIcon("img/logos/program_icon.bmp"));
00098 } // Editor constructor
00099 
00100 Editor::~Editor()
00101 {
00102 //  if (_tiles != NULL)
00103 //    delete _tiles;
00104   if (_ed_scrollview != NULL)
00105     delete _ed_scrollview;
00106   if (_ed_tabs != NULL)
00107     delete _ed_tabs;
00108   delete _ed_layout;
00109   delete _ed_widget;
00110 
00111 } // Editor destructor
00112 
00113 
00114 
00115 // ********** Protected function **********
00116 
00117 void Editor::closeEvent(QCloseEvent*)
00118 {
00119     _FileQuit();
00120 } // closeEvent(...)
00121 
00122 
00123 
00124 // ********** Private slots **********
00125 
00126 void Editor::_FileMenuSetup()
00127 {
00128   _file_menu->clear();
00129   _file_menu->insertItem("&New...", this, SLOT(_FileNew()), Qt::CTRL+Qt::Key_N);
00130   _file_menu->insertItem("&Open...", this, SLOT(_FileOpen()), Qt::CTRL+Qt::Key_O);
00131   int save_id = _file_menu->insertItem("&Save", this, SLOT(_FileSave()), Qt::CTRL+Qt::Key_S);
00132   int save_as_id = _file_menu->insertItem("Save &As...", this, SLOT(_FileSaveAs()));
00133   _file_menu->insertSeparator();
00134   int resize_id = _file_menu->insertItem("&Resize Map...", this, SLOT(_FileResize()));
00135   _file_menu->insertSeparator();
00136   _file_menu->insertItem("&Quit", this, SLOT(_FileQuit()), Qt::CTRL+Qt::Key_Q);
00137 
00138   if (_ed_scrollview != NULL && _ed_scrollview->_map != NULL)
00139   {
00140     _file_menu->setItemEnabled(save_id, _ed_scrollview->_map->GetChanged());
00141     _file_menu->setItemEnabled(save_as_id, true);
00142   //  _file_menu->setItemEnabled(resize_id, true);
00143   } // map must exist in order to save or resize it
00144   else
00145   {
00146     _file_menu->setItemEnabled(save_id, false);
00147     _file_menu->setItemEnabled(save_as_id, false);
00148   } // map does not exist, can't save or resize it
00149   _file_menu->setItemEnabled(resize_id, false);
00150 } // _FileMenuSetup()
00151 
00152 void Editor::_FileNew()
00153 {
00154   if (_EraseOK())
00155   {
00156     NewMapDialog* new_map = new NewMapDialog(this, "new_map");
00157 
00158     if (new_map->exec() == QDialog::Accepted)
00159     {
00160       if (_ed_scrollview != NULL)
00161         delete _ed_scrollview;
00162       _ed_scrollview = new EditorScrollView(_ed_widget, "map", new_map->GetWidth(), new_map->GetHeight());
00163 
00164       if (_ed_tabs != NULL)
00165         delete _ed_tabs;
00166       _ed_tabs = new QTabWidget(_ed_widget);
00167       _ed_tabs->setTabPosition(QTabWidget::South);
00168 
00169       _ed_layout->addWidget(_ed_scrollview);
00170       _ed_layout->addWidget(_ed_tabs);
00171       _ed_scrollview->show();
00172 
00173       Q3CheckListItem* tiles = static_cast<Q3CheckListItem*> (new_map->GetTilesetListView()->firstChild());
00174       while (tiles)
00175       {
00176         if (tiles->isOn())
00177         {
00178           Tileset* a_tileset = new Tileset(_ed_widget, tiles->text());
00179           _ed_tabs->addTab(a_tileset->table, tiles->text());
00180           //_ed_scrollview->_map->tileset_names.append(tiles->text());
00181           _ed_scrollview->_map->tilesets.push_back(a_tileset);
00182         } // tileset must be selected
00183         tiles = static_cast<Q3CheckListItem*> (tiles->nextSibling());
00184       } // iterate through all possible tilesets
00185   
00186       _ed_tabs->show();
00187 
00188       _ed_scrollview->resize(new_map->GetWidth() * TILE_WIDTH, new_map->GetHeight() * TILE_HEIGHT);
00189 
00190       _grid_on = false;
00191       _ll_on   = false;
00192       _ml_on   = false;
00193       _ul_on   = false;
00194       _ViewToggleGrid();
00195       _ViewToggleLL();
00196       _ViewToggleML();
00197       _ViewToggleUL();
00198       
00199       // Set default edit mode
00200       _SetEditLayer(LOWER_LAYER);
00201       _SetEditMode(PAINT_TILE);
00202     } // only if the user pressed OK
00203     else
00204       _stat_bar->message("No map created!", 5000);
00205 
00206     delete new_map;
00207   } // make sure an unsaved map is not lost
00208 } // _FileNew()
00209 
00210 void Editor::_FileOpen()
00211 {
00212   if (_EraseOK())
00213   {
00214     // file to open
00215     QString file_name = Q3FileDialog::getOpenFileName(
00216       "dat/maps", "Maps (*.lua)", this, "file open",
00217       "HoA Level Editor -- File Open");
00218 
00219     if (!file_name.isEmpty())
00220     {
00221       if (_ed_scrollview != NULL)
00222         delete _ed_scrollview;
00223       _ed_scrollview = new EditorScrollView(_ed_widget, "map", 0, 0);
00224 
00225       if (_ed_tabs != NULL)
00226         delete _ed_tabs;
00227       _ed_tabs = new QTabWidget(_ed_widget);
00228       _ed_tabs->setTabPosition(QTabWidget::South);
00229 
00230       _ed_layout->addWidget(_ed_scrollview);
00231       _ed_layout->addWidget(_ed_tabs);
00232       _ed_scrollview->show();
00233 
00234       _ed_scrollview->_map->SetFileName(file_name);
00235       _ed_scrollview->_map->LoadMap();
00236 
00237       for (QStringList::ConstIterator it = _ed_scrollview->_map->tileset_names.begin();
00238         it != _ed_scrollview->_map->tileset_names.end(); it++)
00239       {
00240         Tileset* a_tileset = new Tileset(_ed_widget, *it);
00241         _ed_tabs->addTab(a_tileset->table, *it);
00242         _ed_scrollview->_map->tilesets.push_back(a_tileset);
00243       } // iterate through all tilesets in the map
00244 
00245       _ed_tabs->show();
00246 
00247       _ed_scrollview->resize(_ed_scrollview->_map->GetWidth(), _ed_scrollview->_map->GetHeight());
00248 
00249       _grid_on = false;
00250       _ll_on   = false;
00251       _ml_on   = false;
00252       _ul_on   = false;
00253       _ViewToggleGrid();
00254       _ViewToggleLL();
00255       _ViewToggleML();
00256       _ViewToggleUL();
00257 
00258       // Set default edit mode
00259       _SetEditLayer(LOWER_LAYER);
00260       _SetEditMode(PAINT_TILE);
00261 
00262       _stat_bar->message(QString("Opened \'%1\'").arg(_ed_scrollview->_map->GetFileName()), 5000);
00263     } // file must exist in order to open it
00264   } // make sure an unsaved map is not lost
00265 } // _FileOpen()
00266 
00267 void Editor::_FileSaveAs()
00268 {
00269   // get the file name from the user
00270   QString file_name = Q3FileDialog::getSaveFileName(
00271     "dat/maps", "Maps (*.lua)", this, "file save",
00272     "HoA Level Editor -- File Save");
00273     
00274   if (!file_name.isEmpty())
00275   {
00276     int answer = 0;   // button pressed by user
00277     
00278     // ask to overwrite existing file
00279     if (QFile::exists(file_name))
00280       answer = QMessageBox::warning(this, "Overwrite File",
00281         QString("Overwrite\n\'%1\'?" ).arg(file_name),
00282         "&Yes", "&No", QString::null, 1, 1);
00283         
00284     if (answer == 0)
00285     {
00286       _ed_scrollview->_map->SetFileName(file_name);
00287       _FileSave();
00288       return;
00289     } // save the file
00290     } // make sure the file name is not blank
00291   
00292     _stat_bar->message("Save abandoned.", 5000);
00293 } // _FileSaveAs()
00294 
00295 void Editor::_FileSave()
00296 {
00297   if (_ed_scrollview->_map->GetFileName().isEmpty() ||
00298     _ed_scrollview->_map->GetFileName() == "Untitled")
00299   {
00300     _FileSaveAs();
00301     return;
00302   } // gets a file name if it is blank
00303 
00304   _ed_scrollview->_map->SaveMap();      // actually saves the map
00305   setCaption(QString("%1").arg(_ed_scrollview->_map->GetFileName()));
00306   _stat_bar->message(QString("Saved \'%1\' successfully!").
00307     arg(_ed_scrollview->_map->GetFileName()), 5000);
00308 } // _FileSave()
00309 
00310 void Editor::_FileResize()
00311 {
00312   NewMapDialog* resize = new NewMapDialog(this, "map_resize");
00313   
00314   if (resize->exec() == QDialog::Accepted)
00315   {
00316     _ed_scrollview->_map->SetHeight(resize->GetHeight());
00317     _ed_scrollview->_map->SetWidth(resize->GetWidth());
00318     _ed_scrollview->_map->resize(resize->GetWidth() * TILE_WIDTH, resize->GetHeight() * TILE_HEIGHT);
00319     _ed_scrollview->resize(resize->GetWidth() * TILE_WIDTH, resize->GetHeight() * TILE_HEIGHT);
00320 
00321     if (_ed_tabs != NULL)
00322       delete _ed_tabs;
00323     _ed_tabs = new QTabWidget(_ed_widget);
00324     _ed_tabs->setTabPosition(QTabWidget::South);
00325 
00326     Q3CheckListItem* tiles = static_cast<Q3CheckListItem*> (resize->GetTilesetListView()->firstChild());
00327     _ed_scrollview->_map->tileset_names.clear();
00328     while (tiles)
00329     {
00330       if (tiles->isOn())
00331       {
00332         Tileset* a_tileset = new Tileset(_ed_widget, tiles->text());
00333         _ed_tabs->addTab(a_tileset->table, tiles->text());
00334         //_ed_scrollview->_map->tileset_names.append(tiles->text());
00335         _ed_scrollview->_map->tilesets.push_back(a_tileset);
00336       } // tileset must be selected
00337       tiles = static_cast<Q3CheckListItem*> (tiles->nextSibling());
00338     } // iterate through all possible tilesets
00339   
00340     _ed_layout->addWidget(_ed_tabs);
00341     _ed_tabs->show();
00342   } // only if the user pressed OK
00343   else
00344     _stat_bar->message("Map not resized!", 5000);
00345 
00346   delete resize;
00347 } // _FileResize()
00348 
00349 void Editor::_FileQuit()
00350 {
00351   // Checks to see if the map is unsaved.
00352   if (_EraseOK())
00353     qApp->exit(0);
00354 } // _FileQuit()
00355 
00356 void Editor::_ViewToggleGrid()
00357 {
00358   if (_ed_scrollview != NULL && _ed_scrollview->_map != NULL)
00359   {
00360     _grid_on = !_grid_on;
00361     _view_menu->setItemChecked(_grid_id, _grid_on);
00362     _ed_scrollview->_map->SetGridOn(_grid_on);
00363   } // map must exist in order to view things on it
00364 } // _ViewToggleGrid()
00365 
00366 void Editor::_ViewToggleLL()
00367 {
00368   if (_ed_scrollview != NULL && _ed_scrollview->_map != NULL)
00369   {
00370     _ll_on = !_ll_on;
00371     _view_menu->setItemChecked(_ll_id, _ll_on);
00372     _ed_scrollview->_map->SetLLOn(_ll_on);
00373   } // map must exist in order to view things on it
00374 } // _ViewToggleLL()
00375 
00376 void Editor::_ViewToggleML()
00377 {
00378   if (_ed_scrollview != NULL && _ed_scrollview->_map != NULL)
00379   {
00380     _ml_on = !_ml_on;
00381     _view_menu->setItemChecked(_ml_id, _ml_on);
00382     _ed_scrollview->_map->SetMLOn(_ml_on);
00383   } // map must exist in order to view things on it
00384 } // _ViewToggleML()
00385 
00386 void Editor::_ViewToggleUL()
00387 {
00388   if (_ed_scrollview != NULL && _ed_scrollview->_map != NULL)
00389   {
00390     _ul_on = !_ul_on;
00391     _view_menu->setItemChecked(_ul_id, _ul_on);
00392     _ed_scrollview->_map->SetULOn(_ul_on);
00393   } // map must exist in order to view things on it
00394 } // _ViewToggleUL()
00395 
00396 void Editor::_TileLayerFill()
00397 {
00398   // get reference to current tileset
00399   Q3Table* table = static_cast<Q3Table*> (_ed_tabs->currentPage());
00400 
00401   // put selected tile from tileset into tile array at correct position
00402   int tileset_index = table->currentRow() * 16 + table->currentColumn();
00403   int multiplier = _ed_scrollview->_map->tileset_names.findIndex(_ed_tabs->tabText(_ed_tabs->currentIndex()));
00404   if (multiplier == -1)
00405   {
00406     _ed_scrollview->_map->tileset_names.append(_ed_tabs->tabText(_ed_tabs->currentIndex()));
00407     multiplier = _ed_scrollview->_map->tileset_names.findIndex(_ed_tabs->tabText(_ed_tabs->currentIndex()));
00408   } // calculate index of current tileset
00409 
00410   vector<int32>::iterator it;    // used to iterate over an entire layer
00411   vector<int32>& CurrentLayer = _ed_scrollview->GetCurrentLayer();
00412   for (it = CurrentLayer.begin(); it != CurrentLayer.end(); it++)
00413     *it = tileset_index + multiplier * 256;
00414 
00415   // Draw the changes
00416   _ed_scrollview->_map->updateGL();
00417 } // _TileLayerFill()
00418 
00419 void Editor::_TileLayerClear()
00420 {
00421   vector<int32>::iterator it;    // used to iterate over an entire layer
00422   vector<int32>& CurrentLayer = _ed_scrollview->GetCurrentLayer();
00423   for (it = CurrentLayer.begin(); it != CurrentLayer.end(); it++)
00424     *it = -1;
00425 
00426   // Draw the changes
00427   _ed_scrollview->_map->updateGL();
00428 } // _TileLayerClear()
00429 
00430 void Editor::_SetEditMode(TILE_MODE_TYPE new_mode)
00431 {
00432   if(_ed_scrollview == NULL)
00433     return;
00434 
00435   // Unset old check
00436   _tiles_menu->setItemChecked(_mode_ids[_ed_scrollview->_tile_mode], false);
00437 
00438   // Change mode and apply new check
00439   _ed_scrollview->_tile_mode = new_mode;
00440   _tiles_menu->setItemChecked(_mode_ids[_ed_scrollview->_tile_mode], true);
00441 } // _SetEditMode(TILE_MODE_TYPE new_mode)
00442 
00443 void Editor::_TileModePaint()
00444 {
00445   if (_ed_scrollview != NULL)
00446     _SetEditMode(PAINT_TILE);
00447 } // _TileModePaint()
00448 
00449 void Editor::_TileModeMove()
00450 {
00451   if (_ed_scrollview != NULL)
00452     _SetEditMode(MOVE_TILE);
00453 } // _TileModeMove()
00454 
00455 void Editor::_TileModeDelete()
00456 {
00457   if (_ed_scrollview != NULL)
00458     _SetEditMode(DELETE_TILE);
00459 } // _TileModeDelete()
00460 
00461 void Editor::_SetEditLayer(LAYER_TYPE new_layer)
00462 {
00463   if(_ed_scrollview == NULL)
00464     return;
00465 
00466   // Unset old check
00467   _tiles_menu->setItemChecked(_layer_ids[_ed_scrollview->_layer_edit],false);
00468 
00469   // Set new edit layer and set check
00470   _ed_scrollview->_layer_edit=new_layer;
00471   _tiles_menu->setItemChecked(_layer_ids[_ed_scrollview->_layer_edit],true);
00472 }
00473 
00474 void Editor::_TileEditLL()
00475 {
00476   if (_ed_scrollview != NULL)
00477     _SetEditLayer(LOWER_LAYER);
00478 } // _TileEditLL()
00479 
00480 void Editor::_TileEditML()
00481 {
00482   if (_ed_scrollview != NULL)
00483     _SetEditLayer(MIDDLE_LAYER);
00484 } // _TileEditML()
00485 
00486 void Editor::_TileEditUL()
00487 {
00488   if (_ed_scrollview != NULL)
00489     _SetEditLayer(UPPER_LAYER);
00490 } // _TileEditUL()
00491 
00492 void Editor::_MapSelectMusic()
00493 {
00494   if(_ed_scrollview == NULL)
00495     return;
00496 
00497   MusicDialog* music = new MusicDialog(this, "music_dialog", _ed_scrollview->_map->GetMusic());
00498   if(music->exec() == QDialog::Accepted) {
00499     _ed_scrollview->_map->SetMusic(music->GetSelectedFile());
00500     _ed_scrollview->_map->SetChanged(true);
00501   }
00502   delete music;
00503 }
00504 
00505 void Editor::_HelpHelp()
00506 {
00507   _stat_bar->message(QString("See http://allacrost.sourceforge.net/wiki/index.php/Code_Documentation#Map_Editor_Documentation for more details"), 10000);
00508 } // _HelpHelp()
00509 
00510 void Editor::_HelpAbout()
00511 {
00512     QMessageBox::about(this, "HoA Level Editor -- About",
00513     "<center><h1><font color=blue>Hero of Allacrost Level Editor<font>"
00514     "</h1></center>"
00515     "<center><h2><font color=blue>Copyright (c) 2004-2007<font></h2></center>"
00516     "<p>A level editor created for the Hero of Allacrost project."
00517     " See 'http://www.allacrost.org/' for more details</p>");
00518 } // _HelpAbout()
00519 
00520 void Editor::_HelpAboutQt()
00521 {
00522     QMessageBox::aboutQt(this, "HoA Level Editor -- About Qt");
00523 } // _HelpAboutQt()
00524 
00525 
00526 
00527 // ********** Private functions **********
00528 
00529 bool Editor::_EraseOK()
00530 {
00531   if (_ed_scrollview != NULL && _ed_scrollview->_map != NULL)
00532   {
00533       if (_ed_scrollview->_map->GetChanged())
00534     {
00535       switch(QMessageBox::warning(this, "Unsaved File", "The document contains unsaved changes\n"
00536         "Do you want to save the changes before proceeding?", "&Save", "&Discard", "Cancel",
00537         0,    // Enter == button 0
00538             2))   // Escape == button 2
00539       {
00540           case 0: // Save clicked or Alt+S pressed or Enter pressed.
00541               // save and exit
00542           _FileSave();
00543           break;
00544         case 1: // Discard clicked or Alt+D pressed
00545           // don't save but exit
00546           break;
00547         default: // Cancel clicked or Escape pressed
00548               // don't exit
00549           _stat_bar->message("Save abandoned", 5000);
00550               return false;
00551         } // warn the user to save
00552       } // map has been modified
00553   } // map must exist first
00554 
00555     return true;
00556 } // _EraseOK()
00557 
00558 
00559 
00560 /************************
00561   NewMapDialog class functions follow
00562 ************************/
00563 
00564 NewMapDialog::NewMapDialog(QWidget* parent, const QString& name)
00565   : QDialog(parent, (const char*) name)
00566 {
00567   setCaption("Map Properties...");
00568 
00569   _dia_layout    = new Q3GridLayout(this, 7, 2, 5);
00570   
00571   _height_label  = new QLabel("Height (in tiles):", this);
00572   _height_sbox   = new QSpinBox(this);
00573   _height_sbox->setMinimum(24);
00574   _height_sbox->setMaximum(1000);
00575   
00576   _width_label   = new QLabel(" Width (in tiles):", this);
00577   _width_sbox    = new QSpinBox(this);
00578   _width_sbox->setMinimum(32);
00579   _width_sbox->setMaximum(1000);
00580   
00581   _tileset_lview = new Q3ListView(this, "tileset_lview", Qt::WStaticContents|Qt::WNoAutoErase);
00582   
00583   _cancel_pbut   = new QPushButton("Cancel", this);
00584   _ok_pbut       = new QPushButton("OK", this);
00585   
00586   _cancel_pbut->setDefault(true);
00587   connect(_ok_pbut,     SIGNAL(released()), this, SLOT(accept()));
00588   connect(_cancel_pbut, SIGNAL(released()), this, SLOT(reject()));
00589 
00590   QDir tileset_dir("img/tilesets");
00591   _tileset_lview->addColumn("Tilesets");
00592   for (uint32 i = 0; i < tileset_dir.count(); i++)  // looks for tileset files in the tileset directory
00593     (void) new Q3CheckListItem(_tileset_lview, tileset_dir[i].remove(".png"), Q3CheckListItem::CheckBox);
00594   
00595   _dia_layout->addWidget(_height_label, 0, 0);
00596   _dia_layout->addWidget(_height_sbox, 1, 0);
00597   _dia_layout->addWidget(_width_label, 2, 0);
00598   _dia_layout->addWidget(_width_sbox, 3, 0);
00599   _dia_layout->addMultiCellWidget(_tileset_lview, 0, 5, 1, 1);
00600   _dia_layout->addWidget(_cancel_pbut, 6, 1);
00601   _dia_layout->addWidget(_ok_pbut, 6, 0);
00602 } // NewMapDialog constructor
00603 
00604 NewMapDialog::~NewMapDialog()
00605 {
00606   delete _height_label;
00607   delete _height_sbox;
00608   delete _width_label;
00609   delete _width_sbox;
00610   delete _cancel_pbut;
00611   delete _ok_pbut;
00612   delete _dia_layout;
00613 } // NewMapDialog destructor
00614 
00615 
00616 
00617 /************************
00618   MusicDialog class functions follow
00619 ************************/
00620 
00621 MusicDialog::MusicDialog(QWidget* parent, const QString& name, const QString& selected_music)
00622   : QDialog(parent,name)
00623 {
00624   setCaption("Select map music");
00625   _dia_layout    = new Q3GridLayout(this, 7, 2, 5);
00626 
00627   _cancel_pbut   = new QPushButton("Cancel", this);
00628   _ok_pbut       = new QPushButton("OK", this);
00629   _select_label  = new QLabel("Select the music for this map:",this);
00630   _music_list    = new Q3ListView(this, "tileset_lview", Qt::WStaticContents|Qt::WNoAutoErase);
00631 
00632   //Turn off sorting
00633   _music_list->setSorting(-1);
00634 
00635   connect(_ok_pbut,     SIGNAL(released()), this, SLOT(accept()));
00636   connect(_cancel_pbut, SIGNAL(released()), this, SLOT(reject()));
00637 
00638   _dia_layout->addWidget(_select_label, 0, 0);
00639   _dia_layout->addWidget(_music_list, 1, 0);
00640   _dia_layout->addWidget(_ok_pbut, 2, 0);
00641   _dia_layout->addWidget(_cancel_pbut, 2, 1);
00642 
00643   _PopulateMusicList(selected_music);
00644 } // MusicDialog::MusicDialog
00645 
00646 MusicDialog::~MusicDialog()
00647 {
00648   delete _cancel_pbut;
00649   delete _ok_pbut;
00650   delete _select_label;
00651   delete _music_list;
00652   delete _dia_layout;
00653 } // MusicDialog::~MusicDialog
00654 
00655 void MusicDialog::_PopulateMusicList(const QString& selected_str)
00656 {
00657   QDir music_dir("mus");
00658   _music_list->addColumn("Filename");
00659 
00660   // Add music files
00661   for (unsigned int i = 0; i < music_dir.count(); i++) 
00662   {
00663     if (music_dir[i].contains(".ogg"))
00664     {
00665       QString file_name = music_dir[i];
00666       Q3ListViewItem* Item = new Q3ListViewItem(_music_list, file_name);
00667       if (selected_str.endsWith(file_name) && !selected_str.isEmpty())
00668         _music_list->setSelected(Item, true);
00669     } // only look for .ogg files
00670   } // iterate through all files in the music directory
00671 
00672   // Add "None" option
00673   Q3ListViewItem* none_item = new Q3ListViewItem(_music_list, "None");
00674   if (selected_str.isEmpty() || selected_str == "None")
00675     _music_list->setSelected(none_item, true);
00676 } // MusicDialog::_PopulateMusicList
00677 
00678 QString MusicDialog::GetSelectedFile()
00679 {
00680   if (_music_list->currentItem() == 0)
00681     return QString("None");
00682 
00683   return QString("mus/" + _music_list->currentItem()->text(0));
00684 } // MusicDialog::GetSelectedFile
00685 
00686 
00687 
00688 /************************
00689   EditorScrollView class functions follow
00690 ************************/
00691 
00692 EditorScrollView::EditorScrollView(QWidget* parent, const QString& name, int width, int height)
00693   : Q3ScrollView(parent, (const char*) name, Qt::WNoAutoErase|Qt::WStaticContents)
00694 {
00695   // Set default editing modes.
00696   _tile_mode  = PAINT_TILE;
00697   _layer_edit = LOWER_LAYER;
00698   
00699   // Create a new map.
00700   _map = new Grid(viewport(), "Untitled", width, height);
00701   addChild(_map);
00702 
00703   // Context menu creation.
00704   //_context_menu = new Q3PopupMenu(this);
00705 
00706   //connect(_context_menu, SIGNAL(aboutToShow()), this, SLOT(_ContextMenuSetup()));
00707   //connect(_context_menu, SIGNAL(aboutToHide()), this, SLOT(_ContextMenuEvaluate()));
00708   //_context_menu->insertItem("Unwalkability", checkboxes, NULL);
00709 } // EditorScrollView constructor
00710 
00711 EditorScrollView::~EditorScrollView()
00712 {
00713   delete _map;
00714   //delete _context_menu;
00715 } // EditorScrollView destructor
00716 
00717 void EditorScrollView::Resize(int width, int height)
00718 {
00719   _map->resize(width * TILE_WIDTH, height * TILE_HEIGHT);
00720   _map->SetHeight(height);
00721   _map->SetWidth(width);
00722 } // Resize(...)
00723 
00724 std::vector<int32>& EditorScrollView::GetCurrentLayer()
00725 {
00726   return _map->GetLayer(_layer_edit);
00727 }
00728 
00729 // ********** Protected slots **********
00730 
00731 void EditorScrollView::contentsMousePressEvent(QMouseEvent* evt)
00732 {
00733   // don't draw outside the map
00734   if ((evt->y() / TILE_HEIGHT) >= _map->GetHeight() ||
00735     (evt->x() / TILE_WIDTH)  >= _map->GetWidth())
00736     return;
00737 
00738   _tile_index = evt->y() / TILE_HEIGHT * _map->GetWidth() + evt->x() / TILE_WIDTH;
00739   _map->SetChanged(true);
00740 
00741   switch (_tile_mode)
00742   {
00743     case PAINT_TILE: // start painting tiles
00744     {
00745       if (evt->button() == Qt::LeftButton)
00746       {
00747         // get reference to current tileset
00748         Editor* editor = static_cast<Editor*> (topLevelWidget());
00749         Q3Table* table = static_cast<Q3Table*> (editor->_ed_tabs->currentPage());
00750         QString tileset_name = editor->_ed_tabs->tabText(editor->_ed_tabs->currentIndex());
00751 
00752         // put selected tile from tileset into tile array at correct position
00753         int tileset_index = table->currentRow() * 16 + table->currentColumn();
00754         int multiplier = _map->tileset_names.findIndex(tileset_name);
00755         if (multiplier == -1)
00756         {
00757           _map->tileset_names.append(tileset_name);
00758           multiplier = _map->tileset_names.findIndex(tileset_name);
00759         } // calculate index of current tileset
00760         
00761         if (_map->tilesets[multiplier]->walkability[tileset_index][0] != -1)
00762           GetCurrentLayer()[_tile_index] = tileset_index + multiplier * 256;
00763       } // left mouse button was pressed
00764       break;
00765     } // edit mode PAINT_TILE
00766 
00767     case MOVE_TILE: // start moving a tile
00768     {
00769       _move_source_index = _tile_index;
00770       break;
00771     } // edit mode MOVE_TILE
00772 
00773     case DELETE_TILE: // start deleting tiles
00774     {
00775       if (evt->button() == Qt::LeftButton)
00776       {
00777         // NOTE: Is file_index going to be used?? If not, no reason for this call
00778         //int file_index = GetCurrentLayer()[_tile_index];
00779 
00780         // delete the tile
00781         GetCurrentLayer()[_tile_index] = -1;
00782 
00783         // No longer needed
00784         //_RemoveIfUnused(file_index);
00785       } // left mouse button was pressed
00786       break;
00787     } // edit mode DELETE_TILE
00788 
00789     default:
00790       QMessageBox::warning(this, "Tile editing mode",
00791         "ERROR: Invalid tile editing mode!");
00792   } // switch on tile editing mode
00793 
00794   // Draw the changes
00795   _map->updateGL();
00796 } // contentsMousePressEvent(...)
00797 
00798 void EditorScrollView::contentsMouseMoveEvent(QMouseEvent *evt)
00799 {
00800   // don't draw outside the map
00801   if ((evt->y() / TILE_HEIGHT) >= _map->GetHeight() ||
00802     (evt->x() / TILE_WIDTH)  >= _map->GetWidth())
00803     return;
00804 
00805   int index = evt->y() / TILE_HEIGHT * _map->GetWidth() + evt->x() / TILE_WIDTH;
00806   if (index != _tile_index)
00807   {
00808     _tile_index = index;
00809     switch (_tile_mode)
00810     {
00811       case PAINT_TILE: // continue painting tiles
00812       {
00813         if (evt->state() == Qt::LeftButton)
00814         {
00815           // get reference to current tileset
00816           Editor* editor = static_cast<Editor*> (topLevelWidget());
00817           Q3Table* table = static_cast<Q3Table*> (editor->_ed_tabs->currentPage());
00818           QString tileset_name = editor->_ed_tabs->tabText(editor->_ed_tabs->currentIndex());
00819 
00820           // put selected tile from tileset into tile array at correct position
00821           int tileset_index = table->currentRow() * 16 + table->currentColumn();
00822           int multiplier = _map->tileset_names.findIndex(tileset_name);
00823           if (multiplier == -1)
00824           {
00825             _map->tileset_names.append(tileset_name);
00826             multiplier = _map->tileset_names.findIndex(tileset_name);
00827           } // calculate index of current tileset
00828 
00829           if (_map->tilesets[multiplier]->walkability[tileset_index][0] != -1)
00830             GetCurrentLayer()[_tile_index] = tileset_index + multiplier * 256;
00831         } // left mouse button was pressed
00832         break;
00833       } // edit mode PAINT_TILE
00834 
00835       case MOVE_TILE: // continue moving a tile
00836       {
00837         break;
00838       } // edit mode MOVE_TILE
00839 
00840       case DELETE_TILE: // continue deleting tiles
00841       {
00842         if (evt->state() == Qt::LeftButton)
00843         {
00844           // NOTE: file_index is not being used here...
00845           //int file_index = GetCurrentLayer()[_tile_index];
00846 
00847           // delete the tile
00848           GetCurrentLayer()[_tile_index] = -1;
00849 
00850           //_RemoveIfUnused(file_index);
00851         } // left mouse button was pressed
00852         break;
00853       } // edit mode DELETE_TILE
00854 
00855       default:
00856         QMessageBox::warning(this, "Tile editing mode",
00857           "ERROR: Invalid tile editing mode!");
00858     } // switch on tile editing mode
00859   } // mouse has moved to a new tile position
00860 
00861   // Draw the changes
00862   _map->updateGL();
00863 } // contentsMouseMoveEvent(...)
00864 
00865 void EditorScrollView::contentsMouseReleaseEvent(QMouseEvent *evt)
00866 {
00867   // Should already be finished painting or deleting tiles.
00868 
00869   _tile_index = evt->y() / TILE_HEIGHT * _map->GetWidth() + evt->x() / TILE_WIDTH;
00870 
00871   if (_tile_mode == MOVE_TILE)
00872   {
00873     std::vector<int32>& layer = GetCurrentLayer();
00874     layer[_tile_index] = layer[_move_source_index];
00875     layer[_move_source_index] = -1;
00876   } // finish moving a tile
00877   else if (_tile_mode == INVALID_TILE)
00878     QMessageBox::warning(this, "Tile editing mode",
00879       "ERROR: Invalid tile editing mode!");
00880 
00881   // Draw the changes
00882   _map->updateGL();
00883 } // contentsMouseReleaseEvent(...)
00884 
00885 /*
00886 void EditorScrollView::contentsContextMenuEvent(QContextMenuEvent *evt)
00887 {
00888   // Don't popup a menu outside the map.
00889   if ((evt->y() / TILE_HEIGHT) >= _map->GetHeight() ||
00890     (evt->x() / TILE_WIDTH)  >= _map->GetWidth())
00891     return;
00892 
00893   _tile_index = evt->y() / TILE_HEIGHT * _map->GetWidth() + evt->x() / TILE_WIDTH;
00894   _context_menu->exec(QCursor::pos());
00895 } // contentsContextMenuEvent(...)
00896 */
00897 
00898 
00899 // ********** Private slots **********
00900 /*
00901 void EditorScrollView::_ContextMenuSetup()
00902 {
00903 // used for a right-click menu on the tiles
00904 } // _ContextMenuSetup()
00905 
00906 void EditorScrollView::_ContextMenuEvaluate()
00907 {
00908 } // _ContextMenuEvaluate()
00909 */

Generated on Fri Jul 6 23:11:13 2007 for Hero of Allacrost by  doxygen 1.5.1