From de9b082004da011d1fbe262660d3092dbcda8ef9 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 23 Jul 2024 23:54:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E5=88=97=E8=A1=A8=E3=80=81=E5=86=85=E5=AE=B9=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- src/main.cpp | 298 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 266 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4d2a81..e175495 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.16) project(CMakeSFMLProject LANGUAGES CXX) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_CXX_STANDARD 20) option(BUILD_SHARED_LIBS "Build shared libraries" OFF) include(FetchContent) @@ -19,7 +20,6 @@ FetchContent_MakeAvailable(xlnt) add_executable(main src/main.cpp) target_link_libraries(main PRIVATE sfml-graphics xlnt) -target_compile_features(main PRIVATE cxx_std_17) target_include_directories(main PRIVATE include) if(WIN32) diff --git a/src/main.cpp b/src/main.cpp index f2e0872..c9d5ac7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include int font_size = 15; float width = 800.f; @@ -59,17 +62,29 @@ std::vector queryData(const std::wstring &keyword, const std::vecto return results; } -static int line_counter = 1; -// static int extra_line_counter = 0; -void setTextWithWrap(sf::Text &text, const std::wstring &content, const sf::Font &font, unsigned int characterSize, float maxWidth) +sf::Text textWithWrap( + const std::wstring &content, + 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""); std::wstring line; float lineWidth = 0.f; float lineHeight = static_cast(font.getLineSpacing(characterSize)); + bool skippingFirstLine = false; for (auto &ch : content) { + if (skippingFirstLine) + { + if (ch == L'\n') + skippingFirstLine = false; + else + continue; + } sf::Glyph glyph = font.getGlyph(ch, characterSize, false); if (ch == L'\n') { @@ -82,8 +97,13 @@ void setTextWithWrap(sf::Text &text, const std::wstring &content, const sf::Font else { lineWidth += glyph.advance; - if (lineWidth > maxWidth) + if (lineWidth + characterSize > maxWidth) { + if (firstLineCut && line_counter == 1) + { + skippingFirstLine = true; + continue; + } line_counter++; text.setString(text.getString() + line + L"\n"); // 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); + return text; +} + +std::vector genX(double x, double y) +{ + std::vector 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() { - std::wstring resultStr; - float offset = 0.f; + std::map results; + std::wstring content; + float scroll = 0.f; + int offset = 0; + int shadowIndex = -1; + std::shared_ptr running(new bool(true)); + std::shared_ptr 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Îļþ xlnt::workbook wb; @@ -146,12 +209,12 @@ int main() inputTextBox.setFont(font); inputTextBox.setCharacterSize(20); 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)); 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.setOutlineThickness(2); @@ -165,21 +228,53 @@ int main() buttonText.getCharacterSize() * buttonText.getString().getSize() / 2, 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 - sf::RectangleShape resultBox(sf::Vector2f(width * 7.f / 8 - 4, height * 5.f / 6)); - resultBox.setPosition(2, 2); + sf::RectangleShape resultBox(sf::Vector2f(width - border_size * 2 - 4 - 260, height - 100.f - border_size - 4)); + resultBox.setPosition(262, 2); resultBox.setFillColor(sf::Color::White); resultBox.setOutlineColor(sf::Color::Black); resultBox.setOutlineThickness(2); - sf::Text resultText; - resultText.setFont(font); - resultText.setCharacterSize(font_size); - resultText.setFillColor(sf::Color::Black); - resultText.setPosition(7, 0); + sf::RectangleShape resultList(sf::Vector2f(258, height - 100.f - border_size - 4)); + resultList.setPosition(2, 2); + resultList.setFillColor(sf::Color::White); + resultList.setOutlineColor(sf::Color::Black); + resultList.setOutlineThickness(2); - sf::View resultView(sf::FloatRect(0.f, 0.f, width * 7.f / 8 - 2, height * 5.f / 6 - 100)); - resultView.setViewport(sf::FloatRect(1.f / 16, 100.f / height, 7.f / 8, 1.f)); + sf::RectangleShape resultTitle(sf::Vector2f(width - border_size * 2 - 4 - 260, 20)); + 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()) { @@ -187,7 +282,10 @@ int main() while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) + { + *running = false; window.close(); + } if (event.type == sf::Event::TextEntered) { if (event.text.unicode == 8) @@ -212,20 +310,94 @@ int main() if (button.getGlobalBounds().contains(mousePos.x, mousePos.y)) { // Perform query - std::vector results = queryData(inputText, data); - resultStr.clear(); - for (const auto &result : results) + std::vector qresults = queryData(inputText, data); + results.clear(); + 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.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 @@ -234,31 +406,91 @@ int main() width = event.size.width; height = event.size.height; 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); buttonText.setPosition( - button.getPosition().x + button.getSize().x / 2 - // + button.getPosition().x + button.getSize().x / 2 - buttonText.getCharacterSize() * buttonText.getString().getSize() / 2, 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.clear(sf::Color(0x40, 0x80, 0x40)); window.draw(inputBox); 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(buttonText); - resultView.reset(sf::FloatRect(0.f, 0.f, width - border_size * 2, height - 100.f - border_size)); window.setView(resultView); + window.draw(resultList); window.draw(resultBox); - resultView.move(sf::Vector2f(0, offset)); - window.setView(resultView); - window.draw(resultText); + window.draw(resultTitle); + + 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(); }