Search: Implemented highlighting of a letters from the search string

This commit is contained in:
YuSanka 2020-03-31 22:46:12 +02:00
parent abad9133eb
commit 042880ba2d
4 changed files with 118 additions and 13 deletions

View file

@ -97,9 +97,14 @@
//#define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
// Special ASCII characters STX and ETX are used here as markup symbols for tokens to be highlighted.
const char ColorMarkerStart = 0x2; // STX
const char ColorMarkerEnd = 0x3; // ETX
// void MyFunction(const char* name, const MyMatrix44& v);
}
*/

View file

@ -33,6 +33,7 @@ Index of this file:
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include "imgui_internal.h"
#include "imconfig.h"
#include <stdio.h> // vsnprintf, sscanf, printf
#if !defined(alloca)
@ -2991,6 +2992,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
ImU32 defaultCol = col;
while (s < text_end)
{
if (word_wrap_enabled)
@ -3019,6 +3022,17 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
}
}
if (*s == ImGui::ColorMarkerStart) {
col = ImGui::GetColorU32(ImGuiCol_ButtonHovered);
s += 1;
}
else if (*s == ImGui::ColorMarkerEnd) {
col = defaultCol;
s += 1;
if (s == text_end)
break;
}
// Decode and advance source
unsigned int c = (unsigned int)*s;
if (c < 0x80)

View file

@ -23,14 +23,15 @@
#define FTS_FUZZY_MATCH_IMPLEMENTATION
#include "fts_fuzzy_match.h"
#include "imgui/imconfig.h"
using boost::optional;
namespace Slic3r {
namespace GUI {
bool SearchOptions::Option::containes(const wxString& search_) const
bool SearchOptions::Option::fuzzy_match_simple(char const * search_pattern) const
{
char const* search_pattern = search_.utf8_str();
char const* opt_key_str = opt_key.c_str();
char const* label_str = label.utf8_str();
@ -38,9 +39,20 @@ bool SearchOptions::Option::containes(const wxString& search_) const
fts::fuzzy_match_simple(search_pattern, opt_key_str ) ;
}
bool SearchOptions::Option::is_matched_option(const wxString& search, int& outScore)
bool SearchOptions::Option::fuzzy_match_simple(const wxString& search) const
{
char const* search_pattern = search.utf8_str();
return fuzzy_match_simple(search_pattern);
}
bool SearchOptions::Option::fuzzy_match_simple(const std::string& search) const
{
char const* search_pattern = search.c_str();
return fuzzy_match_simple(search_pattern);
}
bool SearchOptions::Option::fuzzy_match(char const* search_pattern, int& outScore)
{
char const* opt_key_str = opt_key.c_str();
char const* label_str = label.utf8_str();
@ -48,6 +60,18 @@ bool SearchOptions::Option::is_matched_option(const wxString& search, int& outSc
fts::fuzzy_match(search_pattern, opt_key_str , outScore) );
}
bool SearchOptions::Option::fuzzy_match(const wxString& search, int& outScore)
{
char const* search_pattern = search.utf8_str();
return fuzzy_match(search_pattern, outScore);
}
bool SearchOptions::Option::fuzzy_match(const std::string& search, int& outScore)
{
char const* search_pattern = search.c_str();
return fuzzy_match(search_pattern, outScore);
}
void SearchOptions::Filter::get_label(const char** out_text) const
{
*out_text = label.utf8_str();
@ -91,15 +115,73 @@ void SearchOptions::append_options(DynamicPrintConfig* config, Preset::Type type
}
}
// Wrap a string with ColorMarkerStart and ColorMarkerEnd symbols
static wxString wrap_string(const wxString& str)
{
return wxString::Format("%c%s%c", ImGui::ColorMarkerStart, str, ImGui::ColorMarkerEnd);
}
// Mark a string using ColorMarkerStart and ColorMarkerEnd symbols
static void mark_string(wxString& str, const wxString& search_str)
{
// Try to find whole search string
if (str.Replace(search_str, wrap_string(search_str), false) != 0)
return;
// Try to find whole capitalized search string
wxString search_str_capitalized = search_str.Capitalize();
if (str.Replace(search_str_capitalized, wrap_string(search_str_capitalized), false) != 0)
return;
// if search string is just a one letter now, there is no reason to continue
if (search_str.Len()==1)
return;
// Split a search string for two strings (string without last letter and last letter)
// and repeat a function with new search strings
mark_string(str, search_str.SubString(0, search_str.Len() - 2));
mark_string(str, search_str.Last());
}
// clear marked string from a redundant use of ColorMarkers
static void clear_marked_string(wxString& str)
{
// Check if the string has a several ColorMarkerStart in a row and replace them to only one, if any
wxString delete_string = wxString::Format("%c%c", ImGui::ColorMarkerStart, ImGui::ColorMarkerStart);
if (str.Replace(delete_string, ImGui::ColorMarkerStart, true) != 0) {
// If there were several ColorMarkerStart in a row, it means there should be a several ColorMarkerStop in a row,
// replace them to only one
delete_string = wxString::Format("%c%c", ImGui::ColorMarkerEnd, ImGui::ColorMarkerEnd);
str.Replace(delete_string, ImGui::ColorMarkerEnd, true);
}
// And we should to remove redundant ColorMarkers, if they are in "End, Start" sequence in a row
delete_string = wxString::Format("%c%c", ImGui::ColorMarkerEnd, ImGui::ColorMarkerStart);
str.Replace(delete_string, wxEmptyString, true);
}
void SearchOptions::apply_filters(const std::string& search)
{
clear_filters();
bool full_list = search.empty();
for (size_t i=0; i < options.size(); i++) {
int score=0;
if (full_list || options[i].is_matched_option(search, score))
filters.emplace_back(Filter{ options[i].label, i, score });
for (size_t i=0; i < options.size(); i++)
{
if (full_list) {
filters.emplace_back(Filter{ options[i].label, i, 0 });
continue;
}
int score = 0;
if (options[i].fuzzy_match_simple(search)/*fuzzy_match(search, score)*/)
{
wxString label = options[i].label;
mark_string(label, from_u8(search));
clear_marked_string(label);
filters.emplace_back(Filter{ label, i, score });
}
}
if (!full_list)
@ -243,7 +325,7 @@ void SearchComboBox::append_items(const wxString& search)
*/
for (const SearchOptions::Option& option : search_list.options)
if (option.containes(search))
if (option.fuzzy_match_simple(search))
append(option.label, (void*)&option);
SuppressUpdate su(this);

View file

@ -35,8 +35,12 @@ public:
Preset::Type type {Preset::TYPE_INVALID};
// wxString grope;
bool containes(const wxString& search) const;
bool is_matched_option(const wxString &search, int &outScore);
bool fuzzy_match_simple(char const *search_pattern) const;
bool fuzzy_match_simple(const wxString& search) const;
bool fuzzy_match_simple(const std::string &search) const;
bool fuzzy_match(char const *search_pattern, int &outScore);
bool fuzzy_match(const wxString &search, int &outScore);
bool fuzzy_match(const std::string &search, int &outScore);
};
std::vector<Option> options {};