/** * @file llgltffolderitem.cpp * @author Andrey Kleshchev * @brief LLGLTFFolderItem class implementation * * $LicenseInfo:firstyear=2024&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2024, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #include "llviewerprecompiledheaders.h" #include "llgltffolderitem.h" #include "llinventoryicon.h" /// LLGLTFItem LLGLTFFolderItem::LLGLTFFolderItem(S32 id, const std::string &display_name, EType type, LLFolderViewModelInterface& root_view_model) : LLFolderViewModelItemCommon(root_view_model) , mName(display_name) , mItemType(type) , mItemId(id) { init(); } LLGLTFFolderItem::LLGLTFFolderItem(LLFolderViewModelInterface& root_view_model) : LLFolderViewModelItemCommon(root_view_model) { init(); } LLGLTFFolderItem::~LLGLTFFolderItem() { } void LLGLTFFolderItem::init() { // using inventory icons as a placeholder. // Todo: GLTF needs to have own icons switch (mItemType) { case TYPE_SCENE: pIcon = LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT_MULTI); break; case TYPE_NODE: pIcon = LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT); break; case TYPE_MESH: pIcon = LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_MESH); break; case TYPE_SKIN: pIcon = LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_BODYPART_SKIN); break; default: pIcon = LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT); break; } } bool LLGLTFFolderItem::filterChildItem(LLFolderViewModelItem* item, LLFolderViewFilter& filter) { S32 filter_generation = filter.getCurrentGeneration(); bool continue_filtering = true; if (item) { if (item->getLastFilterGeneration() < filter_generation) { // Recursive application of the filter for child items (CHUI-849) continue_filtering = item->filter(filter); } // Update latest generation to pass filter in parent and propagate up to root if (item->passedFilter()) { LLGLTFFolderItem* view_model = this; while (view_model && view_model->mMostFilteredDescendantGeneration < filter_generation) { view_model->mMostFilteredDescendantGeneration = filter_generation; view_model = static_cast(view_model->mParent); } } } return continue_filtering; } bool LLGLTFFolderItem::filter(LLFolderViewFilter& filter) { const S32 filter_generation = filter.getCurrentGeneration(); const S32 must_pass_generation = filter.getFirstRequiredGeneration(); if (getLastFilterGeneration() >= must_pass_generation && getLastFolderFilterGeneration() >= must_pass_generation && !passedFilter(must_pass_generation)) { // failed to pass an earlier filter that was a subset of the current one // go ahead and flag this item as not pass setPassedFilter(false, filter_generation); setPassedFolderFilter(false, filter_generation); return true; } bool is_folder = true; const bool passed_filter_folder = is_folder ? filter.checkFolder(this) : true; setPassedFolderFilter(passed_filter_folder, filter_generation); bool continue_filtering = true; if (!mChildren.empty() && (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass || descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement { // now query children for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end(); iter != end_iter; ++iter) { continue_filtering = filterChildItem((*iter), filter); if (!continue_filtering) { break; } } } // If we didn't use all the filter time that means we filtered all of our descendants so we can filter ourselves now if (continue_filtering) { // This is where filter check on the item done (CHUI-849) const bool passed_filter = filter.check(this); if (passed_filter && mChildren.empty() && is_folder) // Update the latest filter generation for empty folders { LLGLTFFolderItem* view_model = this; while (view_model && view_model->mMostFilteredDescendantGeneration < filter_generation) { view_model->mMostFilteredDescendantGeneration = filter_generation; view_model = static_cast(view_model->mParent); } } setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize()); continue_filtering = !filter.isTimedOut(); } return continue_filtering; }