mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-10 12:39:53 +00:00
Add complete search functionality for forward and backward searching
This commit is contained in:
parent
b80556b5af
commit
54f1f380e1
@ -383,26 +383,108 @@ namespace MWGui
|
|||||||
void Console::acceptSearchTerm(MyGUI::EditBox* _sender)
|
void Console::acceptSearchTerm(MyGUI::EditBox* _sender)
|
||||||
{
|
{
|
||||||
const std::string& searchTerm = mSearchTerm->getOnlyText();
|
const std::string& searchTerm = mSearchTerm->getOnlyText();
|
||||||
if (searchTerm.length() <= 3)
|
|
||||||
|
if (searchTerm.length() < minLengthOfSearchTerm)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto result = mHistory->getOnlyText().find(searchTerm);
|
currentSearchTerm = searchTerm;
|
||||||
|
currentOccurrence = std::string::npos;
|
||||||
|
|
||||||
// result ist nur der Index des Chars
|
findNextOccurrence(nullptr);
|
||||||
// gescrollt wird aber mit Pixelwerten
|
|
||||||
// also muss man irgendwie umrechnen, welche Zeile welchem Pixelwert entspricht
|
|
||||||
mHistory->setTextSelection(result, result + searchTerm.length());
|
|
||||||
mHistory->setVScrollPosition(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::findNextOccurrence(MyGUI::Widget* _sender)
|
void Console::findNextOccurrence(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
print("Next");
|
if (currentSearchTerm.length() < minLengthOfSearchTerm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto historyText = mHistory->getOnlyText();
|
||||||
|
|
||||||
|
// If we are doing the first search OR are at the end of the text,
|
||||||
|
// we continue searching from the beginning of the text.
|
||||||
|
if (currentOccurrence == std::string::npos || historyText.length() - currentOccurrence <= minLengthOfSearchTerm)
|
||||||
|
{
|
||||||
|
currentOccurrence = historyText.find(currentSearchTerm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentOccurrence = historyText.find(currentSearchTerm, currentOccurrence + minLengthOfSearchTerm);
|
||||||
|
|
||||||
|
// Check if we already got the last occurrence & restart from the beginning
|
||||||
|
if (currentOccurrence == std::string::npos)
|
||||||
|
{
|
||||||
|
currentOccurrence = historyText.find(currentSearchTerm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only scroll & select if we actually found something
|
||||||
|
if (currentOccurrence != std::string::npos)
|
||||||
|
{
|
||||||
|
markOccurrence(currentOccurrence, currentSearchTerm.length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::findPreviousOccurence(MyGUI::Widget* _sender)
|
void Console::findPreviousOccurence(MyGUI::Widget* _sender)
|
||||||
{
|
{
|
||||||
print("Prev");
|
if (currentSearchTerm.length() < minLengthOfSearchTerm)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto historyText = mHistory->getOnlyText();
|
||||||
|
|
||||||
|
// If we are doing the first search OR are at the beginning of the text,
|
||||||
|
// we continue searching from the end of the text.
|
||||||
|
if (currentOccurrence == std::string::npos || currentOccurrence <= minLengthOfSearchTerm)
|
||||||
|
{
|
||||||
|
currentOccurrence = historyText.rfind(currentSearchTerm, historyText.length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentOccurrence = historyText.rfind(currentSearchTerm, currentOccurrence - minLengthOfSearchTerm);
|
||||||
|
|
||||||
|
// Check if we already got the first occurrence & restart from the end
|
||||||
|
if (currentOccurrence == std::string::npos)
|
||||||
|
{
|
||||||
|
currentOccurrence = historyText.rfind(currentSearchTerm, historyText.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only scroll & select if we actually found something
|
||||||
|
if (currentOccurrence != std::string::npos)
|
||||||
|
{
|
||||||
|
markOccurrence(currentOccurrence, currentSearchTerm.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::markOccurrence(const size_t textPosition, const size_t length)
|
||||||
|
{
|
||||||
|
const auto historyText = mHistory->getOnlyText();
|
||||||
|
const size_t upperLimit = std::min(historyText.length(), textPosition);
|
||||||
|
|
||||||
|
// Since MyGUI::EditBox.setVScrollPosition() works on pixels instead of text positions
|
||||||
|
// we need to calculate the actual pixel position by counting lines.
|
||||||
|
size_t lineNumber = 0;
|
||||||
|
for (size_t i = 0; i < upperLimit; i++)
|
||||||
|
{
|
||||||
|
if (historyText[i] == '\n')
|
||||||
|
{
|
||||||
|
lineNumber++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make some space before the actual result
|
||||||
|
if (lineNumber >= 2)
|
||||||
|
{
|
||||||
|
lineNumber -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHistory->setTextSelection(textPosition, textPosition + length);
|
||||||
|
mHistory->setVScrollPosition(mHistory->getFontHeight() * lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Console::complete(std::string input, std::vector<std::string>& matches)
|
std::string Console::complete(std::string input, std::vector<std::string>& matches)
|
||||||
|
@ -86,6 +86,10 @@ namespace MWGui
|
|||||||
void acceptSearchTerm(MyGUI::EditBox* _sender);
|
void acceptSearchTerm(MyGUI::EditBox* _sender);
|
||||||
void findNextOccurrence(MyGUI::Widget* _sender);
|
void findNextOccurrence(MyGUI::Widget* _sender);
|
||||||
void findPreviousOccurence(MyGUI::Widget* _sender);
|
void findPreviousOccurence(MyGUI::Widget* _sender);
|
||||||
|
void markOccurrence(size_t textPosition, size_t length);
|
||||||
|
size_t currentOccurrence = std::string::npos;
|
||||||
|
std::string currentSearchTerm = "";
|
||||||
|
const size_t minLengthOfSearchTerm = 3;
|
||||||
|
|
||||||
std::string complete(std::string input, std::vector<std::string>& matches);
|
std::string complete(std::string input, std::vector<std::string>& matches);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user