diff --git a/include/graphics/map/GeoPoint.h b/include/graphics/map/GeoPoint.h index 0240ef0..9ca6e95 100644 --- a/include/graphics/map/GeoPoint.h +++ b/include/graphics/map/GeoPoint.h @@ -55,7 +55,7 @@ class GeoPoint // ILOG_DEBUG("zoomed GeoPoint(%f, %f) %d/%d/%d (%d/%d)", latitude, longitude, zoom, xTile, yTile, xPos, yPos); } - // move the GeoPoint position by pixels and recalculate the resulting tile and new lat/long + // move the GeoPoint position by pixels and recalculate the resulting tile and new lat/lon void move(int16_t scrollX, int16_t scrollY) { // ILOG_DEBUG("move: tile offset: x: %d->%d, y: %d->%d pixel", xPos, xPos - scrollX, yPos, yPos - scrollY); @@ -99,6 +99,7 @@ class GeoPoint uint32_t yTile; // level 0 (course) .. 18 (detail) uint8_t zoomLevel; + bool isFiltered = false; }; #ifdef UNIT_TEST diff --git a/include/graphics/map/MapPanel.h b/include/graphics/map/MapPanel.h index f7a7239..9dbcbe1 100644 --- a/include/graphics/map/MapPanel.h +++ b/include/graphics/map/MapPanel.h @@ -43,16 +43,17 @@ class MapPanel bool scroll(int16_t deltaX, int16_t deltaY, uint16_t fraction = 3); // -1, 0, +1, 1/3 void moveHome(bool zoomDefault = true); void moveCurrent(void); - // placing objects (uses *user_data as internal reference!) + // placing objects void add(uint32_t id, float lat, float lon, DrawCallback drawCB); void update(uint32_t id, float lat, float lon); + void update(uint32_t id, bool filtered); void remove(uint32_t id); uint32_t getObjectsOnMap(void) { return objectsOnMap; } // images void setHomeLocationImage(lv_obj_t *img); void setGpsPositionImage(lv_obj_t *img); void setNoTileImage(const lv_image_dsc_t *img_src); - void forceRedraw(void) { needsRedraw = true; } + void forceRedraw(bool onlyObjects = false); bool redrawComplete(void) { return redrawCompleted; } // for debugging void printTiles(void); @@ -71,7 +72,7 @@ class MapPanel void redraw(void); void drawLocation(void); void drawObjects(void); - void drawObject(const MapObject &obj); + void drawObject(MapObject &obj); bool needsRedraw = false; bool redrawCompleted = true; diff --git a/source/graphics/TFT/TFTView_320x240.cpp b/source/graphics/TFT/TFTView_320x240.cpp index 6c4d253..4a51d87 100644 --- a/source/graphics/TFT/TFTView_320x240.cpp +++ b/source/graphics/TFT/TFTView_320x240.cpp @@ -929,6 +929,10 @@ void TFTView_320x240::ui_event_NodesButton(lv_event_t *e) if (filterNeedsUpdate) { THIS->updateNodesFiltered(true); THIS->updateNodesStatus(); + lv_obj_scroll_to_view(objects.node_panel, LV_ANIM_ON); + if (THIS->map) { + THIS->map->forceRedraw(true); + } filterNeedsUpdate = false; } } else if (event_code == LV_EVENT_LONG_PRESSED) { @@ -2500,8 +2504,9 @@ void TFTView_320x240::addOrUpdateMap(uint32_t nodeNum, int32_t lat, int32_t lon) updateLocationMap(map->getObjectsOnMap()); } } else { - if (map) + if (map) { map->update(it->first, lat * 1e-7, lon * 1e-7); + } } } @@ -5292,6 +5297,10 @@ bool TFTView_320x240::applyNodesFilter(uint32_t nodeNum, bool reset) lv_obj_clear_flag(panel, LV_OBJ_FLAG_HIDDEN); } + // hide node location if filtered + if (map) + map->update(nodeNum, hide); + bool highlight = false; if (true /*highlight.active*/) { // TODO if (lv_obj_has_state(objects.nodes_hl_active_chat_switch, LV_STATE_CHECKED)) { diff --git a/source/graphics/map/MapPanel.cpp b/source/graphics/map/MapPanel.cpp index 56702a0..58ebf08 100644 --- a/source/graphics/map/MapPanel.cpp +++ b/source/graphics/map/MapPanel.cpp @@ -122,24 +122,30 @@ void MapPanel::drawObjects(void) { objectsOnMap = 0; for (auto &it : mapObjects) { - // check if object's tile is visible - MapObject &obj = *it.second; - obj.point.setZoom(MapTileSettings::getZoomLevel()); - drawObject(obj); + drawObject(*it.second); } } -void MapPanel::drawObject(const MapObject &obj) +void MapPanel::drawObject(MapObject &obj) { if (obj.draw) { - auto tileIt = tiles.find(obj.point.xTile << 16 | obj.point.yTile); - if (tileIt != tiles.end()) { - MapTile &tile = *tileIt->second; - objectsOnMap++; // FIXME: counts also objects that are clipped away - obj.draw(obj.id, tile.getX() + obj.point.xPos, tile.getY() + obj.point.yPos, MapTileSettings::getZoomLevel()); - } else { - obj.draw(obj.id, 0, 0, 0); // hide object + if (!obj.point.isFiltered) { + if (obj.point.zoomLevel != MapTileSettings::getZoomLevel()) { + obj.point.setZoom(MapTileSettings::getZoomLevel()); + } + // check if object is in the visible tile area + auto tileIt = tiles.find(obj.point.xTile << 16 | obj.point.yTile); + if (tileIt != tiles.end()) { + MapTile &tile = *tileIt->second; + if (tile.getX() + obj.point.xPos >= 0 && tile.getX() + obj.point.xPos < widthPixel && + tile.getY() + obj.point.yPos >= 0 && tile.getY() + obj.point.yPos < heightPixel) { + objectsOnMap++; + obj.draw(obj.id, tile.getX() + obj.point.xPos, tile.getY() + obj.point.yPos, MapTileSettings::getZoomLevel()); + return; + } + } } + obj.draw(obj.id, 0, 0, 0); // hide object } } @@ -422,6 +428,16 @@ void MapPanel::update(uint32_t id, float lat, float lon) drawObject(*it->second); } +void MapPanel::update(uint32_t id, bool filtered) +{ + auto it = mapObjects.find(id); + if (it != mapObjects.end() && it->second->point.isFiltered != filtered) { + // only update if filter state changed + it->second->point.isFiltered = filtered; + drawObject(*it->second); + } +} + void MapPanel::remove(uint32_t id) { mapObjects.erase(id); @@ -443,6 +459,16 @@ void MapPanel::setNoTileImage(const lv_image_dsc_t *img_src) noTileImage = img_src; } +void MapPanel::forceRedraw(bool onlyObjects) +{ + if (onlyObjects) { + drawObjects(); + drawLocation(); + } else { + needsRedraw = true; + } +} + void MapPanel::task_handler(void) { redraw();