增加查询结果列表、内容点击显示
This commit is contained in:
parent
1251d2f72b
commit
de9b082004
|
@ -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)
|
||||
|
|
298
src/main.cpp
298
src/main.cpp
|
@ -5,6 +5,9 @@
|
|||
#include <vector>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
|
||||
int font_size = 15;
|
||||
float width = 800.f;
|
||||
|
@ -59,17 +62,29 @@ std::vector<QueryResult> 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<float>(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<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()
|
||||
{
|
||||
std::wstring resultStr;
|
||||
float offset = 0.f;
|
||||
std::map<std::wstring, std::wstring> results;
|
||||
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Îļþ
|
||||
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<QueryResult> results = queryData(inputText, data);
|
||||
resultStr.clear();
|
||||
for (const auto &result : results)
|
||||
std::vector<QueryResult> 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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue