diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/map.xml b/code/ryzom/client/data/gamedev/interfaces_v3/map.xml index f2e90bbc0..0f1ab111c 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/map.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/map.xml @@ -204,6 +204,31 @@ + + + + + + h="-4" + child_resize_w="true"> + + + + + + + + + + + diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index a05a6f9bb..a841beb44 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -427,7 +427,7 @@ CGroupMap::CGroupMap(const TCtorParam ¶m) _TargetLM = NULL; _HomeLM = NULL; _LandmarkFilter.clear(); - _MatchedLandmarkCount = 0; + _MatchedLandmarks.clear(); // _ScaleMax = 8.f; _ScaleMaxR2 = 8.f; @@ -2249,6 +2249,31 @@ void CGroupMap::centerOnPlayer() computeOffsets(); invalidateCoords(); } +//============================================================================================================ +void CGroupMap::centerOnWorldPos(const CVector2f &worldPos) +{ + CVector2f mapPos; + worldToMap(mapPos, worldPos); + + sint32 sx, sy; + mapToScreen(sx, sy, mapPos); + + sint32 x, y, w, h; + computeMapRectInsideGroup(x, y, w, h); + + sint32 dx, dy; + if (sx < getXReal()) + dx = -(getXReal() - sx + w/2); + else + dx = sx - getXReal() - w/2; + + if (sy < getYReal()) + dy = -(getYReal() - sy + h/2); + else + dy = sy - getYReal() - h/2; + + pan(dx, dy); +} //============================================================================================================ void CGroupMap::setScale(float newUserScale, const NLMISC::CVector2f &/* center */) @@ -2271,7 +2296,6 @@ void CGroupMap::setScale(float newScale) setScale(newScale, mapCoords); } - //============================================================================================================ void CGroupMap::updateLandMarkList(TLandMarkButtonVect &lmVect) { @@ -2303,6 +2327,63 @@ void CGroupMap::updateLandMarkTextList(TLandMarkTextVect &lmVect) } } +//============================================================================================================ +void CGroupMap::updateMatchedLandmarks() +{ + CInterfaceGroup *gc = getParentContainer(); + if (!gc) return; + + // visible landmark count + CViewText *pVT = dynamic_cast(gc->getView("lm_count")); + if (pVT) + { + // show total landmark count if search filter has not been set + uint c = _MatchedLandmarks.size(); + if (c == 0 && _LandmarkFilter.size() == 0) + c = _UserLM.size(); + + pVT->setText(toString(c)); + } + + // list of matched landmarks + CGroupList *pL = dynamic_cast(gc->getGroup("lm_result")); + if (!pL) return; + + pL->clearGroups(); + + if (_LandmarkFilter.size() == 0) return; + + // create result list + for(uint k = 0; k < _MatchedLandmarks.size(); ++k) + { + std::vector > params; + params.clear(); + params.push_back(std::pair("id", toString("lm%d", k))); + params.push_back(std::pair("tooltip", _MatchedLandmarks[k].Title.toUtf8())); + params.push_back(std::pair("index", toString(k))); + + CInterfaceGroup *g = CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL->getId(), params); + if (g) + { + pL->addChild(g); + + CViewText* t = dynamic_cast(g->getView("title")); + if (t) + { + t->setSingleLineTextFormatTaged(_MatchedLandmarks[k].Title); + } + + CViewBitmap* b = dynamic_cast(g->getView("icon")); + if (b) + { + b->setTexture(_MatchedLandmarks[k].Options.LandMarkTexNormal); + b->setColor(_MatchedLandmarks[k].Options.ColorNormal); + } + } + } + pL->invalidateCoords(); +} + //============================================================================================================ void CGroupMap::removeLandMarks(TLandMarkButtonVect &lm) { @@ -2320,6 +2401,9 @@ void CGroupMap::removeLandMarks(TLandMarkButtonVect &lm) //============================================================================================================ void CGroupMap::createLMWidgets(const std::vector &lms) { + // disable any match in "world" mode + bool notWorldMode = _CurMap->Name != "world"; + for (uint32 k = 0; k < lms.size(); ++k) { const CContLandMark &rCLM =lms[k]; @@ -2330,9 +2414,9 @@ void CGroupMap::createLMWidgets(const std::vector &lms) const ucstring ucsTmp(CStringManagerClient::getPlaceLocalizedName(rCLM.TitleTextID)); const ucstring lcTitle = toLower(ucsTmp); - bool searchMatch = _LandmarkFilter.size() > 0 && filterLandmark(lcTitle); + bool searchMatch = notWorldMode && _LandmarkFilter.size() > 0 && filterLandmark(lcTitle); if (searchMatch) - _MatchedLandmarkCount++; + _MatchedLandmarks.push_back(SMatchedLandmark(rCLM.Pos, ucsTmp, _ContinentLMOptions)); // Add button if not a region nor a place if ((rCLM.Type != CContLandMark::Region) && (rCLM.Type != CContLandMark::Place) && @@ -2391,8 +2475,7 @@ void CGroupMap::createLMWidgets(const std::vector &lms) void CGroupMap::createContinentLandMarks() { uint32 k; - - _MatchedLandmarkCount = 0; + _MatchedLandmarks.clear(); if (_MapMode != MapMode_Normal) return; if (_CurMap == NULL) return; @@ -2411,38 +2494,35 @@ void CGroupMap::createContinentLandMarks() if (_CurMap->Name == "world") { createLMWidgets(ContinentMngr.WorldMap); - invalidateCoords(); - return; } - - if (_CurContinent == NULL) return; - - // Continent Landmarks - createLMWidgets(_CurContinent->ContLandMarks); - // User Landmarks - for(k = 0; k < _CurContinent->UserLandMarks.size(); ++k) + else if (_CurContinent) { - NLMISC::CVector2f mapPos; - worldToMap(mapPos, _CurContinent->UserLandMarks[k].Pos); - - if (filterLandmark(_CurContinent->UserLandMarks[k].Title)) + // Continent Landmarks + createLMWidgets(_CurContinent->ContLandMarks); + // User Landmarks + for(k = 0; k < _CurContinent->UserLandMarks.size(); ++k) { - addLandMark(_UserLM, mapPos, _CurContinent->UserLandMarks[k].Title, getUserLandMarkOptions(k)); - _MatchedLandmarkCount++; - } - } - - // update visible landmark count - CInterfaceGroup *gc = getParentContainer(); - if (gc) - { - CViewText *pVT = dynamic_cast(gc->getView("lm_count")); - if (pVT) - { - pVT->setText(toString(_MatchedLandmarkCount)); + NLMISC::CVector2f mapPos; + worldToMap(mapPos, _CurContinent->UserLandMarks[k].Pos); + + CLandMarkOptions options = getUserLandMarkOptions(k); + addLandMark(_UserLM, mapPos, _CurContinent->UserLandMarks[k].Title, options); + + if (_LandmarkFilter.size() > 0) + { + if (filterLandmark(_CurContinent->UserLandMarks[k].Title)) + { + _MatchedLandmarks.push_back(SMatchedLandmark(_CurContinent->UserLandMarks[k].Pos, _CurContinent->UserLandMarks[k].Title, options)); + } + else + { + _UserLM.back()->setActive(false); + } + } } } + updateMatchedLandmarks(); invalidateCoords(); } @@ -3035,6 +3115,30 @@ void CGroupMap::targetLandmark(CCtrlButton *lm) } } +//========================================================================================================= +void CGroupMap::targetLandmarkResult(uint32 index) +{ + if (index > _MatchedLandmarks.size()) return; + + CCompassTarget ct; + ct.Pos = _MatchedLandmarks[index].Pos; + ct.Name = _MatchedLandmarks[index].Title; + // type sets compass arrow color + ct.setType(CCompassTarget::UserLandMark); + + centerOnWorldPos(ct.Pos); + + CInterfaceManager *im = CInterfaceManager::getInstance(); + CGroupCompas *gc = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(_CompassId)); + if (gc) + { + gc->setActive(true); + gc->setTarget(ct); + gc->blink(); + CWidgetManager::getInstance()->setTopWindow(gc); + } +} + //========================================================================================================= void CGroupMap::getLandmarkPosition(const CCtrlButton *lm, NLMISC::CVector2f &worldPos) { @@ -3255,6 +3359,25 @@ class CAHLandMarkFilter : public IActionHandler }; REGISTER_ACTION_HANDLER(CAHLandMarkFilter, "land_mark_filter"); +//========================================================================================================= +// Landmark selected from result list +class CAHLandMarkResultSelected : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const string ¶ms) + { + string id = getParam(params, "map"); + CGroupMap* map = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(id)); + if (!map) return; + + sint index; + string nr = getParam(params, "index"); + if (!fromString(nr, index)) return; + + map->targetLandmarkResult(index); + } +}; +REGISTER_ACTION_HANDLER(CAHLandMarkResultSelected, "land_mark_result_selected"); + //========================================================================================================= // A land mark button has been pushed class CAHLandMarkSelected : public IActionHandler diff --git a/code/ryzom/client/src/interface_v3/group_map.h b/code/ryzom/client/src/interface_v3/group_map.h index bead3d20f..52980c0d8 100644 --- a/code/ryzom/client/src/interface_v3/group_map.h +++ b/code/ryzom/client/src/interface_v3/group_map.h @@ -139,6 +139,9 @@ public: // center the map on the player void centerOnPlayer(); + // center current map on world coords (if not out of map bounds) + void centerOnWorldPos(const NLMISC::CVector2f &worldPos); + void setPlayerPos(const NLMISC::CVector2f &p) { _PlayerPos = p; } NLMISC::CVector2f getPlayerPos() const { return _PlayerPos; } // test if player is currently panning the map @@ -169,6 +172,7 @@ public: CLandMarkOptions getUserLandMarkOptions(uint32 lmindex) const; // target the given landmark void targetLandmark(CCtrlButton *lm); + void targetLandmarkResult(uint32 index); // get the world position of a landmark or return vector Null if not found void getLandmarkPosition(const CCtrlButton *lm, NLMISC::CVector2f &worldPos); @@ -457,7 +461,17 @@ private: // filter keywords std::vector _LandmarkFilter; - uint32 _MatchedLandmarkCount; + struct SMatchedLandmark + { + SMatchedLandmark(const NLMISC::CVector2f pos, const ucstring &title, CLandMarkOptions opts) + : Pos(pos), Title(title), Options(opts) + {} + NLMISC::CVector2f Pos; + ucstring Title; + + CLandMarkOptions Options; + }; + std::vector _MatchedLandmarks; ////////////////////// // Respawn handling // @@ -497,6 +511,7 @@ private: */ void updateLandMarkList(TLandMarkButtonVect &lm); void updateLandMarkTextList(TLandMarkTextVect &lm); + void updateMatchedLandmarks(); // void removeLandMarks(TLandMarkButtonVect &lm); /** create landmarks from the continent (and remove previous ones)