增加查询结果列表、内容点击显示

This commit is contained in:
pointer-to-bios 2024-07-23 23:54:24 +08:00
parent 1251d2f72b
commit de9b082004
2 changed files with 266 additions and 34 deletions

View File

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.16)
project(CMakeSFMLProject LANGUAGES CXX) project(CMakeSFMLProject LANGUAGES CXX)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_CXX_STANDARD 20)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF) option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
include(FetchContent) include(FetchContent)
@ -19,7 +20,6 @@ FetchContent_MakeAvailable(xlnt)
add_executable(main src/main.cpp) add_executable(main src/main.cpp)
target_link_libraries(main PRIVATE sfml-graphics xlnt) target_link_libraries(main PRIVATE sfml-graphics xlnt)
target_compile_features(main PRIVATE cxx_std_17)
target_include_directories(main PRIVATE include) target_include_directories(main PRIVATE include)
if(WIN32) if(WIN32)

View File

@ -5,6 +5,9 @@
#include <vector> #include <vector>
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
#include <chrono>
#include <thread>
#include <map>
int font_size = 15; int font_size = 15;
float width = 800.f; float width = 800.f;
@ -59,17 +62,29 @@ std::vector<QueryResult> queryData(const std::wstring &keyword, const std::vecto
return results; return results;
} }
static int line_counter = 1; sf::Text textWithWrap(
// static int extra_line_counter = 0; const std::wstring &content,
void setTextWithWrap(sf::Text &text, const std::wstring &content, const sf::Font &font, unsigned int characterSize, float maxWidth) const sf::Font &font,
unsigned int characterSize,
float maxWidth,
bool firstLineCut = false)
{ {
line_counter = 1; sf::Text text;
int line_counter = 1;
text.setString(L""); text.setString(L"");
std::wstring line; std::wstring line;
float lineWidth = 0.f; float lineWidth = 0.f;
float lineHeight = static_cast<float>(font.getLineSpacing(characterSize)); float lineHeight = static_cast<float>(font.getLineSpacing(characterSize));
bool skippingFirstLine = false;
for (auto &ch : content) for (auto &ch : content)
{ {
if (skippingFirstLine)
{
if (ch == L'\n')
skippingFirstLine = false;
else
continue;
}
sf::Glyph glyph = font.getGlyph(ch, characterSize, false); sf::Glyph glyph = font.getGlyph(ch, characterSize, false);
if (ch == L'\n') if (ch == L'\n')
{ {
@ -82,8 +97,13 @@ void setTextWithWrap(sf::Text &text, const std::wstring &content, const sf::Font
else else
{ {
lineWidth += glyph.advance; lineWidth += glyph.advance;
if (lineWidth > maxWidth) if (lineWidth + characterSize > maxWidth)
{ {
if (firstLineCut && line_counter == 1)
{
skippingFirstLine = true;
continue;
}
line_counter++; line_counter++;
text.setString(text.getString() + line + L"\n"); text.setString(text.getString() + line + L"\n");
// text.setString(text.getString() + line + L"\n" + intToWString(line_counter) + L">>"); // text.setString(text.getString() + line + L"\n" + intToWString(line_counter) + L">>");
@ -95,12 +115,55 @@ void setTextWithWrap(sf::Text &text, const std::wstring &content, const sf::Font
} }
} }
text.setString(text.getString() + line); text.setString(text.getString() + line);
return text;
}
std::vector<sf::VertexArray> genX(double x, double y)
{
std::vector<sf::VertexArray> res;
sf::VertexArray line(sf::Lines, 2);
line[0].position.x = x - 6;
line[0].position.y = y - 6;
line[1].position.x = x + 6;
line[1].position.y = y + 6;
line[0].color = sf::Color::White;
line[1].color = sf::Color::White;
res.push_back(line);
auto line_ = line;
line_[0].position.x = x + 6;
line_[1].position.x = x - 6;
res.push_back(line_);
return res;
}
sf::VertexArray genCursor(double x, double y, double h)
{
sf::VertexArray line(sf::Lines, 2);
line[0].position.x = x;
line[0].position.y = y + 2;
line[1].position.x = x;
line[1].position.y = y + h - 2;
line[0].color = sf::Color::Black;
line[1].color = sf::Color::Black;
return line;
} }
int main() int main()
{ {
std::wstring resultStr; std::map<std::wstring, std::wstring> results;
float offset = 0.f; std::wstring content;
float scroll = 0.f;
int offset = 0;
int shadowIndex = -1;
std::shared_ptr<bool> running(new bool(true));
std::shared_ptr<bool> cursor_on(new bool(false));
std::jthread worker([running, cursor_on]()
{
while(*running){
std::this_thread::sleep_for(std::chrono::milliseconds(500));
*cursor_on = !*cursor_on;
} });
// ¶ÁÈ¡ExcelÎļþ // ¶ÁÈ¡ExcelÎļþ
xlnt::workbook wb; xlnt::workbook wb;
@ -146,12 +209,12 @@ int main()
inputTextBox.setFont(font); inputTextBox.setFont(font);
inputTextBox.setCharacterSize(20); inputTextBox.setCharacterSize(20);
inputTextBox.setFillColor(sf::Color::Black); inputTextBox.setFillColor(sf::Color::Black);
inputTextBox.setPosition(55, 55); inputTextBox.setPosition(border_size + 5, border_size + 5);
// Button // query Button
sf::RectangleShape button(sf::Vector2f(100, 30)); sf::RectangleShape button(sf::Vector2f(100, 30));
button.setPosition(width - border_size - button.getSize().x, 50); button.setPosition(width - border_size - button.getSize().x, 50);
button.setFillColor(sf::Color::Green); button.setFillColor(sf::Color(0x33, 0xff, 0x33));
button.setOutlineColor(sf::Color::Black); button.setOutlineColor(sf::Color::Black);
button.setOutlineThickness(2); button.setOutlineThickness(2);
@ -165,21 +228,53 @@ int main()
buttonText.getCharacterSize() * buttonText.getString().getSize() / 2, buttonText.getCharacterSize() * buttonText.getString().getSize() / 2,
52); 52);
// delete Button
sf::CircleShape deleteButton(12, 32);
deleteButton.setPosition(
sf::Vector2f(
border_size + inputBox.getSize().x - 27,
border_size + inputBox.getSize().y / 2 - deleteButton.getRadius()));
deleteButton.setFillColor(sf::Color(0x80, 0x80, 0x80));
// Query result area // Query result area
sf::RectangleShape resultBox(sf::Vector2f(width * 7.f / 8 - 4, height * 5.f / 6)); sf::RectangleShape resultBox(sf::Vector2f(width - border_size * 2 - 4 - 260, height - 100.f - border_size - 4));
resultBox.setPosition(2, 2); resultBox.setPosition(262, 2);
resultBox.setFillColor(sf::Color::White); resultBox.setFillColor(sf::Color::White);
resultBox.setOutlineColor(sf::Color::Black); resultBox.setOutlineColor(sf::Color::Black);
resultBox.setOutlineThickness(2); resultBox.setOutlineThickness(2);
sf::Text resultText; sf::RectangleShape resultList(sf::Vector2f(258, height - 100.f - border_size - 4));
resultText.setFont(font); resultList.setPosition(2, 2);
resultText.setCharacterSize(font_size); resultList.setFillColor(sf::Color::White);
resultText.setFillColor(sf::Color::Black); resultList.setOutlineColor(sf::Color::Black);
resultText.setPosition(7, 0); resultList.setOutlineThickness(2);
sf::View resultView(sf::FloatRect(0.f, 0.f, width * 7.f / 8 - 2, height * 5.f / 6 - 100)); sf::RectangleShape resultTitle(sf::Vector2f(width - border_size * 2 - 4 - 260, 20));
resultView.setViewport(sf::FloatRect(1.f / 16, 100.f / height, 7.f / 8, 1.f)); resultTitle.setPosition(262, 2);
resultTitle.setFillColor(sf::Color::Yellow);
sf::RectangleShape shadow(sf::Vector2f(258, 20));
shadow.setFillColor(sf::Color(0xbb, 0xbb, 0xbb));
sf::View resultView(sf::FloatRect(0.f, 0.f, width - border_size * 2, height - 100.f - border_size));
resultView.setViewport(
sf::FloatRect(
border_size / width, 100.f / height,
(width - border_size * 2) / width,
(height - 100.f - border_size) / height));
sf::View reslistView(sf::FloatRect(0.f, 0.f, 260, height - 100.f - border_size));
reslistView.setViewport(
sf::FloatRect(
border_size / width, 100.f / height,
260 / width, (height - 100.f - border_size) / height));
sf::View showView(sf::FloatRect(0.f, 0.f, width - border_size * 2 - 262, height - 100.f - border_size));
showView.setViewport(
sf::FloatRect(
(border_size + 262) / width, 100.f / height,
(width - border_size * 2 - 262) / width,
(height - 100.f - border_size) / height));
while (window.isOpen()) while (window.isOpen())
{ {
@ -187,7 +282,10 @@ int main()
while (window.pollEvent(event)) while (window.pollEvent(event))
{ {
if (event.type == sf::Event::Closed) if (event.type == sf::Event::Closed)
{
*running = false;
window.close(); window.close();
}
if (event.type == sf::Event::TextEntered) if (event.type == sf::Event::TextEntered)
{ {
if (event.text.unicode == 8) if (event.text.unicode == 8)
@ -212,20 +310,94 @@ int main()
if (button.getGlobalBounds().contains(mousePos.x, mousePos.y)) if (button.getGlobalBounds().contains(mousePos.x, mousePos.y))
{ {
// Perform query // Perform query
std::vector<QueryResult> results = queryData(inputText, data); std::vector<QueryResult> qresults = queryData(inputText, data);
resultStr.clear(); results.clear();
for (const auto &result : results) for (const auto &result : qresults)
{ {
resultStr += result.keyword + L"\n" + result.content + L"\n\n"; if (result.keyword.empty())
continue;
results.insert(std::pair(result.keyword, result.content));
}
button.setFillColor(sf::Color(0xaa, 0xff, 0xaa));
reslistView.reset(sf::FloatRect(0.f, 0.f, 260, height - 100.f - border_size));
offset = 0;
}
else if (deleteButton.getGlobalBounds().contains(mousePos.x, mousePos.y))
{
deleteButton.setFillColor(sf::Color::Red);
content.clear();
shadowIndex = -1;
results.clear();
inputText.clear();
inputTextBox.setString(inputText);
}
else if (inputBox.getGlobalBounds().contains(mousePos.x, mousePos.y))
{
inputBox.setOutlineColor(sf::Color(0xaa, 0xaa, 0xaa));
}
sf::Vector2f vp(
mousePos.x - reslistView.getViewport().left * width,
mousePos.y - reslistView.getViewport().top * height);
if (resultList.getGlobalBounds().contains(vp.x, vp.y) && shadowIndex != -1)
{
auto i = shadowIndex + offset;
auto it = results.begin();
for (; i && it != results.end(); i--, it++)
;
if (it != results.end())
{
content = it->first + L"\n" + it->second;
std::wcout << content << std::endl;
} }
} }
} }
} }
if (event.type == sf::Event::MouseButtonReleased)
{
if (event.mouseButton.button == sf::Mouse::Left)
{
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
if (button.getGlobalBounds().contains(mousePos.x, mousePos.y))
{
button.setFillColor(sf::Color(0x33, 0xff, 0x33));
}
else if (deleteButton.getGlobalBounds().contains(mousePos.x, mousePos.y))
{
deleteButton.setFillColor(sf::Color(0x80, 0x80, 0x80));
}
else if (inputBox.getGlobalBounds().contains(mousePos.x, mousePos.y))
{
inputBox.setOutlineColor(sf::Color::Black);
}
}
}
if (event.type == sf::Event::MouseMoved)
{
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
sf::Vector2f vp(
mousePos.x - reslistView.getViewport().left * width,
mousePos.y - reslistView.getViewport().top * height);
if (resultList.getGlobalBounds().contains(vp.x, vp.y))
{
shadowIndex = (int)vp.y / 20;
}
}
if (event.type == sf::Event::MouseWheelScrolled) if (event.type == sf::Event::MouseWheelScrolled)
{ {
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
{ {
offset -= event.mouseWheelScroll.delta * 20.f; sf::Vector2i mousePos = sf::Mouse::getPosition(window);
sf::Vector2f vp(reslistView.getViewport().left * width, reslistView.getViewport().top * height);
if (resultList.getGlobalBounds().contains(mousePos.x - vp.x, mousePos.y - vp.y))
{
offset -= event.mouseWheelScroll.delta;
if (offset < 0)
offset = 0;
else if (offset > results.size())
offset = results.size();
else
scroll -= event.mouseWheelScroll.delta * 20.f;
}
} }
} }
// catch the resize events // catch the resize events
@ -234,31 +406,91 @@ int main()
width = event.size.width; width = event.size.width;
height = event.size.height; height = event.size.height;
inputBox.setSize(sf::Vector2f(width - border_size * 2 - 120, 30)); inputBox.setSize(sf::Vector2f(width - border_size * 2 - 120, 30));
deleteButton.setPosition(
sf::Vector2f(
border_size + inputBox.getSize().x - 27,
border_size + inputBox.getSize().y / 2 - deleteButton.getRadius()));
button.setPosition(width - border_size - button.getSize().x, 50); button.setPosition(width - border_size - button.getSize().x, 50);
buttonText.setPosition( buttonText.setPosition(
button.getPosition().x + button.getSize().x / 2 - // button.getPosition().x + button.getSize().x / 2 -
buttonText.getCharacterSize() * buttonText.getString().getSize() / 2, buttonText.getCharacterSize() * buttonText.getString().getSize() / 2,
52); 52);
resultBox.setSize(sf::Vector2f(width - border_size * 2 - 4, height - 100.f - border_size - 4));
resultView.setViewport(sf::FloatRect(border_size / width, 100.f / height, (width - border_size * 2) / width, (height - 100.f - border_size) / height)); resultList.setSize(sf::Vector2f(258, height - 100.f - border_size - 4));
resultBox.setSize(sf::Vector2f(width - border_size * 2 - 4 - 260, height - 100.f - border_size - 4));
resultTitle.setSize(sf::Vector2f(width - border_size * 2 - 4 - 260, 20));
resultView.reset(sf::FloatRect(0.f, 0.f, width - border_size * 2, height - 100.f - border_size));
resultView.setViewport(
sf::FloatRect(
border_size / width, 100.f / height,
(width - border_size * 2) / width,
(height - 100.f - border_size) / height));
reslistView.reset(sf::FloatRect(0.f, 0.f, 260, height - 100.f - border_size));
reslistView.setViewport(
sf::FloatRect(
border_size / width, 100.f / height,
260 / width, (height - 100.f - border_size - 2) / height));
reslistView.move(sf::Vector2f(0, offset * 20));
showView.reset(sf::FloatRect(0.f, 0.f, width - border_size * 2 - 260, height - 100.f - border_size));
showView.setViewport(sf::FloatRect(
(border_size + 262) / width, 100.f / height,
(width - border_size * 2 - 260) / width,
(height - 100.f - border_size) / height));
} }
} }
setTextWithWrap(resultText, resultStr, font, font_size, width * 7.f / 8 - 14);
window.setView(sf::View(sf::FloatRect(0.f, 0.f, width, height))); window.setView(sf::View(sf::FloatRect(0.f, 0.f, width, height)));
window.clear(sf::Color(0x40, 0x80, 0x40)); window.clear(sf::Color(0x40, 0x80, 0x40));
window.draw(inputBox); window.draw(inputBox);
window.draw(inputTextBox); window.draw(inputTextBox);
if (*cursor_on)
{
auto b = inputTextBox.getGlobalBounds();
auto c = genCursor(b.getSize().x + b.getPosition().x, inputBox.getPosition().y, inputBox.getSize().y);
window.draw(c);
}
window.draw(deleteButton);
auto x = genX(deleteButton.getPosition().x + 12, deleteButton.getPosition().y + 12);
window.draw(x[0]);
window.draw(x[1]);
window.draw(button); window.draw(button);
window.draw(buttonText); window.draw(buttonText);
resultView.reset(sf::FloatRect(0.f, 0.f, width - border_size * 2, height - 100.f - border_size));
window.setView(resultView); window.setView(resultView);
window.draw(resultList);
window.draw(resultBox); window.draw(resultBox);
resultView.move(sf::Vector2f(0, offset)); window.draw(resultTitle);
window.setView(resultView);
window.draw(resultText); window.setView(reslistView);
reslistView.move(sf::Vector2f(0, scroll));
scroll = 0;
auto i = 0;
for (auto it = results.begin(); it != results.end(); it++)
{
if (i == shadowIndex)
{
shadow.setPosition(2, 2 + offset * 20 + i * 20);
window.draw(shadow);
}
auto text = textWithWrap(it->first, font, font_size, reslistView.getSize().x);
text.setFont(font);
text.setCharacterSize(font_size);
text.setFillColor(sf::Color::Black);
text.setPosition(7, 2 + i * 20);
window.draw(text);
i++;
}
window.setView(showView);
auto contentText = textWithWrap(content, font, font_size, showView.getSize().x, true);
contentText.setFont(font);
contentText.setCharacterSize(font_size);
contentText.setFillColor(sf::Color::Black);
contentText.setPosition(7, 4);
window.draw(contentText);
window.display(); window.display();
} }