Fix inputs and add methods

This commit is contained in:
2026-05-07 13:55:02 +01:00
parent a77f75dcf4
commit 0f693a5de0
12 changed files with 500 additions and 93 deletions
+33 -1
View File
@@ -180,6 +180,8 @@ struct Scene {
element_pool[id]->click();
}
#warning "This does not take rotation into account \
reference and use reverse-transform on point then AABB check instead"
std::vector<uint64_t> elements_at(Vec2<float> position) {
std::vector<uint64_t> result;
@@ -211,6 +213,11 @@ struct App {
uint64_t current_scene_id = 0;
bool running = true;
Vec2<float> mouse_position = {-1, -1};
std::array<bool, 600> down_keys{};
std::vector<Key> pressed_keys;
std::vector<Key> released_keys;
Vec2<float> scroll = {0, 0};
std::string text = "";
void exit() {
running = false;
@@ -246,6 +253,11 @@ struct App {
Scene *scene = scene_pool[current_scene_id];
pressed_keys.clear();
released_keys.clear();
scroll = {0, 0};
text = "";
Event e;
while (window.poll(e)) {
switch (e.type) {
@@ -254,6 +266,12 @@ struct App {
break;
case Event::MOUSE_BUTTON_DOWN:
scene->click(e.mouse_button.position);
down_keys[e.mouse_button.button] = true;
pressed_keys.push_back(e.mouse_button.button);
break;
case Event::MOUSE_BUTTON_UP:
down_keys[e.mouse_button.button] = false;
released_keys.push_back(e.mouse_button.button);
break;
case Event::MOUSE_MOVE:
mouse_position = e.mouse_move.position;
@@ -261,10 +279,24 @@ struct App {
case Event::MOUSE_LEAVE:
mouse_position = {-1, -1};
break;
case Event::KEY_DOWN:
down_keys[e.key.key] = true;
pressed_keys.push_back(e.key.key);
break;
case Event::KEY_UP:
down_keys[e.key.key] = false;
released_keys.push_back(e.key.key);
break;
case Event::SCROLL:
scroll = e.scroll;
break;
case Event::TEXT_INPUT:
text += *e.text_input;
delete e.text_input;
break;
default:
break;
}
window.consume(e);
}
scene->update_scene(dt);
+85 -1
View File
@@ -134,6 +134,16 @@ static mrb_value image_hash(mrb_state *mrb, mrb_value self) {
return mrb_fixnum_value(id);
}
static mrb_value image_width(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_Image(mrb, self);
return mrb_float_value(mrb, window.get_image_size(id).x);
}
static mrb_value image_height(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_Image(mrb, self);
return mrb_float_value(mrb, window.get_image_size(id).y);
}
static void Animation_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
@@ -578,6 +588,18 @@ static mrb_value element_text_click_through_set(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
static mrb_value element_text_width(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_ElementText(mrb, self);
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->size(&window).x);
}
static mrb_value element_text_height(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_ElementText(mrb, self);
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->size(&window).y);
}
static void ElementRect_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
@@ -1413,6 +1435,58 @@ static mrb_value app_mouse_position(mrb_state *mrb, mrb_value) {
return result;
}
static mrb_value app_is_down(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
Key key = get_key(key_name);
return mrb_bool_value(app_->down_keys[key]);
}
static mrb_value app_is_pressed(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
Key key = get_key(key_name);
for (Key pressed_key : app_->pressed_keys)
if (pressed_key == key)
return mrb_bool_value(true);
return mrb_bool_value(false);
}
static mrb_value app_is_released(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
Key key = get_key(key_name);
for (Key released_key : app_->released_keys)
if (released_key == key)
return mrb_bool_value(true);
return mrb_bool_value(false);
}
static mrb_value app_map_key(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_sym action_sym;
mrb_get_args(mrb, "nn", &key_sym, &action_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
std::string action_name = mrb_sym2name(mrb, action_sym);
set_action_mapping(action_name, key_name);
return mrb_nil_value();
}
static mrb_value app_scroll(mrb_state *mrb, mrb_value) {
Vec2<float> scroll = app_->scroll;
mrb_value result = mrb_hash_new(mrb);
HASH_SET(result, x, mrb_float_value(mrb, scroll.x));
HASH_SET(result, y, mrb_float_value(mrb, scroll.y));
return result;
}
static mrb_value app_text_input(mrb_state *mrb, mrb_value) {
return mrb_str_new_cstr(mrb, app_->text.c_str());
}
static mrb_value app_exit(mrb_state *, mrb_value) {
app_->exit();
return mrb_nil_value();
@@ -1428,6 +1502,8 @@ inline void setup() {
ADD_METHOD(Image, "==", image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Image, "eql?", image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Image, "hash", image_hash, MRB_ARGS_NONE());
ADD_METHOD(Image, "width", image_width, MRB_ARGS_NONE());
ADD_METHOD(Image, "height", image_height, MRB_ARGS_NONE());
DEF_CLASS(Animation, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
ADD_METHOD(Animation, "==", animation_equal, MRB_ARGS_REQ(1));
@@ -1463,6 +1539,8 @@ inline void setup() {
ADD_METHOD(ElementText, "z", element_text_z_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "click_through=", element_text_click_through_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "click_through", element_text_click_through_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "width", element_text_width, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "height", element_text_height, MRB_ARGS_NONE());
DEF_CLASS(ElementRect, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1));
ADD_METHOD(ElementRect, "==", element_rect_equal, MRB_ARGS_REQ(1));
@@ -1527,7 +1605,13 @@ inline void setup() {
ADD_MODULE_METHOD(App, "language=", app_language_set, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "language", app_language_get, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "mouse_position", app_mouse_position, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "exit", app_exit, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "down?", app_is_down, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "pressed?", app_is_pressed, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "released?", app_is_released, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "map_key", app_map_key, MRB_ARGS_REQ(2));
ADD_MODULE_METHOD(App, "scroll", app_scroll, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "text_input", app_text_input, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "exit!", app_exit, MRB_ARGS_NONE());
}
} // namespace definitions
+219 -22
View File
@@ -40,6 +40,220 @@ inline Pool<Font> font_pool;
// Text pool
inline Pool<Text> text_pool;
enum Key : uint16_t {
Unknown = SDL_SCANCODE_UNKNOWN,
A = SDL_SCANCODE_A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Num0 = SDL_SCANCODE_0,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
Space = SDL_SCANCODE_SPACE,
Enter = SDL_SCANCODE_RETURN,
Escape = SDL_SCANCODE_ESCAPE,
Tab = SDL_SCANCODE_TAB,
Backspace = SDL_SCANCODE_BACKSPACE,
LeftShift = SDL_SCANCODE_LSHIFT,
RightShift = SDL_SCANCODE_RSHIFT,
LeftCtrl = SDL_SCANCODE_LCTRL,
RightCtrl = SDL_SCANCODE_RCTRL,
LeftAlt = SDL_SCANCODE_LALT,
RightAlt = SDL_SCANCODE_RALT,
CapsLock = SDL_SCANCODE_CAPSLOCK,
Up = SDL_SCANCODE_UP,
Down = SDL_SCANCODE_DOWN,
Left = SDL_SCANCODE_LEFT,
Right = SDL_SCANCODE_RIGHT,
Home = SDL_SCANCODE_HOME,
End = SDL_SCANCODE_END,
PageUp = SDL_SCANCODE_PAGEUP,
PageDown = SDL_SCANCODE_PAGEDOWN,
Delete = SDL_SCANCODE_DELETE,
Insert = SDL_SCANCODE_INSERT,
Minus = SDL_SCANCODE_MINUS,
Equals = SDL_SCANCODE_EQUALS,
LeftBracket = SDL_SCANCODE_LEFTBRACKET,
RightBracket = SDL_SCANCODE_RIGHTBRACKET,
Semicolon = SDL_SCANCODE_SEMICOLON,
Apostrophe = SDL_SCANCODE_APOSTROPHE,
Grave = SDL_SCANCODE_GRAVE,
Comma = SDL_SCANCODE_COMMA,
Period = SDL_SCANCODE_PERIOD,
Slash = SDL_SCANCODE_SLASH,
Backslash = SDL_SCANCODE_NONUSBACKSLASH,
F1 = SDL_SCANCODE_F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
MouseLeft = 513,
MouseMiddle,
MouseRight
};
constexpr std::pair<std::string, Key> KEY_NAMES[] = {
{"a", Key::A},
{"b", Key::B},
{"c", Key::C},
{"d", Key::D},
{"e", Key::E},
{"f", Key::F},
{"g", Key::G},
{"h", Key::H},
{"i", Key::I},
{"j", Key::J},
{"k", Key::K},
{"l", Key::L},
{"m", Key::M},
{"n", Key::N},
{"o", Key::O},
{"p", Key::P},
{"q", Key::Q},
{"r", Key::R},
{"s", Key::S},
{"t", Key::T},
{"u", Key::U},
{"v", Key::V},
{"w", Key::W},
{"x", Key::X},
{"y", Key::Y},
{"z", Key::Z},
{"num0", Key::Num0},
{"num1", Key::Num1},
{"num2", Key::Num2},
{"num3", Key::Num3},
{"num4", Key::Num4},
{"num5", Key::Num5},
{"num6", Key::Num6},
{"num7", Key::Num7},
{"num8", Key::Num8},
{"num9", Key::Num9},
{"space", Key::Space},
{"enter", Key::Enter},
{"escape", Key::Escape},
{"tab", Key::Tab},
{"backspace", Key::Backspace},
{"left_shift", Key::LeftShift},
{"right_shift", Key::RightShift},
{"left_ctrl", Key::LeftCtrl},
{"right_ctrl", Key::RightCtrl},
{"left_alt", Key::LeftAlt},
{"right_alt", Key::RightAlt},
{"capslock", Key::CapsLock},
{"up", Key::Up},
{"down", Key::Down},
{"left", Key::Left},
{"right", Key::Right},
{"home", Key::Home},
{"end", Key::End},
{"page_up", Key::PageUp},
{"page_down", Key::PageDown},
{"delete", Key::Delete},
{"insert", Key::Insert},
{"minus", Key::Minus},
{"equals", Key::Equals},
{"left_bracket", Key::LeftBracket},
{"right_bracket", Key::RightBracket},
{"semicolon", Key::Semicolon},
{"apostrophe", Key::Apostrophe},
{"grave", Key::Grave},
{"comma", Key::Comma},
{"period", Key::Period},
{"slash", Key::Slash},
{"backslash", Key::Backslash},
{"f1", Key::F1},
{"f2", Key::F2},
{"f3", Key::F3},
{"f4", Key::F4},
{"f5", Key::F5},
{"f6", Key::F6},
{"f7", Key::F7},
{"f8", Key::F8},
{"f9", Key::F9},
{"f10", Key::F10},
{"f11", Key::F11},
{"f12", Key::F12},
{"mouse_left", Key::MouseLeft},
{"mouse_middle", Key::MouseMiddle},
{"mouse_right", Key::MouseRight}
};
inline Key get_key_from_name(std::string_view name) {
for (const auto &[key_name, key] : KEY_NAMES)
if (key_name == name)
return key;
return Key::Unknown;
}
inline std::unordered_map<std::string, Key> action_key_map;
inline void set_action_mapping(const std::string &action_name, const std::string &key_name) {
Key key = get_key_from_name(key_name);
if (key != Key::Unknown)
action_key_map[action_name] = key;
}
inline Key get_key(std::string &name) {
auto it = action_key_map.find(name);
if (it != action_key_map.end())
return it->second;
return get_key_from_name(name);
}
struct Event {
enum Type {
NONE,
@@ -56,20 +270,15 @@ struct Event {
union {
struct {
uint32_t key;
Key key;
} key;
struct {
char *text;
uint32_t length;
} text_input;
std::string *text_input;
Vec2<float> scroll;
struct {
float x, y;
} scroll;
struct {
uint8_t button;
Key button;
Vec2<float> position;
} mouse_button;
@@ -125,16 +334,6 @@ public:
bool poll(Event &event); // returns true if an event was polled, false otherwise
// consumes an event, (mostly for text input, to free the text input buffer)
// but also so the user can decide when they're done with the event explicitly.
void consume(Event &event);
// Text input
// Starts accepting Unicode text input events, and stops acceptong normal key down/up events for those keys.
void start_text_input();
void stop_text_input();
// Clipboard get
// To be free'd by the caller after use.
@@ -190,8 +389,6 @@ private:
std::vector<struct RenderInstruction> render_instructions;
bool text_input_active;
void compute_transform();
bool mouse_in_window(const Vec2<float> real_position, Vec2<float> &virtual_position);