Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improved search results #2116

Merged
merged 7 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions source/MRViewer/MRRibbonMenuSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ void RibbonMenuSearch::drawWindow_( const Parameters& params )
{
if ( ImGui::IsKeyPressed( ImGuiKey_Escape ) )
deactivateSearch_();
#ifndef NDEBUG
if ( ImGui::IsKeyPressed( ImGuiKey_F11 ) )
showResultWeight_ = !showResultWeight_;
#endif

const float minSearchSize = cSearchSize * params.scaling;
if ( isSmallUI() )
Expand Down Expand Up @@ -125,6 +129,15 @@ void RibbonMenuSearch::drawWindow_( const Parameters& params )
params.btnDrawer.drawButtonItem( *foundItem.item, dbParams );
if ( foundItem.item->item->isActive() != pluginActive )
deactivateSearch_();
#ifndef NDEBUG
if ( showResultWeight_ )
{
ImGui::SameLine();
ImGui::Text( "%.3f", foundItem.weight );
if ( ImGui::IsItemHovered() )
ImGui::SetTooltip( "caption = %.3f\ntooltip = %.3f", foundItem.captionWeight, foundItem.tooltipWeight );
}
#endif
}
ImGui::PopStyleVar( 1 );
ImGui::PopStyleColor( 3 );
Expand Down
3 changes: 3 additions & 0 deletions source/MRViewer/MRRibbonMenuSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class MRVIEWER_CLASS RibbonMenuSearch
bool mainInputFocused_ = false;
bool blockSearchBtn_ = false;
bool setMainInputFocus_ = false;
#ifndef NDEBUG
bool showResultWeight_ = false;
#endif
};

}
80 changes: 60 additions & 20 deletions source/MRViewer/MRRibbonSchema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ std::vector<RibbonSchemaHolder::SearchResult> RibbonSchemaHolder::search( const
return res;
auto words = split( searchStr, " " );
std::erase_if( words, [] ( const auto& str ) { return str.empty(); } );
std::vector<std::pair<float, SearchResult>> resultListForSort;
auto enweight = [] ( const std::vector<std::string>& searchWords, const std::string& testLine )->float
{
if ( testLine.empty() )
Expand All @@ -55,28 +54,60 @@ std::vector<RibbonSchemaHolder::SearchResult> RibbonSchemaHolder::search( const
return std::clamp( sumWeight / float( searchWords.size() ), 0.0f, 1.0f );
};

const float maxWeight = 0.25f;
bool exactMatch = false;
auto checkItem = [&] ( const MenuItemInfo& item, int t )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add comment for this function

{
const auto& caption = item.caption.empty() ? item.item->name() : item.caption;
const auto& tooltip = item.tooltip;
auto captionRes = enweight( words, caption );
auto tooltipRes = enweight( words, tooltip );
if ( captionRes > 0.1f && tooltipRes > 0.1f )
SearchResult itemRes;
itemRes.tabIndex = t;
itemRes.item = &item;
const auto posCE = findSubstringCaseInsensitive( caption, searchStr );
if ( posCE != std::string::npos )
{
if ( !exactMatch )
{
res.clear();
exactMatch = true;
}
itemRes.captionWeight = 0.f;
itemRes.weight = float( posCE ) / caption.size();
res.push_back( itemRes );
return;
}
else if ( exactMatch )
{
const auto posTE = findSubstringCaseInsensitive( tooltip, searchStr );
if ( posTE == std::string::npos )
return;
itemRes.tooltipWeight = 0.f;
itemRes.weight = 1.f + float( posTE ) / tooltip.size();
res.push_back( itemRes );
return;
}

itemRes.captionWeight = enweight( words, caption );
itemRes.tooltipWeight = enweight( words, tooltip );
float captionOrderWeight = 0.f;
float tooltipOrderWeight = 0.f;
if ( itemRes.captionWeight > maxWeight && itemRes.tooltipWeight > maxWeight )
return;
for ( const auto& word : words )
{
auto posC = findSubstringCaseInsensitive( caption, word );
auto posT = findSubstringCaseInsensitive( tooltip, word );
if ( posC == std::string::npos )
captionRes += 10.0f;
captionOrderWeight += 10.0f;
else
captionRes += 0.5f * ( float( posC ) / caption.size() );
captionOrderWeight += 0.5f * ( float( posC ) / caption.size() );
if ( posT == std::string::npos )
tooltipRes += 10.0f;
tooltipOrderWeight += 10.0f;
else
tooltipRes += 0.5f * ( float( posT ) / tooltip.size() );
tooltipOrderWeight += 0.5f * ( float( posT ) / tooltip.size() );
}
resultListForSort.push_back( { captionRes + 0.5f * tooltipRes, SearchResult{t,&item} } );
itemRes.weight = itemRes.captionWeight + captionOrderWeight + 0.5f * ( itemRes.tooltipWeight + tooltipOrderWeight );
res.push_back( itemRes );
};
const auto& schema = RibbonSchemaHolder::schema();
auto lookUpMenuItemList = [&] ( const MenuItemsList& list, int t )
Expand Down Expand Up @@ -121,25 +152,34 @@ std::vector<RibbonSchemaHolder::SearchResult> RibbonSchemaHolder::search( const
lookUpMenuItemList( schema.headerQuickAccessList, -1 );
lookUpMenuItemList( schema.sceneButtonsList, -1 );

std::sort( resultListForSort.begin(), resultListForSort.end(), [] ( const auto& a, const auto& b )
std::sort( res.begin(), res.end(), [] ( const auto& a, const auto& b )
{
return intptr_t( a.second.item ) < intptr_t( b.second.item );
return intptr_t( a.item ) < intptr_t( b.item );
} );
resultListForSort.erase(
std::unique( resultListForSort.begin(), resultListForSort.end(),
res.erase(
std::unique( res.begin(), res.end(),
[] ( const auto& a, const auto& b )
{
return a.second.item == b.second.item;
return a.item == b.item;
} ),
resultListForSort.end() );
res.end() );

std::sort( resultListForSort.begin(), resultListForSort.end(), [] ( const auto& a, const auto& b )
std::sort( res.begin(), res.end(), [] ( const auto& a, const auto& b )
{
return a.first < b.first;
return a.weight < b.weight;
} );
res.reserve( resultListForSort.size() );
for ( const auto& sortedRes : resultListForSort )
res.push_back( sortedRes.second );
if ( !res.empty() && res[0].captionWeight > 0.f )
{
const float maxWeightNew = std::min( res[0].captionWeight, res[0].tooltipWeight ) * 3.f;
if ( maxWeightNew < maxWeight && res.back().captionWeight > maxWeightNew && res.back().tooltipWeight > maxWeightNew )
{
auto tailIt = std::find_if( res.begin(), res.end(), [&] ( const auto& a )
{
return a.captionWeight > maxWeightNew && a.tooltipWeight > maxWeightNew;
} );
res.erase( tailIt, res.end() );
}
}

return res;
}
Expand Down
3 changes: 3 additions & 0 deletions source/MRViewer/MRRibbonSchema.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class MRVIEWER_CLASS RibbonSchemaHolder
{
int tabIndex{ -1 }; // -1 is default value if item has no tab
const MenuItemInfo* item{ nullptr }; // item info to show correct caption
float weight{ -1.f };
float captionWeight{ -1.f };
float tooltipWeight{ -1.f };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure we want to store dynamic search information here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better expand SearchResult struct

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also should these new field be under DEBUG def?

};
MRVIEWER_API static std::vector<SearchResult> search( const std::string& searchStr );
private:
Expand Down