phoenix-firestorm/indra/newview/llgltffolderitem.cpp

165 lines
5.6 KiB
C++

/**
* @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<LLGLTFFolderItem*>(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<LLGLTFFolderItem*>(view_model->mParent);
}
}
setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
continue_filtering = !filter.isTimedOut();
}
return continue_filtering;
}