aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-14 19:09:14 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-14 19:09:14 +0200
commit70dbffca112f7deb26a470c12ae56d11137aae86 (patch)
tree5216b0914f0ce3adbebdfbac26aee91218270da8
parent0fc9eb828c0236d759698186dcbdefb2370e61b7 (diff)
WIP keyboard shortcuts
-rw-r--r--Scancode.h11
-rw-r--r--View.cpp41
-rw-r--r--View.h6
-rw-r--r--ViewController.cpp50
-rw-r--r--ViewController.h14
-rw-r--r--main.cpp24
6 files changed, 113 insertions, 33 deletions
diff --git a/Scancode.h b/Scancode.h
new file mode 100644
index 0000000..d838bf2
--- /dev/null
+++ b/Scancode.h
@@ -0,0 +1,11 @@
+#pragma once
+
+typedef enum {
+ KEY_SPACE = 44,
+ KEY_ENTER = 40,
+ KEY_O = 18,
+ KEY_A = 4,
+ KEY_LEFT = 80,
+ KEY_RIGHT = 79,
+} Scancode;
+
diff --git a/View.cpp b/View.cpp
index fd80b79..c53ad8f 100644
--- a/View.cpp
+++ b/View.cpp
@@ -1,10 +1,14 @@
#include <SDL3/SDL.h>
+#include <SDL3/SDL_events.h>
#include <thread>
+#include <vector>
#include "View.h"
#include "ViewController.h"
-View::View(Museum & m) : controller(m) {
+using namespace std;
+
+View::View(Museum & m) : controller(m, *this) {
this->worker = new std::thread(&View::work, this);
}
@@ -24,18 +28,27 @@ void View::work() {
for (SDL_Event e; SDL_PollEvent(&e);) {
if (e.type == SDL_EVENT_QUIT) {
this->open = false;
- return;
+ continue;
+ }
+ if (e.type == SDL_EVENT_KEY_DOWN) {
+ this->ev_keydown(e.key);
+ continue;
}
}
this->draw_begin();
- this->controller.update(*this);
+ this->controller.update();
this->draw_end();
}
this->window_deinit();
}
+void View::ev_keydown(SDL_KeyboardEvent ev) {
+ if (ev.repeat) return;
+ this->controller.keypress(static_cast<Scancode>(ev.scancode));
+}
+
void View::window_init() {
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
this->window = SDL_CreateWindow(
@@ -60,7 +73,7 @@ void View::window_deinit() {
SDL_Quit();
}
-void View::set_size(unsigned int width, unsigned int height) {
+void View::window_size(unsigned int width, unsigned int height) {
if (this->width == width && this->height == height) return;
SDL_SetWindowSize(this->window, width, height);
@@ -88,3 +101,23 @@ void View::draw_rect(Rectangle r, Color c) {
SDL_RenderFillRect(this->renderer, &rect);
}
+typedef struct {
+ bool open;
+ vector<string> out;
+} dialog_file_tmp_data;
+vector<string> View::dialog_file() {
+ dialog_file_tmp_data data = {
+ .open = true,
+ .out = {},
+ };
+ SDL_DialogFileCallback callback = [](void * userdata, const char * const * files, int) -> void {
+ dialog_file_tmp_data * data = static_cast<dialog_file_tmp_data*>(userdata);
+ for (; *files != NULL; files++)
+ data->out.push_back(std::string(*files));
+ data->open = false;
+ };
+ SDL_ShowOpenFileDialog(callback, &data, this->window, NULL, 0, NULL, true);
+ while (data.open);
+ return data.out;
+}
+
diff --git a/View.h b/View.h
index ef9e937..5c8a2a6 100644
--- a/View.h
+++ b/View.h
@@ -2,6 +2,8 @@
#include <SDL2/SDL.h>
#include <thread>
+#include <vector>
+#include <string>
#include "Color.h"
#include "Rectangle.h"
@@ -13,7 +15,8 @@ public:
virtual ~View();
public:
- virtual void set_size(unsigned int width, unsigned int height);
+ virtual void window_size(unsigned int width, unsigned int height);
+ virtual std::vector<std::string> dialog_file();
virtual void draw_rect(Rectangle r, Color c);
private:
@@ -21,6 +24,7 @@ private:
virtual void draw_end();
virtual void window_init();
virtual void window_deinit();
+ virtual void ev_keydown(SDL_KeyboardEvent);
public:
bool open = true;
diff --git a/ViewController.cpp b/ViewController.cpp
index 269edaa..c7fa50d 100644
--- a/ViewController.cpp
+++ b/ViewController.cpp
@@ -1,23 +1,24 @@
#include "ViewController.h"
+#include "Scancode.h"
#include "View.h"
#include "Museum.h"
-ViewController::ViewController(Museum & m) : museum(m) {};
+ViewController::ViewController(Museum & m, View & v) : museum(m), view(v) {};
-void ViewController::update(View & view) {
- this->update_size(view);
- this->update_tiles(view);
- this->update_artists(view);
+void ViewController::update() {
+ this->update_size();
+ this->update_tiles();
+ this->update_artists();
}
-void ViewController::update_size(View & view) {
- view.set_size(
+void ViewController::update_size() {
+ this->view.window_size(
this->scale * this->museum.canvas.data.columns,
this->scale * this->museum.canvas.data.rows
);
}
-void ViewController::update_tiles(View & view) {
+void ViewController::update_tiles() {
for (unsigned y = 0; y < this->museum.canvas.data.rows; y++) {
for (unsigned x = 0; x < this->museum.canvas.data.columns; x++) {
Tile & tile = this->museum.canvas.get_tile(x, y);
@@ -27,12 +28,12 @@ void ViewController::update_tiles(View & view) {
.width = scale - line_width,
.height = scale - line_width,
};
- view.draw_rect(rect, tile.color);
+ this->view.draw_rect(rect, tile.color);
}
}
}
-void ViewController::update_artists(View & view) {
+void ViewController::update_artists() {
People & people = this->museum.people;
for (Artist * artist : people.get_artists()) {
if (artist == nullptr) continue;
@@ -42,7 +43,34 @@ void ViewController::update_artists(View & view) {
.width = artist_size,
.height = artist_size,
};
- view.draw_rect(rect, artist->color);
+ this->view.draw_rect(rect, artist->color);
+ }
+}
+
+void ViewController::keypress(Scancode scancode) {
+ switch (scancode) {
+ KEY_SPACE: {
+ printf("TODO: toggle museum.pause\n");
+ break;
+ }
+ KEY_ENTER: {
+ break;
+ }
+ KEY_O: {
+ printf("TODO: open dialog\n");
+ this->view.dialog_file();
+ break;
+ }
+ KEY_A: {
+ break;
+ }
+ KEY_LEFT: {
+ break;
+ }
+ KEY_RIGHT: {
+ break;
+ }
+ default: break;
}
}
diff --git a/ViewController.h b/ViewController.h
index bffd0b2..9e1e812 100644
--- a/ViewController.h
+++ b/ViewController.h
@@ -1,22 +1,26 @@
#pragma once
+#include "Scancode.h"
+
class View;
class Museum;
class ViewController {
public:
- ViewController(Museum & m);
+ ViewController(Museum & m, View & v);
public:
- void update(View & v);
+ void update();
+ void keypress(Scancode scancode);
private:
- void update_size(View & v);
- void update_tiles(View & v);
- void update_artists(View & v);
+ void update_size();
+ void update_tiles();
+ void update_artists();
private:
Museum & museum;
+ View & view;
private:
unsigned int scale = 16;
diff --git a/main.cpp b/main.cpp
index d824e5a..f9ef3c0 100644
--- a/main.cpp
+++ b/main.cpp
@@ -31,22 +31,22 @@ static void parse(FileStrategy & file, Deserializer & deserializer, const char *
int main(int argc, char** argv) {
Museum museum {};
+ View view { museum };
- museum.set_pause(true);
-
- Deserializer deserializer { museum };
-
- for (int i = 1; i < argc; i++) {
- char * url = argv[i];
+ { // load files provided on command line
+ Deserializer deserializer { museum };
+ museum.set_pause(true);
+ for (int i = 1; i < argc; i++) {
+ char * url = argv[i];
- unique_ptr<FileStrategy> file = open(url);
- parse(*file, deserializer, url);
+ unique_ptr<FileStrategy> file = open(url);
+ parse(*file, deserializer, url);
+ }
+ museum.set_pause(false);
}
- View view { museum };
-
- museum.set_pause(false);
-
+ // Museum and View both create their own worker threads, so the main thread
+ // should remain to keep the view active.
while (view.open);
return EXIT_SUCCESS;