Working text drawing and accepting based on input

This commit is contained in:
Stephen Seo 2023-12-14 17:39:11 +09:00
parent 5709799fdd
commit 51c167bbb4
6 changed files with 172 additions and 12 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
/dvorak_typing_practice
/objects/
/.cache/
/compile_commands.json

View file

@ -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}))

BIN
dvorak_keyboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -1,10 +1,18 @@
// Standard library includes
#include <string>
#include <iostream>
#include <fstream>
std::string get_next_word() {
// Third party includes
#include <raylib.h>
// 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<char>::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;
}

78
src/screen.cc Normal file
View file

@ -0,0 +1,78 @@
#include "screen.h"
#include <raylib.h>
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);
}
}

45
src/screen.h Normal file
View file

@ -0,0 +1,45 @@
#ifndef DVORAK_TYPING_PRACTICE_SCREEN_H_
#define DVORAK_TYPING_PRACTICE_SCREEN_H_
// Standard library includes
#include <array>
#include <bitset>
#include <string>
// Third party includes
#include <raylib.h>
// 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<char, 2> word_center;
Texture2D keyboard;
unsigned int idx;
/*
* 0 - cached word data is dirty
*/
std::bitset<32> flags;
};
#endif