From 2c175f57ae45b6eae3fc0eebafa45e5182a05adf Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Tue, 7 Dec 2010 10:33:14 +0000 Subject: [PATCH 1/5] Override puaComboBox recalc_bbox, ignore the popup-menu --- src/GUI/WaypointList.cxx | 1 + src/GUI/dialog.cxx | 32 ++++++++++++++++++++++++++++++++ src/GUI/dialog.hxx | 5 ++++- src/GUI/layout.cxx | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/GUI/WaypointList.cxx b/src/GUI/WaypointList.cxx index 1c1014e03..31c5e480c 100644 --- a/src/GUI/WaypointList.cxx +++ b/src/GUI/WaypointList.cxx @@ -818,6 +818,7 @@ void ScrolledWaypointList::setScrollPercent(float v) void ScrolledWaypointList::setSize(int w, int h) { updateWantsScroll(w, h); + puGroup::setSize(w, h); } void ScrolledWaypointList::updateWantsScroll(int w, int h) diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx index 71852fbc7..8a4160499 100644 --- a/src/GUI/dialog.cxx +++ b/src/GUI/dialog.cxx @@ -1376,4 +1376,36 @@ int fgComboBox::checkHit(int b, int up, int x, int y) return r; } +void fgComboBox::setSize(int w, int h) +{ + puaComboBox::setSize(w, h); + recalc_bbox(); +} + +void fgComboBox::recalc_bbox() +{ +// bug-fix for issue #192 +// http://code.google.com/p/flightgear-bugs/issues/detail?id=192 +// puaComboBox is including the height of its popupMenu in the height +// computation, which breaks layout computations. +// this implementation skips popup-menus + + puBox contents; + contents.empty(); + + for (puObject *bo = dlist; bo != NULL; bo = bo -> getNextObject()) { + if (bo->getType() & PUCLASS_POPUPMENU) { + continue; + } + + contents.extend (bo -> getBBox()) ; + } + + abox.max[0] = abox.min[0] + contents.max[0] ; + abox.max[1] = abox.min[1] + contents.max[1] ; + + puObject::recalc_bbox () ; + +} + // end of dialog.cxx diff --git a/src/GUI/dialog.hxx b/src/GUI/dialog.hxx index 10739280d..497e07104 100644 --- a/src/GUI/dialog.hxx +++ b/src/GUI/dialog.hxx @@ -266,8 +266,11 @@ public: void update(); + virtual void setSize(int w, int h); + virtual int checkHit(int b, int up, int x, int y); - + + virtual void recalc_bbox(); private: bool _inHit; }; diff --git a/src/GUI/layout.cxx b/src/GUI/layout.cxx index f9581b3d5..b6fa5ab8f 100644 --- a/src/GUI/layout.cxx +++ b/src/GUI/layout.cxx @@ -80,7 +80,7 @@ void LayoutWidget::calcPrefSize(int* w, int* h) if(getBool("vertical")) *w = 4*UNIT; else *h = 4*UNIT; } else if (isType("list") || isType("airport-list") - || isType("property-list") || isType("dial")) { + || isType("property-list") || isType("dial") || isType("waypointlist")) { *w = *h = 12*UNIT; } else if (isType("hrule")) { *h = 1; From d2bbaa69e07aafb157d58a84f2eb8d83eea51b73 Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Tue, 7 Dec 2010 17:55:45 +0000 Subject: [PATCH 2/5] Change how ils.xml data is loaded, to reduce impact on startup time. --- src/Navaids/navdb.cxx | 61 +++++++++++++++++++++++++++++++++++++++ src/Navaids/navdb.hxx | 7 +++++ src/Navaids/navrecord.cxx | 37 ++++-------------------- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx index 4f7c10e7f..96d38c153 100644 --- a/src/Navaids/navdb.cxx +++ b/src/Navaids/navdb.cxx @@ -34,6 +34,7 @@ #include <simgear/misc/sg_path.hxx> #include <simgear/structure/exception.hxx> #include <simgear/misc/sgstream.hxx> +#include <simgear/props/props_io.hxx> #include "navrecord.hxx" #include "navlist.hxx" @@ -41,9 +42,16 @@ #include <Main/globals.hxx> #include <Navaids/markerbeacon.hxx> #include <Airports/simple.hxx> +#include <Airports/runways.hxx> +#include <Airports/xmlloader.hxx> +#include <Main/fg_props.hxx> using std::string; +typedef std::map<FGAirport*, SGPropertyNode_ptr> AirportPropertyMap; + +static AirportPropertyMap static_airportIlsData; + static FGPositioned::Type mapRobinTypeToFGPType(int aTy) { @@ -223,9 +231,62 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, // end ReadChanFile + // flush all the parsed ils.xml data, we don't need it anymore, + // since it's been meregd into the FGNavRecords + static_airportIlsData.clear(); + return true; } +SGPropertyNode* ilsDataForRunwayAndNavaid(FGRunway* aRunway, const std::string& aNavIdent) +{ + if (!fgGetBool("/sim/paths/use-custom-scenery-data")) { + return NULL; + } + + if (!aRunway) { + return NULL; + } + + FGAirport* apt = aRunway->airport(); +// find (or load) the airprot ILS data + AirportPropertyMap::iterator it = static_airportIlsData.find(apt); + if (it == static_airportIlsData.end()) { + SGPath path; + if (!XMLLoader::findAirportData(apt->ident(), "ils", path)) { + // no ils.xml file for this airpot, insert a NULL entry so we don't + // check again + static_airportIlsData.insert(it, std::make_pair(apt, SGPropertyNode_ptr())); + return NULL; + } + + SGPropertyNode_ptr rootNode = new SGPropertyNode; + readProperties(path.str(), rootNode); + it = static_airportIlsData.insert(it, std::make_pair(apt, rootNode)); + } // of ils.xml file not loaded + + if (!it->second) { + return NULL; + } + +// find the entry matching the runway + SGPropertyNode* runwayNode, *ilsNode; + for (int i=0; (runwayNode = it->second->getChild("runway", i)) != NULL; ++i) { + for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) { + // must match on both nav-ident and runway ident, to support the following: + // - runways with multiple distinct ILS installations (KEWD, for example) + // - runways where both ends share the same nav ident (LFAT, for example) + if ((ilsNode->getStringValue("nav-id") == aNavIdent) && + (ilsNode->getStringValue("rwy") == aRunway->ident())) + { + return ilsNode; + } + } // of ILS iteration + } // of runway iteration + + return NULL; +} + FGRunway* getRunwayFromName(const std::string& aName) { vector<string> parts = simgear::strutils::split(aName); diff --git a/src/Navaids/navdb.hxx b/src/Navaids/navdb.hxx index 5c2aa117c..a4aa9be1b 100644 --- a/src/Navaids/navdb.hxx +++ b/src/Navaids/navdb.hxx @@ -37,6 +37,13 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist, FGTACANList *channellist ); +/** + * Return the property node corresponding to the runway ILS installation, + * from the Airports/I/C/A/ICAO.ils.xml file (loading it if necessary) + * returns NULL is no ILS data is defined for the runway. + */ +SGPropertyNode* ilsDataForRunwayAndNavaid(FGRunway* aRunway, const std::string& aNavIdent); + /** * Helper to map a nav.data name (eg 'KBWI 33R GS') into a FGRunway reference. * returns NULL, and complains loudly, if the airport/runway is not found. diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx index a22bebb69..03317a57d 100644 --- a/src/Navaids/navrecord.cxx +++ b/src/Navaids/navrecord.cxx @@ -32,7 +32,7 @@ #include <simgear/debug/logstream.hxx> #include <simgear/sg_inlines.h> #include <simgear/props/props.hxx> -#include <simgear/props/props_io.hxx> + #include <Navaids/navrecord.hxx> #include <Navaids/navdb.hxx> @@ -97,7 +97,10 @@ void FGNavRecord::initAirportRelation() } if (type() != GS) { - readAirportSceneryData(); + SGPropertyNode* ilsData = ilsDataForRunwayAndNavaid(mRunway, ident()); + if (ilsData) { + processSceneryILS(ilsData); + } } // fudge elevation to the runway elevation if it's not specified @@ -121,36 +124,6 @@ void FGNavRecord::initAirportRelation() } } -void FGNavRecord::readAirportSceneryData() -{ - // allow users to disable the scenery data in the short-term - // longer term, this option can probably disappear - if (!fgGetBool("/sim/use-scenery-airport-data")) { - return; - } - - SGPath path; - SGPropertyNode_ptr rootNode = new SGPropertyNode; - if (!XMLLoader::findAirportData(mRunway->airport()->ident(), "ils", path)) { - return; - } - - readProperties(path.str(), rootNode); - SGPropertyNode* runwayNode, *ilsNode; - for (int i=0; (runwayNode = rootNode->getChild("runway", i)) != NULL; ++i) { - for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) { - // must match on both nav-ident and runway ident, to support the following: - // - runways with multiple distinct ILS installations (KEWD, for example) - // - runways where both ends share the same nav ident (LFAT, for example) - if ((ilsNode->getStringValue("nav-id") == ident()) && - (ilsNode->getStringValue("rwy") == mRunway->ident())) { - processSceneryILS(ilsNode); - return; - } - } // of ILS iteration - } // of runway iteration -} - void FGNavRecord::processSceneryILS(SGPropertyNode* aILSNode) { double hdgDeg = aILSNode->getDoubleValue("hdg-deg"), From 340bb58579cbc767c2d89b141b0ccdb6cb281311 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Thu, 9 Dec 2010 09:08:49 +0100 Subject: [PATCH 3/5] Export the 2d cloudlayer transparency to the property tree --- src/Environment/environment_mgr.cxx | 17 ++++++++++++++++- src/Environment/environment_mgr.hxx | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx index 7b276eb62..4d05fab29 100644 --- a/src/Environment/environment_mgr.cxx +++ b/src/Environment/environment_mgr.cxx @@ -156,7 +156,9 @@ FGEnvironmentMgr::bind () &FGEnvironmentMgr::get_cloud_layer_visibility_m, &FGEnvironmentMgr::set_cloud_layer_visibility_m); - + _tiedProperties.Tie( layerNode->getNode( "alpha",true), this, i, + &FGEnvironmentMgr::get_cloud_layer_maxalpha, + &FGEnvironmentMgr::set_cloud_layer_maxalpha); } _tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) ); @@ -332,6 +334,19 @@ FGEnvironmentMgr::set_cloud_layer_visibility_m (int index, double visibility_m) thesky->get_cloud_layer(index)->setVisibility_m(visibility_m); } +double +FGEnvironmentMgr::get_cloud_layer_maxalpha (int index ) const +{ + return thesky->get_cloud_layer(index)->getMaxAlpha(); +} + +void +FGEnvironmentMgr::set_cloud_layer_maxalpha (int index, double maxalpha) +{ + thesky->get_cloud_layer(index)->setMaxAlpha(maxalpha); +} + + void diff --git a/src/Environment/environment_mgr.hxx b/src/Environment/environment_mgr.hxx index 7b5ad76cb..d9c770319 100644 --- a/src/Environment/environment_mgr.hxx +++ b/src/Environment/environment_mgr.hxx @@ -89,6 +89,8 @@ private: void set_cloud_layer_coverage_type (int index, int type ); double get_cloud_layer_visibility_m (int index) const; void set_cloud_layer_visibility_m (int index, double visibility_m); + double get_cloud_layer_maxalpha (int index ) const; + void set_cloud_layer_maxalpha (int index, double maxalpha); FGEnvironment * _environment; // always the same, for now FGClouds *fgClouds; From 87daa1290aace4cdadcd775e7700650fb96cde43 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Thu, 9 Dec 2010 11:08:36 +0100 Subject: [PATCH 4/5] Improved fog/mist/haze creation from METAR --- src/Environment/metarproperties.cxx | 52 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx index 23d16b59c..ea605d73a 100644 --- a/src/Environment/metarproperties.cxx +++ b/src/Environment/metarproperties.cxx @@ -239,26 +239,46 @@ void MetarProperties::set_metar( const char * metar ) unsigned layerOffset = 0; // Oh, this is ugly! bool setGroundCloudLayer = _rootNode->getBoolValue("set-ground-cloud-layer", false ); - if( setGroundCloudLayer && isFG ) { - // make sure fog actually starts at ground and set it's bottom at a constant + if( setGroundCloudLayer ) { + // create a cloud layer #0 starting at the ground if its fog, mist or haze + + // make sure layer actually starts at ground and set it's bottom at a constant // value below the station's elevation const double LAYER_BOTTOM_BELOW_STATION_ELEVATION=200; - // fog - create a cloud layer #0 starting at the ground + SGMetarCloud::Coverage coverage = SGMetarCloud::COVERAGE_NIL; + double thickness = 0; + double alpha = 1.0; + + if( isFG ) { // fog + coverage = isBC ? SGMetarCloud::COVERAGE_SCATTERED : SGMetarCloud::COVERAGE_BROKEN; + thickness = isMI ? + 30 + LAYER_BOTTOM_BELOW_STATION_ELEVATION : // shallow fog, 10m/30ft + 500 + LAYER_BOTTOM_BELOW_STATION_ELEVATION; // fog, 150m/500ft + alpha = 1.0; + + } else if( isBR ) { // mist + coverage = SGMetarCloud::COVERAGE_OVERCAST; + thickness = 2000 + LAYER_BOTTOM_BELOW_STATION_ELEVATION; + alpha = 0.8; + } else if( isHZ ) { // hase + coverage = SGMetarCloud::COVERAGE_OVERCAST; + thickness = 2000 + LAYER_BOTTOM_BELOW_STATION_ELEVATION; + alpha = 0.6; + } // fog is "overcast" by default of "broken" for patches of fog - SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, 0, true ); - SGMetarCloud::Coverage coverage = isBC ? SGMetarCloud::COVERAGE_SCATTERED : SGMetarCloud::COVERAGE_BROKEN; - layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) ); - layerNode->setStringValue( "coverage", coverage_string[coverage] ); - layerNode->setDoubleValue( "elevation-ft", _station_elevation - LAYER_BOTTOM_BELOW_STATION_ELEVATION ); - layerNode->setDoubleValue( "thickness-ft", isMI ? - 30 + LAYER_BOTTOM_BELOW_STATION_ELEVATION : // shallow fog, 10m/30ft - 500 + LAYER_BOTTOM_BELOW_STATION_ELEVATION ); // fog, 150m/500ft - layerNode->setDoubleValue( "visibility-m", _min_visibility ); - _min_visibility = _max_visibility = 20000.0; // assume good visibility above the fog - layerOffset = 1; // shudder - } else if( setGroundCloudLayer && isHZ ) { - } + if( coverage != SGMetarCloud::COVERAGE_NIL ) { + SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, 0, true ); + layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) ); + layerNode->setStringValue( "coverage", coverage_string[coverage] ); + layerNode->setDoubleValue( "elevation-ft", _station_elevation - LAYER_BOTTOM_BELOW_STATION_ELEVATION ); + layerNode->setDoubleValue( "thickness-ft", thickness ); + layerNode->setDoubleValue( "visibility-m", _min_visibility ); + layerNode->setDoubleValue( "alpha", alpha ); + _min_visibility = _max_visibility = 20000.0; // assume good visibility above the fog + layerOffset = 1; // shudder + } + } for( unsigned i = 0; i < 5-layerOffset; i++ ) { SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, i+layerOffset, true ); From b4478b56c9fa5b1d6dac32c37a48dc7de59c0de2 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Thu, 9 Dec 2010 16:57:12 +0100 Subject: [PATCH 5/5] Issue #66: Non alphanumeric characters in callsign --- src/Main/options.cxx | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 5604e2f98..8041e67df 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -1256,6 +1256,30 @@ fgOptFgviewer(const char* arg) return FG_OPTIONS_OK; } +static int +fgOptCallSign(const char * arg) +{ + int i; + char callsign[11]; + strncpy(callsign,arg,10); + callsign[10]=0; + for (i=0;callsign[i];i++) + { + switch (callsign[i]) + { + case 'A'...'Z':break; + case 'a'...'z':break; + case '0'...'9':break; + case '_':case '-':break; + default: + // convert any other illegal characters + callsign[i]='-'; + break; + } + } + fgSetString("sim/multiplay/callsign", callsign ); + return FG_OPTIONS_OK; +} static map<string,size_t> fgOptionMap; @@ -1440,7 +1464,7 @@ struct OptionDesc { {"joyclient", true, OPTION_CHANNEL, "", false, "", 0 }, {"jsclient", true, OPTION_CHANNEL, "", false, "", 0 }, {"proxy", true, OPTION_FUNC, "", false, "", fgSetupProxy }, - {"callsign", true, OPTION_STRING, "sim/multiplay/callsign", false, "", 0 }, + {"callsign", true, OPTION_FUNC, "", false, "", fgOptCallSign}, {"multiplay", true, OPTION_CHANNEL, "", false, "", 0 }, {"trace-read", true, OPTION_FUNC, "", false, "", fgOptTraceRead }, {"trace-write", true, OPTION_FUNC, "", false, "", fgOptTraceWrite },