From 51c167bbb488400aafe5b66ab3ae0ea7412d88cb Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Thu, 14 Dec 2023 17:39:11 +0900 Subject: [PATCH] Working text drawing and accepting based on input --- .gitignore | 2 ++ Makefile | 3 +- dvorak_keyboard.png | Bin 0 -> 16269 bytes src/main.cc | 56 ++++++++++++++++++++++++------- src/screen.cc | 78 ++++++++++++++++++++++++++++++++++++++++++++ src/screen.h | 45 +++++++++++++++++++++++++ 6 files changed, 172 insertions(+), 12 deletions(-) create mode 100644 dvorak_keyboard.png create mode 100644 src/screen.cc create mode 100644 src/screen.h diff --git a/.gitignore b/.gitignore index cd0ac6e..0043117 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /dvorak_typing_practice /objects/ +/.cache/ +/compile_commands.json diff --git a/Makefile b/Makefile index b9233e2..ce0296a 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,8 @@ endif OBJDIR = objects -SOURCES = src/main.cc +SOURCES = src/main.cc \ + src/screen.cc OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.o,${SOURCES})) diff --git a/dvorak_keyboard.png b/dvorak_keyboard.png new file mode 100644 index 0000000000000000000000000000000000000000..81a3ef678d6dfda763a21f8c487e574ba5c7461d GIT binary patch literal 16269 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 BJP!Z> literal 0 HcmV?d00001 diff --git a/src/main.cc b/src/main.cc index 18e4a2b..ba93dde 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,10 +1,18 @@ +// Standard library includes #include #include +#include -std::string get_next_word() { +// Third party includes +#include + +// Local includes +#include "screen.h" + +std::string get_next_word(std::istream *i) { std::string word; - while (std::cin.good()) { - int in = std::cin.get(); + while (i->good()) { + int in = i->get(); if (in != std::char_traits::eof() && in != ' ' && in != '\n' && in != '\r') { word.push_back((char)in); } else if (in == ' '|| in == '\n' || in == '\r' || in == '\t') { @@ -15,15 +23,41 @@ std::string get_next_word() { return word; } -int main() { - std::string word; +int main(int argc, char **argv) { + if (argc != 2) { + std::cout << "Expected 1 arg input filename!\n"; + return 1; + } - do { - word = get_next_word(); - if (!word.empty()) { - std::cout << word << '\n'; - } - } while (!std::cin.eof()); + std::ifstream ifs(argv[1]); + if (!ifs.good()) { + std::cout << "ERROR: Failed to open file \"" << argv[1] << "\"!\n"; + return 2; + } + + InitWindow(900, 400, "Dvorak Typing Practice"); + SetTargetFPS(15); + + { + Screen screen{}; + + std::string word; + + do { + word = get_next_word(&ifs); + if (!word.empty()) { + screen.set_word(word); + while (!screen.update() && !WindowShouldClose()) { + BeginDrawing(); + ClearBackground(BLACK); + screen.draw(); + EndDrawing(); + } + } + } while (!std::cin.eof() && !WindowShouldClose()); + } + + CloseWindow(); return 0; } diff --git a/src/screen.cc b/src/screen.cc new file mode 100644 index 0000000..15832bb --- /dev/null +++ b/src/screen.cc @@ -0,0 +1,78 @@ +#include "screen.h" +#include + +Screen::Screen() : +prev(), +word(), +word_center{0, 0}, +keyboard(LoadTexture("dvorak_keyboard.png")), +idx(0) +{ + flags.set(0); +} + +Screen::~Screen() { + UnloadTexture(keyboard); +} + +void Screen::set_word(std::string s) { + prev = word; + word = s; + idx = 0; + word_pre.clear(); + word_post.clear(); + word_center[0] = s.at(0); + flags.set(0); +} + +bool Screen::update() { + int input = GetCharPressed(); + if (input == word_center[0]) { + ++idx; + flags.set(0); + if (idx >= word.size()) { + return true; + } + } + + return false; +} + +void Screen::draw() { + DrawTexture(keyboard, 0, 0, WHITE); + if (flags.test(0)) { + flags.reset(0); + + if (idx > 0) { + word_pre = word.substr(0, idx); + } else { + word_pre.clear(); + } + + if (idx < word.size()) { + word_post = word.substr(idx + 1, word.size() - idx - 1); + } else { + word_post.clear(); + } + + word_center[0] = word.at(idx); + } + + int offset = 0; + if (!prev.empty()) { + DrawText(prev.c_str(), LEFT_OFFSET + offset, TOP_OFFSET, FONT_SIZE, Color{127, 127, 127, 255}); + offset += MeasureText(prev.c_str(), FONT_SIZE) + PREV_OFFSET; + } + + if (!word_pre.empty()) { + DrawText(word_pre.c_str(), LEFT_OFFSET + offset, TOP_OFFSET, FONT_SIZE, WHITE); + offset += MeasureText(word_pre.c_str(), FONT_SIZE) + CENTER_X_OFFSET; + } + + DrawText(word_center.data(), LEFT_OFFSET + offset, TOP_OFFSET, FONT_SIZE, GREEN); + offset += MeasureText(word_center.data(), FONT_SIZE) + CENTER_X_OFFSET; + + if (!word_post.empty()) { + DrawText(word_post.c_str(), LEFT_OFFSET + offset, TOP_OFFSET, FONT_SIZE, WHITE); + } +} diff --git a/src/screen.h b/src/screen.h new file mode 100644 index 0000000..13164f1 --- /dev/null +++ b/src/screen.h @@ -0,0 +1,45 @@ +#ifndef DVORAK_TYPING_PRACTICE_SCREEN_H_ +#define DVORAK_TYPING_PRACTICE_SCREEN_H_ + +// Standard library includes +#include +#include +#include + +// Third party includes +#include + +// Constants +constexpr int LEFT_OFFSET = 20; +constexpr int TOP_OFFSET = 320; +constexpr int FONT_SIZE = 40; +constexpr int CENTER_X_OFFSET = FONT_SIZE / 2; +constexpr int PREV_OFFSET = FONT_SIZE * 2; + +class Screen { +public: + Screen(); + ~Screen(); + + void set_word(std::string s); + + // True if finished with word. + bool update(); + void draw(); + +private: + std::string prev; + std::string word; + std::string word_pre; + std::string word_post; + std::array word_center; + Texture2D keyboard; + unsigned int idx; + /* + * 0 - cached word data is dirty + */ + std::bitset<32> flags; + +}; + +#endif