// mainwin4.cpp -- main window // // Written by Frederic Bouvier, started October 2001. // // Copyright (C) 2001 Frederic Bouvier - fredb@users.sourceforge.net // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id: mainwin4.cpp,v 1.2 2005/05/09 07:02:08 fredb Exp $ #ifdef _MSC_VER #pragma warning( disable : 4786 4800 4503 4101 ) #define _USE_MATH_DEFINES #endif #include #include #include #include "mainwin.hpp" #include "fragmentact.hpp" #include "mapfragment.hpp" #include "tile.hpp" #include "sdutil.hpp" #include "messwin.hpp" #include "scenerytools.hpp" void FGSD_MainWindow::toTop_cb( Fl_Widget *w, void *v ) { static_cast( v )->fragmentPopup_cb( w, ToTop ); } void FGSD_MainWindow::toBottom_cb( Fl_Widget *w, void *v ) { static_cast( v )->fragmentPopup_cb( w, ToBottom ); } void FGSD_MainWindow::oneUp_cb( Fl_Widget *w, void *v ) { static_cast( v )->fragmentPopup_cb( w, OneUp ); } void FGSD_MainWindow::oneDown_cb( Fl_Widget *w, void *v ) { static_cast( v )->fragmentPopup_cb( w, OneDown ); } void FGSD_MainWindow::fragmentPopup_cb( Fl_Widget *w, FragmentMvt n ) { FragmentList::iterator fi = _fragmentList.begin(); while ( fi != _fragmentList.end() && *fi != _outlinedFragment ) fi++; if ( fi == _fragmentList.end() ) return; FGSD_MoveFragmentAction *act = 0; size_t i = 0; switch ( n ) { case ToTop: _fragmentList.erase( fi++ ); for ( ; fi != _fragmentList.end(); ++fi ) ++i; _fragmentList.insert( fi, _outlinedFragment ); act = new FGSD_MoveFragmentAction( _outlinedFragment->path(), true, i ); break; case ToBottom: _fragmentList.erase( fi++ ); for ( ; fi != _fragmentList.begin(); --fi ) ++i; _fragmentList.insert( fi, _outlinedFragment ); act = new FGSD_MoveFragmentAction( _outlinedFragment->path(), false, i ); break; case OneUp: if ( fi != _fragmentList.end() ) { _fragmentList.erase( fi++ ); fi++; _fragmentList.insert( fi, _outlinedFragment ); act = new FGSD_MoveFragmentAction( _outlinedFragment->path(), true, 1 ); } break; case OneDown: if ( fi != _fragmentList.begin() ) { _fragmentList.erase( fi-- ); _fragmentList.insert( fi, _outlinedFragment ); act = new FGSD_MoveFragmentAction( _outlinedFragment->path(), false, 1 ); } break; } if ( act ) newAction( act ); _area->redraw(); } void FGSD_MainWindow::remMapFragment_cb(Fl_Widget *o, void *v) { static_cast( v )->remMapFragment_cb( o ); } void FGSD_MainWindow::remMapFragment_cb(Fl_Widget *) { if ( _outlinedFragment ) { std::string name = _outlinedFragment->path(); FragmentList::iterator fi = _fragmentList.begin(); while ( fi != _fragmentList.end() && *fi != _outlinedFragment ) fi++; if ( fi == _fragmentList.end() ) return; size_t i = 0; _fragmentList.erase( fi++ ); for ( ; fi != _fragmentList.end(); ++fi ) ++i; delete _outlinedFragment; _outlinedFragment = 0; newAction( new FGSD_AddRemoveFragmentAction( false, name.c_str(), i ) ); _area->redraw(); } } void FGSD_MainWindow::cleanProject() { _zLevel = 1.0; _zoom->value( 0 ); _minx = 0; _miny = 0; _maxx = 0; _maxy = 0; _visw = 0; _vish = 0; _outlinedFragment = 0; _sceneryTools->drawTiles( false ); for ( FragmentList::iterator i = _fragmentList.begin(); i != _fragmentList.end(); ++i ) { FGSD_MapFragment *f = *i; delete f; } _fragmentList.clear(); for ( TileList::iterator j = _tileList.begin(); j != _tileList.end(); ++j ) { FGSD_Tile *t = j->second; delete t; } _tileList.clear(); for ( CurveList::iterator k = _curveList.begin(); k != _curveList.end(); ++k ) { FGSD_Curve *c = *k; delete c; } _curveList.clear(); _curCurve = 0; _actionMgr.clear(); _fileName = ""; setTitle(); _valid = false; } FGSD_MapFragment *FGSD_MainWindow::createFragment( const char *__fileName, const char *relPath ) { FGSD_MapFragment *fragment = new FGSD_MapFragment; std::string path = FGSD_Util::buildAbsolutePath( __fileName, relPath ); fragment->load( path.c_str() ); newAction( new FGSD_AddRemoveFragmentAction( true, path.c_str() ) ); return fragment; } void FGSD_MainWindow::getFragmentBoundingBox( FGSD_MapFragment *f, double &x1, double &y1, double &x2, double &y2 ) const { f->boundingBox( x1, y1, x2, y2 ); } bool FGSD_MainWindow::mouseIsOverFragment( FGSD_MapFragment *f, double x, double y ) const { return f->isOver( x, y ); } bool FGSD_MainWindow::moveFragment( const char *__name, bool __up, size_t __nb ) { if ( __nb == 0 ) return true; bool ret = false; std::string name = __name; FragmentList::iterator src; for ( src = _fragmentList.begin(); src != _fragmentList.end(); ++src ) { if ( name == (*src)->path() ) break; } if ( src != _fragmentList.end() ) { FragmentList::iterator dst = src; size_t i; if ( __up ) for ( i = 0; i < __nb; i++ ) ++dst; else for ( i = 0; i < __nb; i++ ) --dst; if ( dst != _fragmentList.end() ) { FGSD_MapFragment *fragment = *src; _fragmentList.erase( src ); if ( __up ) ++dst; _fragmentList.insert( dst, fragment ); ret = true; } } return ret; } bool FGSD_MainWindow::loadMapFragment( const char *__name ) { bool ret = false; FGSD_MapFragment *fragment = new FGSD_MapFragment; fragment->load( __name ); if ( fragment->isValid() ) { fragment->refreshTesselation( true ); _fragmentList.push_back( fragment ); overallBoundingBox( _minx, _miny, _maxx, _maxy ); layout_(); ret = true; } else delete fragment; return ret; } bool FGSD_MainWindow::removeMapFragment( const char *__name ) { bool ret = false; std::string name = __name; FragmentList::iterator src; for ( src = _fragmentList.begin(); src != _fragmentList.end(); ++src ) { if ( name == (*src)->path() ) { FGSD_MapFragment *fragment = *src; _fragmentList.erase( src ); delete fragment; overallBoundingBox( _minx, _miny, _maxx, _maxy ); layout_(); ret = true; break; } } return ret; } void FGSD_MainWindow::importAndFetch_cb(Fl_Widget *o, void *v) { static_cast( v )->importAndFetch_cb(); } void FGSD_MainWindow::importAndFetch_cb() { _input->openFetchDialog( _curx, _cury ); import_cb(); } void FGSD_MainWindow::import_cb(Fl_Widget *o, void *v) { static_cast( v )->import_cb(); } void FGSD_MainWindow::import_cb() { _input->show(); while ( _input->visible() ) { Fl::wait(); } FGSD_MapFragment *fragment = _input->fragment(); if ( fragment && fragment->isValid() ) { FGSD_MessageWindow mess( "FlightGear Scenery Designer", "The current fragment is valid.\nDo you want to import it ?", FGSD_MessageWindow::Question, FGSD_MessageWindow::Yes | FGSD_MessageWindow::No ); FGSD_MessageWindow::Button b = mess.exec(); if ( b == FGSD_MessageWindow::Yes ) { fragment->refreshTesselation( true ); _fragmentList.push_back( fragment ); _valid = true; _input->clearFragment(); newAction( new FGSD_AddRemoveFragmentAction( true, fragment->path() ) ); overallBoundingBox( _minx, _miny, _maxx, _maxy ); if ( _fragmentList.size() == 1 ) { _posx = _minx; _posy = _miny; } FGSD_BaseObject::_factor = cos( _miny * M_PI / 180 ); if ( _tileList.empty() ) { _sbutton->value( 0 ); _sbutton->deactivate(); setButtonImage( _sbutton, Scenery_i, true ); _sceneryTools->drawTiles( false ); } else { _sbutton->activate(); setButtonImage( _sbutton, Scenery_i, false ); _sceneryTools->fragmentPresent(); } _vscroll->activate(); _hscroll->activate(); layout_(); _area->valid( 0 ); _area->redraw(); } else { _input->clearFragment( true ); } } else if ( _input->fragment() ) { _input->clearFragment( true ); } } void FGSD_MainWindow::drawTransformedFragment( FGSD_MapFragment *fragment, double xm, double ym, double xM, double yM ) const { fragment->drawTransformed( _posx, _posy, _posx + _visw, _posy + _vish ); } void FGSD_MainWindow::drawFragmentOutline( FGSD_MapFragment *fragment ) const { fragment->drawOutline(); }