Working text drawing and accepting based on input
This commit is contained in:
parent
5709799fdd
commit
51c167bbb4
6 changed files with 172 additions and 12 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
|||
/dvorak_typing_practice
|
||||
/objects/
|
||||
/.cache/
|
||||
/compile_commands.json
|
||||
|
|
3
Makefile
3
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}))
|
||||
|
||||
|
|
BIN
dvorak_keyboard.png
Normal file
BIN
dvorak_keyboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
48
src/main.cc
48
src/main.cc
|
@ -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() {
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
std::cout << "Expected 1 arg input filename!\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
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();
|
||||
word = get_next_word(&ifs);
|
||||
if (!word.empty()) {
|
||||
std::cout << word << '\n';
|
||||
screen.set_word(word);
|
||||
while (!screen.update() && !WindowShouldClose()) {
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
screen.draw();
|
||||
EndDrawing();
|
||||
}
|
||||
}
|
||||
} while (!std::cin.eof() && !WindowShouldClose());
|
||||
}
|
||||
} while (!std::cin.eof());
|
||||
|
||||
CloseWindow();
|
||||
return 0;
|
||||
}
|
||||
|
|
78
src/screen.cc
Normal file
78
src/screen.cc
Normal 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
45
src/screen.h
Normal 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
|
Loading…
Reference in a new issue