Fix Mouse Button errors, implement MouseWheel events
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m42s
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m42s
This commit is contained in:
@@ -57,9 +57,9 @@ namespace ReWindow {
|
||||
class MouseWheelEvent : public MouseEvent
|
||||
{
|
||||
public:
|
||||
int wheel_dt;
|
||||
int WheelMovement;
|
||||
MouseWheelEvent() = default;
|
||||
MouseWheelEvent(int wheel) : MouseEvent(), wheel_dt(wheel) {}
|
||||
MouseWheelEvent(int wheel) : MouseEvent(), WheelMovement(wheel) {}
|
||||
};
|
||||
|
||||
class MouseButtonDownEvent : public MouseEvent {
|
||||
@@ -67,14 +67,14 @@ namespace ReWindow {
|
||||
MouseButton Button;
|
||||
|
||||
MouseButtonDownEvent() = default;
|
||||
MouseButtonDownEvent(MouseButton Button) : MouseEvent() {}
|
||||
MouseButtonDownEvent(MouseButton button) : MouseEvent(), Button(button) {}
|
||||
};
|
||||
|
||||
class MouseButtonUpEvent : public MouseEvent {
|
||||
public:
|
||||
MouseButton Button;
|
||||
MouseButtonUpEvent() = default;
|
||||
MouseButtonUpEvent(MouseButton Button) : MouseEvent() {}
|
||||
MouseButtonUpEvent(MouseButton button) : MouseEvent(), Button(button) {}
|
||||
};
|
||||
|
||||
class WindowResizeRequestEvent : public RWindowEvent
|
||||
|
@@ -19,9 +19,9 @@ private:
|
||||
|
||||
public:
|
||||
static std::vector<Key> GetKeyboard();
|
||||
Key();
|
||||
Key() = default;
|
||||
Key(const char* charcode, X11Scancode scancode, WindowsScancode wSc);
|
||||
const char* CharCode;
|
||||
std::string Mnemonic;
|
||||
X11Scancode x11ScanCode;
|
||||
WindowsScancode winScanCode;
|
||||
bool operator==(const Key& rhs) const;
|
||||
|
@@ -10,13 +10,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class MouseButton {
|
||||
public:
|
||||
MouseButton();
|
||||
explicit MouseButton(const char* charcode, unsigned int index);
|
||||
const char* CharCode;
|
||||
std::string Mnemonic;
|
||||
unsigned int ButtonIndex;
|
||||
|
||||
MouseButton() = default;
|
||||
explicit MouseButton(const std::string& charcode, unsigned int index);
|
||||
|
||||
bool operator == (const MouseButton& mb) const;
|
||||
bool operator<(const MouseButton& rhs) const;
|
||||
MouseButton(const MouseButton&) = default;
|
||||
@@ -25,14 +28,17 @@ public:
|
||||
|
||||
namespace MouseButtons
|
||||
{
|
||||
static const MouseButton Left {"l", 1};
|
||||
static const MouseButton Right {"r", 2};
|
||||
static const MouseButton Middle {"m", 3};
|
||||
static const MouseButton MWheelUp {"1", 4};
|
||||
static const MouseButton MWheelDown {"2", 5};
|
||||
static const MouseButton Mouse4 {"4", 8};
|
||||
static const MouseButton Mouse5 {"5", 9};
|
||||
static const MouseButton Unimplemented {"u", 0};
|
||||
static const MouseButton Left ("L", 1);
|
||||
static const MouseButton Right ("R", 2);
|
||||
static const MouseButton Middle ("M", 3);
|
||||
static const MouseButton Mouse4 ("4", 8);
|
||||
static const MouseButton Mouse5 ("5", 9);
|
||||
static const MouseButton Unimplemented ("?", 0);
|
||||
|
||||
/// NOTE: IsMouseButtonDown will not return correctly for the mouse-wheel-buttons, because the action is effectively instantaneous.
|
||||
static const MouseButton MWheelUp ("U", 4);
|
||||
/// NOTE: IsMouseButtonDown will not return correctly for the mouse-wheel-buttons, because the action is effectively instantaneous.
|
||||
static const MouseButton MWheelDown ("D", 5);
|
||||
}
|
||||
|
||||
MouseButton GetMouseButtonFromXButton(unsigned int button);
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <rewindow/types/gamepadbutton.h>
|
||||
#include <J3ML/LinearAlgebra.hpp>
|
||||
#include <rewindow/types/WindowEvents.hpp>
|
||||
#include <format>
|
||||
|
||||
|
||||
enum class RWindowFlags: uint8_t {
|
||||
@@ -29,8 +30,6 @@ enum class RenderingAPI: uint8_t {
|
||||
VULKAN = 1,
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace ReWindow
|
||||
{
|
||||
using J3ML::LinearAlgebra::Vector2;
|
||||
@@ -47,8 +46,57 @@ namespace ReWindow
|
||||
|
||||
class MouseState {
|
||||
public:
|
||||
std::map<MouseButton, bool> PressedBtns;
|
||||
Vector2 Pos;
|
||||
struct
|
||||
{
|
||||
bool LMB = false;
|
||||
bool RMB = false;
|
||||
bool MMB = false;
|
||||
bool SideButton1 = false;
|
||||
bool SideButton2 = false;
|
||||
bool MWheelUp = false;
|
||||
bool MWheelDown = false;
|
||||
} Buttons;
|
||||
|
||||
|
||||
Vector2 Position;
|
||||
int Wheel = 0;
|
||||
|
||||
[[nodiscard]] bool IsDown(const MouseButton& btn) const
|
||||
{
|
||||
if (btn == MouseButtons::Left) return Buttons.LMB;
|
||||
if (btn == MouseButtons::Right) return Buttons.RMB;
|
||||
if (btn == MouseButtons::Middle) return Buttons.MMB;
|
||||
if (btn == MouseButtons::Mouse4) return Buttons.SideButton1;
|
||||
if (btn == MouseButtons::Mouse5) return Buttons.SideButton2;
|
||||
//if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp;
|
||||
//if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown;
|
||||
|
||||
return false; // Unknown button?
|
||||
}
|
||||
|
||||
void Set(const MouseButton& btn, bool state)
|
||||
{
|
||||
if (btn == MouseButtons::Left) Buttons.LMB = state;
|
||||
if (btn == MouseButtons::Right) Buttons.RMB = state;
|
||||
if (btn == MouseButtons::Middle) Buttons.MMB = state;
|
||||
if (btn == MouseButtons::Mouse4) Buttons.SideButton1 = state;
|
||||
if (btn == MouseButtons::Mouse5) Buttons.SideButton2 = state;
|
||||
//if (btn == MouseButtons::MWheelUp) Buttons.MWheelUp = state;
|
||||
//if (btn == MouseButtons::MWheelDown) Buttons.MWheelDown = state;
|
||||
}
|
||||
|
||||
bool& operator[](const MouseButton& btn)
|
||||
{
|
||||
if (btn == MouseButtons::Left) return Buttons.LMB;
|
||||
if (btn == MouseButtons::Right) return Buttons.RMB;
|
||||
if (btn == MouseButtons::Middle) return Buttons.MMB;
|
||||
if (btn == MouseButtons::Mouse4) return Buttons.SideButton1;
|
||||
if (btn == MouseButtons::Mouse5) return Buttons.SideButton2;
|
||||
//if (btn == MouseButtons::MWheelUp) return Buttons.MWheelUp;
|
||||
//if (btn == MouseButtons::MWheelDown) return Buttons.MWheelDown;
|
||||
|
||||
throw std::runtime_error("Attempted to handle unmapped mouse button");
|
||||
}
|
||||
};
|
||||
|
||||
/// RWindow is a class implementation of a platform-independent window abstraction.
|
||||
@@ -111,6 +159,8 @@ namespace ReWindow
|
||||
/// @see GetAccurateMouseCoordinates().
|
||||
Vector2 GetMouseCoordinates() const;
|
||||
|
||||
int GetMouseWheelPersistent() const { return currentMouse.Wheel;}
|
||||
|
||||
/// Sets which rendering API is to be used with this window.
|
||||
void SetRenderer(RenderingAPI api);
|
||||
|
||||
@@ -149,7 +199,7 @@ namespace ReWindow
|
||||
[[nodiscard]] bool IsKeyDown(Key key) const;
|
||||
|
||||
/// Returns whether the given mouse button is currently being pressed.
|
||||
[[nodiscard]] bool IsMouseButtonDown(MouseButton button) const;
|
||||
[[nodiscard]] bool IsMouseButtonDown(const MouseButton &button) const;
|
||||
|
||||
/// Sets whether or not to make the window fullscreen.
|
||||
/// @note This is implemented per-OS, and as such, it simply requests the OS to do what we want. No guarantee about follow-through can be given.
|
||||
@@ -301,6 +351,7 @@ namespace ReWindow
|
||||
MouseState previousMouse;
|
||||
|
||||
|
||||
|
||||
RenderingAPI renderer = RenderingAPI::OPENGL;
|
||||
|
||||
//Vector2 mouse_coords = {0, 0};
|
||||
@@ -340,9 +391,9 @@ namespace ReWindow
|
||||
/// @note This will be invoked **after** the window-open procedure completes.
|
||||
void processOnOpen();
|
||||
/// Executes event handlers for mouse press events.
|
||||
void processMousePress(MouseButton btn);
|
||||
void processMousePress(const MouseButton& btn);
|
||||
/// Executes event handlers for mouse release events.
|
||||
void processMouseRelease(MouseButton btn);
|
||||
void processMouseRelease(const MouseButton& btn);
|
||||
/// Executes event handlers for window focus events.
|
||||
void processFocusIn();
|
||||
/// Executes event handlers for window unfocus events.
|
||||
|
43
main.cpp
43
main.cpp
@@ -32,6 +32,28 @@ class MyWindow : public ReWindow::RWindow {
|
||||
auto pos = GetMouseCoordinates();
|
||||
//std::cout << pos.x << ", " << pos.y << std::endl;
|
||||
|
||||
//if (IsMouseButtonDown(MouseButtons::MWheelUp))
|
||||
//std::cout << "WheelUp Mouse Button" << std::endl;
|
||||
|
||||
//if (IsMouseButtonDown(MouseButtons::MWheelDown))
|
||||
//std::cout << "WheelDown Mouse Button" << std::endl;
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Left))
|
||||
std::cout << "Left Mouse Button" << std::endl;
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Right))
|
||||
std::cout << "Right Mouse Button" << std::endl;
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Middle))
|
||||
std::cout << "Middle Mouse Button" << std::endl;
|
||||
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Mouse4))
|
||||
std::cout << "Mouse4 Mouse Button" << std::endl;
|
||||
|
||||
if (IsMouseButtonDown(MouseButtons::Mouse5))
|
||||
std::cout << "Mouse5 Mouse Button" << std::endl;
|
||||
|
||||
RWindow::OnRefresh(elapsed);
|
||||
}
|
||||
|
||||
@@ -39,6 +61,18 @@ class MyWindow : public ReWindow::RWindow {
|
||||
std::cout << "resized to " << e.Size.x << ", " << e.Size.y << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnMouseButtonDown(const ReWindow::MouseButtonDownEvent &e) override
|
||||
{
|
||||
std::cout << "Overload Down: " << e.Button.Mnemonic << std::endl;
|
||||
RWindow::OnMouseButtonDown(e);
|
||||
}
|
||||
|
||||
void OnMouseButtonUp(const ReWindow::MouseButtonUpEvent &e) override
|
||||
{
|
||||
std::cout << "Overload Up: " << e.Button.Mnemonic << std::endl;
|
||||
RWindow::OnMouseButtonUp(e);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
@@ -95,14 +129,19 @@ int main() {
|
||||
|
||||
|
||||
window->OnKeyDownEvent += [&] (ReWindow::KeyDownEvent e) {
|
||||
jlog::Debug(e.key.CharCode);
|
||||
jlog::Debug(e.key.Mnemonic);
|
||||
};
|
||||
|
||||
|
||||
window->OnMouseButtonDownEvent += [&] (ReWindow::MouseButtonDownEvent e) {
|
||||
jlog::Debug(e.Button.CharCode);
|
||||
jlog::Debug(e.Button.Mnemonic + std::to_string(e.Button.ButtonIndex));
|
||||
};
|
||||
|
||||
window->OnMouseWheelEvent += [&, window] (ReWindow::MouseWheelEvent e)
|
||||
{
|
||||
std::cout << window->GetMouseWheelPersistent() << std::endl;
|
||||
};
|
||||
|
||||
while (window->IsAlive()) {
|
||||
window->PollEvents();
|
||||
window->ManagedRefresh();
|
||||
|
@@ -166,18 +166,34 @@ void RWindow::PollEvents() {
|
||||
}
|
||||
|
||||
if (xev.type == ButtonRelease) {
|
||||
Logger::Debug(std::format("Recieved event '{}'", "ButtonRelease"));
|
||||
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
|
||||
|
||||
processMouseRelease(button);
|
||||
// Mouse Wheel fires both the ButtonPress and ButtonRelease instantaneously.
|
||||
// Therefore, we handle it as a specific MouseWheel event rather than a MouseButton event,
|
||||
// and only call on ButtonPress, otherwise it will appear to duplicate the mouse wheel scroll.
|
||||
if (xev.xbutton.button != 4 && xev.xbutton.button != 5) {
|
||||
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
|
||||
Logger::Debug(std::format("Recieved event '{}'", "ButtonRelease"));
|
||||
processMouseRelease(button);
|
||||
}
|
||||
}
|
||||
|
||||
if (xev.type == ButtonPress) {
|
||||
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
|
||||
|
||||
Logger::Debug(std::format("Window event: MouseButtonPress {}", button.CharCode));
|
||||
// Mouse Wheel fires both the ButtonPress and ButtonRelease instantaneously.
|
||||
// Therefore, we handle it as a specific MouseWheel event rather than a MouseButton event,
|
||||
// and only call on ButtonPress, otherwise it will appear to duplicate the mouse wheel scroll.
|
||||
if (xev.xbutton.button == 4) {
|
||||
processMouseWheel(-1);
|
||||
} else if (xev.xbutton.button == 5) {
|
||||
processMouseWheel(1);
|
||||
} else
|
||||
{
|
||||
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
|
||||
|
||||
processMousePress(button);
|
||||
Logger::Debug(std::format("Window event: MouseButtonPress {}", button.Mnemonic));
|
||||
|
||||
processMousePress(button);
|
||||
}
|
||||
}
|
||||
|
||||
if (xev.type == Expose)
|
||||
@@ -213,7 +229,7 @@ void RWindow::PollEvents() {
|
||||
|
||||
}
|
||||
previousKeyboard = currentKeyboard;
|
||||
previousMouse.PressedBtns = currentMouse.PressedBtns;
|
||||
previousMouse.Buttons = currentMouse.Buttons;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -33,7 +33,7 @@ RWindow::RWindow(const std::string& title, int width, int height, RenderingAPI r
|
||||
title(title), width(width), height(height), renderer(renderer) {}
|
||||
|
||||
Vector2 RWindow::GetMouseCoordinates() const {
|
||||
return currentMouse.Pos;
|
||||
return currentMouse.Position;
|
||||
}
|
||||
|
||||
bool RWindow::GetFlag(RWindowFlags flag) const {
|
||||
@@ -66,9 +66,9 @@ void RWindow::processFocusOut()
|
||||
OnFocusLostEvent(event);
|
||||
}
|
||||
|
||||
void RWindow::processMousePress(MouseButton btn)
|
||||
void RWindow::processMousePress(const MouseButton& btn)
|
||||
{
|
||||
currentMouse.PressedBtns[btn] = true;
|
||||
currentMouse.Set(btn, true);
|
||||
auto eventData = MouseButtonDownEvent(btn);
|
||||
OnMouseButtonDown(eventData);
|
||||
OnMouseButtonDownEvent(eventData);
|
||||
@@ -77,15 +77,15 @@ void RWindow::processMousePress(MouseButton btn)
|
||||
|
||||
void RWindow::processMouseMove(Vector2 last_pos, Vector2 new_pos)
|
||||
{
|
||||
currentMouse.Pos = new_pos;
|
||||
currentMouse.Position = new_pos;
|
||||
auto eventData = MouseMoveEvent(new_pos);
|
||||
OnMouseMove(eventData);
|
||||
OnMouseMoveEvent(eventData);
|
||||
}
|
||||
|
||||
void RWindow::processMouseRelease(MouseButton btn)
|
||||
void RWindow::processMouseRelease(const MouseButton& btn)
|
||||
{
|
||||
currentMouse.PressedBtns[btn] = false;
|
||||
currentMouse.Set(btn, false);
|
||||
auto eventData = MouseButtonUpEvent(btn);
|
||||
OnMouseButtonUp(eventData);
|
||||
OnMouseButtonUpEvent(eventData);
|
||||
@@ -147,10 +147,9 @@ bool RWindow::IsKeyDown(Key key) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RWindow::IsMouseButtonDown(MouseButton button) const {
|
||||
bool RWindow::IsMouseButtonDown(const MouseButton &button) const {
|
||||
// TODO: Implement MouseButton map
|
||||
for (const auto& pair : currentMouse.PressedBtns)
|
||||
return pair.first == button && pair.second;
|
||||
return currentMouse.IsDown(button);
|
||||
}
|
||||
|
||||
void RWindow::processKeyPress(Key key) {
|
||||
@@ -188,12 +187,12 @@ void RWindow::Refresh() {
|
||||
OnRefresh(delta_time);
|
||||
|
||||
// Only call once and cache the result.
|
||||
currentMouse.Pos = GetAccurateMouseCoordinates();
|
||||
currentMouse.Position = GetAccurateMouseCoordinates();
|
||||
|
||||
/// TODO: Implement optional minimum epsilon to trigger a Mouse Update.
|
||||
if (currentMouse.Pos != previousMouse.Pos) {
|
||||
processMouseMove(previousMouse.Pos, currentMouse.Pos);
|
||||
previousMouse.Pos = currentMouse.Pos;
|
||||
if (currentMouse.Position != previousMouse.Position) {
|
||||
processMouseMove(previousMouse.Position, currentMouse.Position);
|
||||
previousMouse.Position = currentMouse.Position;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -224,9 +223,12 @@ void RWindow::UpdateFrameTiming(float frame_time) {
|
||||
|
||||
void RWindow::processMouseWheel(int scrolls)
|
||||
{
|
||||
currentMouse.Wheel += scrolls;
|
||||
auto ev = MouseWheelEvent(scrolls);
|
||||
OnMouseWheel(ev);
|
||||
OnMouseWheelEvent(ev);
|
||||
|
||||
previousMouse.Wheel = currentMouse.Wheel;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,26 +4,22 @@
|
||||
|
||||
std::vector<Key> Key::GetKeyboard() { return keyboard; }
|
||||
|
||||
Key::Key() {
|
||||
keyboard.push_back(*this);
|
||||
}
|
||||
|
||||
|
||||
Key::Key(const char* charcode, X11Scancode scancode, WindowsScancode sc)
|
||||
: CharCode(charcode), x11ScanCode(scancode), winScanCode(sc)
|
||||
: Mnemonic(charcode), x11ScanCode(scancode), winScanCode(sc)
|
||||
{
|
||||
//TODO doing this is what crashes the program.
|
||||
keyboard.push_back(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Key::operator==(const Key &rhs) const {
|
||||
//This is not a good workaround.
|
||||
return (this->x11ScanCode == rhs.x11ScanCode);
|
||||
}
|
||||
|
||||
bool Key::operator<(const Key &rhs) const {
|
||||
return (this->CharCode < rhs.CharCode);
|
||||
return (this->Mnemonic < rhs.Mnemonic);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,12 +1,11 @@
|
||||
#include <rewindow/types/mousebutton.h>
|
||||
#include <string>
|
||||
#include <X11/X.h>
|
||||
#include "rewindow/logger/logger.h"
|
||||
|
||||
MouseButton::MouseButton() {
|
||||
}
|
||||
|
||||
MouseButton::MouseButton(const char* charcode, unsigned int index) {
|
||||
this->CharCode = charcode;
|
||||
MouseButton::MouseButton(const std::string& charcode, unsigned int index) {
|
||||
this->Mnemonic = charcode;
|
||||
this->ButtonIndex = index;
|
||||
}
|
||||
|
||||
@@ -15,7 +14,7 @@ bool MouseButton::operator==(const MouseButton &mb) const {
|
||||
}
|
||||
|
||||
bool MouseButton::operator<(const MouseButton &rhs) const {
|
||||
return (this->CharCode < rhs.CharCode);
|
||||
return (this->ButtonIndex < rhs.ButtonIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +23,8 @@ MouseButton GetMouseButtonFromXButton(unsigned int button) {
|
||||
case 1: return MouseButtons::Left;
|
||||
case 2: return MouseButtons::Middle;
|
||||
case 3: return MouseButtons::Right;
|
||||
case 4: return MouseButtons::MWheelUp;
|
||||
case 5: return MouseButtons::MWheelDown;
|
||||
//case 4: return MouseButtons::MWheelUp;
|
||||
//case 5: return MouseButtons::MWheelDown;
|
||||
//For *whatever* reason. These aren't in X.h
|
||||
case 8: return MouseButtons::Mouse4;
|
||||
case 9: return MouseButtons::Mouse5;
|
||||
|
Reference in New Issue
Block a user