diff options
Diffstat (limited to 'src/crepe')
| -rw-r--r-- | src/crepe/api/Event.h | 97 | ||||
| -rw-r--r-- | src/crepe/api/Transform.h | 8 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.cpp | 134 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.h | 35 | ||||
| -rw-r--r-- | src/crepe/system/InputSystem.cpp | 102 | 
5 files changed, 239 insertions, 137 deletions
diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index f2f3daf..265e925 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -4,7 +4,7 @@  #include <string>  #include "KeyCodes.h" - +#include "types.h"  namespace crepe {  /** @@ -38,11 +38,8 @@ public:   */  class MousePressEvent : public Event {  public: -	//! X-coordinate of the mouse position at the time of the event. -	int mouse_x = 0; - -	//! Y-coordinate of the mouse position at the time of the event. -	int mouse_y = 0; +	//! mouse position +	ivec2 mouse_pos = {0,0};  	//! The mouse button that was pressed.  	MouseButton button = MouseButton::NONE; @@ -53,11 +50,8 @@ public:   */  class MouseClickEvent : public Event {  public: -	//! X-coordinate of the mouse position at the time of the event. -	int mouse_x = 0; - -	//! Y-coordinate of the mouse position at the time of the event. -	int mouse_y = 0; +	//! mouse position +	ivec2 mouse_pos = {0,0};  	//! The mouse button that was clicked.  	MouseButton button = MouseButton::NONE; @@ -68,11 +62,8 @@ public:   */  class MouseReleaseEvent : public Event {  public: -	//! X-coordinate of the mouse position at the time of the event. -	int mouse_x = 0; - -	//! Y-coordinate of the mouse position at the time of the event. -	int mouse_y = 0; +	//! mouse position +	ivec2 mouse_pos = {0,0};  	//! The mouse button that was released.  	MouseButton button = MouseButton::NONE; @@ -83,17 +74,10 @@ public:   */  class MouseMoveEvent : public Event {  public: -	//! X-coordinate of the mouse position at the time of the event. -	int mouse_x = 0; - -	//! Y-coordinate of the mouse position at the time of the event. -	int mouse_y = 0; - -	// Movement since last event in x -	int delta_x = 0; - -	// Movement since last event in y -	int delta_y = 0; +	//! new mouse position +	ivec2 mouse_pos = {0,0}; +	//! The change in mouse position relative to the last position (in pixels). +	ivec2 mouse_delta = {0,0};  };  /** @@ -101,12 +85,8 @@ public:   */  class MouseScrollEvent : public Event {  public: -	//! X-coordinate of the mouse position at the time of the event. -	int mouse_x = 0; - -	//! Y-coordinate of the mouse position at the time of the event. -	int mouse_y = 0; - +	//! mouse position when the scroll happened. +	ivec2 mouse_pos = {0,0};  	//! scroll direction (-1 = down, 1 = up)  	int scroll_direction = 0;  	//! scroll amount in y axis (from and away from the person). @@ -127,4 +107,55 @@ public:   */  class ShutDownEvent : public Event {}; +/** + * \brief Event triggered to indicate the window is overlapped by another window. + *  + * When two windows overlap the bottom window gets distorted and that window has to be redrawn. + */ +class WindowExposeEvent : public Event{}; + +/** + * \brief Event triggered to indicate the window is resized. + */ +class WindowResizeEvent : public Event{ +	public: +	//! new window dimensions +	ivec2 dimensions = {0,0}; +}; + +/** + * \brief Event triggered to indicate the window is moved. + */ +class WindowMoveEvent : public Event{ +	public: +	//! The change in position relative to the last position (in pixels). +	ivec2 delta_move = {0,0}; +}; + +/** + * \brief Event triggered to indicate the window is minimized. + */ +class WindowMinimizeEvent : public Event{}; + +/** + * \brief Event triggered to indicate the window is maximized + */ +class WindowMaximizeEvent : public Event{}; + +/** + * \brief Event triggered to indicate the window gained focus + *  + * This event is triggered when the window receives focus, meaning it becomes the active window + * for user interaction. + */ +class WindowFocusGainEvent : public Event{}; + +/** + * \brief Event triggered to indicate the window lost focus + *  + * This event is triggered when the window loses focus, meaning it is no longer the active window + * for user interaction. + */ +class WindowFocusLostEvent : public Event{}; +  } // namespace crepe diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h index 7ee6d65..78407ee 100644 --- a/src/crepe/api/Transform.h +++ b/src/crepe/api/Transform.h @@ -13,6 +13,14 @@ namespace crepe {   */  class Transform : public Component {  public: +	//! Specifies the coordinate space for transformations. +	enum Space {  +		//! coordinates are relative to the active camera +		HUD,  +		//! coordinates are relative to the game world +		WORLD, +	}; +	Space coordinate_space = Space::WORLD;  	//! Translation (shift)  	vec2 position = {0, 0};  	//! Rotation, in degrees clockwise diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 4cc2206..e3410cb 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -375,65 +375,83 @@ ivec2 SDLContext::get_size(const Texture & ctx) {  void SDLContext::delay(int ms) const { SDL_Delay(ms); }  std::vector<SDLContext::EventData> SDLContext::get_events() { -	std::vector<SDLContext::EventData> event_list; -	SDL_Event event; -	while (SDL_PollEvent(&event)) { -		switch (event.type) { -			case SDL_QUIT: -				event_list.push_back(EventData{ -					.event_type = SDLContext::EventType::SHUTDOWN, -				}); -				break; -			case SDL_KEYDOWN: -				event_list.push_back(EventData{ -					.event_type = SDLContext::EventType::KEYDOWN, -					.key = sdl_to_keycode(event.key.keysym.scancode), -					.key_repeat = (event.key.repeat != 0), -				}); -				break; -			case SDL_KEYUP: -				event_list.push_back(EventData{ -					.event_type = SDLContext::EventType::KEYUP, -					.key = sdl_to_keycode(event.key.keysym.scancode), -				}); -				break; -			case SDL_MOUSEBUTTONDOWN: -				event_list.push_back(EventData{ -					.event_type = SDLContext::EventType::MOUSEDOWN, -					.mouse_button = sdl_to_mousebutton(event.button.button), -					.mouse_position = {event.button.x, event.button.y}, -				}); -				break; -			case SDL_MOUSEBUTTONUP: { -				int x, y; -				SDL_GetMouseState(&x, &y); -				event_list.push_back(EventData{ -					.event_type = SDLContext::EventType::MOUSEUP, -					.mouse_button = sdl_to_mousebutton(event.button.button), -					.mouse_position = {event.button.x, event.button.y}, -				}); -			} break; - -			case SDL_MOUSEMOTION: { -				event_list.push_back( -					EventData{.event_type = SDLContext::EventType::MOUSEMOVE, -							  .mouse_position = {event.motion.x, event.motion.y}, -							  .rel_mouse_move = {event.motion.xrel, event.motion.yrel}}); -			} break; - -			case SDL_MOUSEWHEEL: { -				event_list.push_back(EventData{ -					.event_type = SDLContext::EventType::MOUSEWHEEL, -					.mouse_position = {event.motion.x, event.motion.y}, -					// TODO: why is this needed? -					.scroll_direction = event.wheel.y < 0 ? -1 : 1, -					.scroll_delta = event.wheel.preciseY, -				}); -			} break; -		} -	} -	return event_list; +    std::vector<SDLContext::EventData> event_list; +    SDL_Event event; + +    // Handle general SDL events +    while (SDL_PollEvent(&event)) { +        switch (event.type) { +            case SDL_QUIT: +                event_list.push_back({SDLContext::EventType::SHUTDOWN, {}, {}, {}}); +                break; +            case SDL_KEYDOWN: +                event_list.push_back({SDLContext::EventType::KEYDOWN,  +                                      {sdl_to_keycode(event.key.keysym.scancode), event.key.repeat != 0}, {}, {}}); +                break; +            case SDL_KEYUP: +                event_list.push_back({SDLContext::EventType::KEYUP,  +                                      {sdl_to_keycode(event.key.keysym.scancode), false}, {}, {}}); +                break; +            case SDL_MOUSEBUTTONDOWN: +                event_list.push_back({SDLContext::EventType::MOUSEDOWN, {},  +                                      {sdl_to_mousebutton(event.button.button), {event.button.x, event.button.y}}, {}}); +                break; +            case SDL_MOUSEBUTTONUP: +                event_list.push_back({SDLContext::EventType::MOUSEUP, {},  +                                      {sdl_to_mousebutton(event.button.button), {event.button.x, event.button.y}}, {}}); +                break; +            case SDL_MOUSEMOTION: +                event_list.push_back({SDLContext::EventType::MOUSEMOVE, {},  +                                      {{}, {event.motion.x, event.motion.y}, -1, INFINITY, {event.motion.xrel, event.motion.yrel}}, {}}); +                break; +            case SDL_MOUSEWHEEL: +                event_list.push_back({SDLContext::EventType::MOUSEWHEEL, {},  +                                      {{}, {}, event.wheel.y < 0 ? -1 : 1, event.wheel.preciseY, {}}, {}}); +                break; + +            // Forward window events for further processing +            case SDL_WINDOWEVENT: +                handle_window_event(event.window, event_list); +                break; +        } +    } + +    return event_list; +} + +// Separate function for SDL_WINDOWEVENT subtypes +void SDLContext::handle_window_event(const SDL_WindowEvent& window_event, +                                     std::vector<SDLContext::EventData>& event_list) { +    switch (window_event.event) { +        case SDL_WINDOWEVENT_EXPOSED: +            event_list.push_back({SDLContext::EventType::WINDOW_EXPOSE, {}, {}, {}}); +            break; +        case SDL_WINDOWEVENT_RESIZED: +            event_list.push_back({SDLContext::EventType::WINDOW_RESIZE, {}, {},  +                                  {{}, {window_event.data1, window_event.data2}}}); +            break; +        case SDL_WINDOWEVENT_MOVED: +            event_list.push_back({SDLContext::EventType::WINDOW_MOVE, {}, {},  +                                  {{window_event.data1, window_event.data2}, {}}}); +            break; +        case SDL_WINDOWEVENT_MINIMIZED: +            event_list.push_back({SDLContext::EventType::WINDOW_MINIMIZE, {}, {}, {}}); +            break; +        case SDL_WINDOWEVENT_MAXIMIZED: +            event_list.push_back({SDLContext::EventType::WINDOW_MAXIMIZE, {}, {}, {}}); +            break; +        case SDL_WINDOWEVENT_FOCUS_GAINED: +            event_list.push_back({SDLContext::EventType::WINDOW_FOCUS_GAIN, {}, {}, {}}); +            break; +        case SDL_WINDOWEVENT_FOCUS_LOST: +            event_list.push_back({SDLContext::EventType::WINDOW_FOCUS_LOST, {}, {}, {}}); +            break; +    }  } + + + +  void SDLContext::set_color_texture(const Texture & texture, const Color & color) {  	SDL_SetTextureColorMod(texture.texture.get(), color.r, color.g, color.b);  	SDL_SetTextureAlphaMod(texture.texture.get(), color.a); diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index e232511..1f83985 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -79,19 +79,37 @@ public:  		KEYUP,  		KEYDOWN,  		SHUTDOWN, - +		WINDOW_MINIMIZE, +		WINDOW_MAXIMIZE, +		WINDOW_FOCUS_GAIN, +		WINDOW_FOCUS_LOST, +		WINDOW_MOVE, +		WINDOW_RESIZE, +		WINDOW_EXPOSE,  	}; -	//! EventData struct for passing event data from facade -	struct EventData { -		SDLContext::EventType event_type = SDLContext::EventType::NONE; +	struct KeyData{  		Keycode key = Keycode::NONE;  		bool key_repeat = false; +	}; +	struct MouseData{  		MouseButton mouse_button = MouseButton::NONE;  		ivec2 mouse_position = {-1, -1};  		int scroll_direction = -1;  		float scroll_delta = INFINITY;  		ivec2 rel_mouse_move = {-1, -1};  	}; +	struct WindowData{ +		ivec2 move_delta; +		ivec2 resize_dimension; +	}; +	//! EventData struct for passing event data from facade +	struct EventData { +		SDLContext::EventType event_type = SDLContext::EventType::NONE; +		KeyData key_data; +		MouseData mouse_data; +		WindowData window_data; +	}; +	  	/**  	 * \brief Gets the singleton instance of SDLContext.  	 * \return Reference to the SDLContext instance. @@ -116,7 +134,14 @@ private:  	 * \return Events that occurred since last call to `get_events()`  	 */  	std::vector<SDLContext::EventData> get_events(); - +	/** +	 * \brief Fills event_list with triggered window events +	 * +	 * This method checks if any window events are triggered and adds them to the event_list. +	 * +	 */ +	void handle_window_event(const SDL_WindowEvent& window_event, +                                     std::vector<SDLContext::EventData>& event_list);  	/**  	 * \brief Converts an SDL key code to the custom Keycode type.  	 * diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index aaa8bdf..b7d2eb4 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -26,29 +26,31 @@ void InputSystem::update() {  	Transform & cam_transform = transform_vec.front().get();  	int camera_origin_x = cam_transform.position.x + current_cam.data.postion_offset.x  						  - (current_cam.viewport_size.x / 2); -	int camera_origin_y = cam_transform.position.y + current_cam.data.postion_offset.y +	int camera_origin_y =  +	ivec2 camera_origin; +	camera_origin.y = cam_transform.position.y + current_cam.data.postion_offset.y  						  - (current_cam.viewport_size.y / 2); - +	camera_origin  	for (const SDLContext::EventData & event : event_list) { -		int world_mouse_x = event.mouse_position.x + camera_origin_x; -		int world_mouse_y = event.mouse_position.y + camera_origin_y; +		int adjusted_mouse_x = event.mouse_data.mouse_position.x + camera_origin_x; +		int adjusted_mouse_y = event.mouse_data.mouse_position.y + camera_origin_y;  		// check if the mouse is within the viewport  		bool mouse_in_viewport -			= !(world_mouse_x < camera_origin_x -				|| world_mouse_x > camera_origin_x + current_cam.viewport_size.x -				|| world_mouse_y < camera_origin_y -				|| world_mouse_y > camera_origin_y + current_cam.viewport_size.y); +			= !(adjusted_mouse_x < camera_origin_x +				|| adjusted_mouse_x > camera_origin_x + current_cam.viewport_size.x +				|| adjusted_mouse_y < camera_origin_y +				|| adjusted_mouse_y > camera_origin_y + current_cam.viewport_size.y);  		switch (event.event_type) {  			case SDLContext::EventType::KEYDOWN:  				event_mgr.queue_event<KeyPressEvent>(KeyPressEvent{ -					.repeat = event.key_repeat, -					.key = event.key, +					.repeat = event.key_data.key_repeat, +					.key = event.key_data.key,  				});  				break;  			case SDLContext::EventType::KEYUP:  				event_mgr.queue_event<KeyReleaseEvent>(KeyReleaseEvent{ -					.key = event.key, +					.key = event.key_data.key,  				});  				break;  			case SDLContext::EventType::MOUSEDOWN: @@ -56,36 +58,32 @@ void InputSystem::update() {  					break;  				}  				event_mgr.queue_event<MousePressEvent>(MousePressEvent{ -					.mouse_x = world_mouse_x, -					.mouse_y = world_mouse_y, -					.button = event.mouse_button, +					.mouse_pos = {adjusted_mouse_x,adjusted_mouse_y}, +					.button = event.mouse_data.mouse_button,  				}); -				this->last_mouse_down_position = {world_mouse_x, world_mouse_y}; -				this->last_mouse_button = event.mouse_button; +				this->last_mouse_down_position = {adjusted_mouse_x, adjusted_mouse_y}; +				this->last_mouse_button = event.mouse_data.mouse_button;  				break;  			case SDLContext::EventType::MOUSEUP: {  				if (!mouse_in_viewport) {  					break;  				}  				event_mgr.queue_event<MouseReleaseEvent>(MouseReleaseEvent{ -					.mouse_x = world_mouse_x, -					.mouse_y = world_mouse_y, -					.button = event.mouse_button, +					.mouse_pos = {adjusted_mouse_x,adjusted_mouse_y}, +					.button = event.mouse_data.mouse_button,  				}); -				//check if its a click by checking the last button down -				int delta_x = world_mouse_x - this->last_mouse_down_position.x; -				int delta_y = world_mouse_y - this->last_mouse_down_position.y; +				int delta_x = adjusted_mouse_x - this->last_mouse_down_position.x; +				int delta_y = adjusted_mouse_y - this->last_mouse_down_position.y; -				if (this->last_mouse_button == event.mouse_button +				if (this->last_mouse_button == event.mouse_data.mouse_button  					&& std::abs(delta_x) <= click_tolerance  					&& std::abs(delta_y) <= click_tolerance) {  					event_mgr.queue_event<MouseClickEvent>(MouseClickEvent{ -						.mouse_x = world_mouse_x, -						.mouse_y = world_mouse_y, -						.button = event.mouse_button, +						.mouse_pos = {adjusted_mouse_x,adjusted_mouse_y}, +						.button = event.mouse_data.mouse_button,  					}); -					this->handle_click(event.mouse_button, world_mouse_x, world_mouse_y); +					this->handle_click(event.mouse_data.mouse_button, adjusted_mouse_x, adjusted_mouse_y);  				}  			} break;  			case SDLContext::EventType::MOUSEMOVE: @@ -93,31 +91,53 @@ void InputSystem::update() {  					break;  				}  				event_mgr.queue_event<MouseMoveEvent>(MouseMoveEvent{ -					.mouse_x = world_mouse_x, -					.mouse_y = world_mouse_y, -					.delta_x = event.rel_mouse_move.x, -					.delta_y = event.rel_mouse_move.y, +					.mouse_pos = {adjusted_mouse_x,adjusted_mouse_y}, +					.mouse_delta = event.mouse_data.rel_mouse_move,  				}); -				this->handle_move(event, world_mouse_x, world_mouse_y); +				this->handle_move(event, adjusted_mouse_x, adjusted_mouse_y);  				break;  			case SDLContext::EventType::MOUSEWHEEL:  				event_mgr.queue_event<MouseScrollEvent>(MouseScrollEvent{ -					.mouse_x = world_mouse_x, -					.mouse_y = world_mouse_y, -					.scroll_direction = event.scroll_direction, -					.scroll_delta = event.scroll_delta, +					.mouse_pos = {adjusted_mouse_x,adjusted_mouse_y}, +					.scroll_direction = event.mouse_data.scroll_direction, +					.scroll_delta = event.mouse_data.scroll_delta,  				});  				break;  			case SDLContext::EventType::SHUTDOWN:  				event_mgr.queue_event<ShutDownEvent>(ShutDownEvent{});  				break; +			case SDLContext::EventType::WINDOW_EXPOSE: +				event_mgr.queue_event<WindowExposeEvent>(WindowExposeEvent{}); +				break; +            case SDLContext::EventType::WINDOW_RESIZE: +				event_mgr.queue_event<WindowResizeEvent>(WindowResizeEvent{ +					.dimensions = event.window_data.resize_dimension, +				}); +				break; +            case SDLContext::EventType::WINDOW_MOVE: +				event_mgr.queue_event<WindowMoveEvent>(WindowMoveEvent{ +					.delta_move = event.window_data.move_delta, +				}); +				break; +            case SDLContext::EventType::WINDOW_MINIMIZE: +				event_mgr.queue_event<WindowMinimizeEvent>(WindowMinimizeEvent{}); +				break; +            case SDLContext::EventType::WINDOW_MAXIMIZE: +				event_mgr.queue_event<WindowMaximizeEvent>(WindowMaximizeEvent{}); +				break; +            case SDLContext::EventType::WINDOW_FOCUS_GAIN: +				event_mgr.queue_event<WindowFocusGainEvent>(WindowFocusGainEvent{}); +				break; +            case SDLContext::EventType::WINDOW_FOCUS_LOST: +				event_mgr.queue_event<WindowFocusLostEvent>(WindowFocusLostEvent{}); +				break;  			default:  				break;  		}  	}  }  void InputSystem::handle_move(const SDLContext::EventData & event_data, -							  const int world_mouse_x, const int world_mouse_y) { +							  const int adjusted_mouse_x, const int adjusted_mouse_y) {  	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); @@ -129,7 +149,7 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data,  		bool was_hovering = button.hover;  		if (button.active -			&& this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { +			&& this->is_mouse_inside_button(adjusted_mouse_x, adjusted_mouse_y, button, transform)) {  			button.hover = true;  			if (!was_hovering && button.on_mouse_enter) {  				button.on_mouse_enter(); @@ -144,8 +164,8 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data,  	}  } -void InputSystem::handle_click(const MouseButton & mouse_button, const int world_mouse_x, -							   const int world_mouse_y) { +void InputSystem::handle_click(const MouseButton & mouse_button, const int adjusted_mouse_x, +							   const int adjusted_mouse_y) {  	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); @@ -156,7 +176,7 @@ void InputSystem::handle_click(const MouseButton & mouse_button, const int world  		Transform & transform = transform_vec.front().get();  		if (button.active -			&& this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { +			&& this->is_mouse_inside_button(adjusted_mouse_x, adjusted_mouse_y, button, transform)) {  			this->handle_button_press(button);  		}  	}  |