SDL/test/testmouse.c

295 lines
7.7 KiB
C
Raw Normal View History

2021-09-09 14:33:35 -06:00
/*
2023-01-09 10:41:41 -07:00
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
2021-09-09 14:33:35 -06:00
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
2021-09-09 14:33:35 -06:00
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
2021-11-13 11:29:50 -07:00
#include <stdlib.h> /* exit() */
#ifdef __IOS__
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
2021-09-09 14:33:35 -06:00
#else
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
2021-09-09 14:33:35 -06:00
#endif
static SDL_Window *window;
typedef struct _Object
{
struct _Object *next;
2021-09-09 14:33:35 -06:00
float x1, y1, x2, y2;
2021-09-09 14:33:35 -06:00
Uint8 r, g, b;
SDL_bool isRect;
} Object;
static Object *active = NULL;
static Object *objects = NULL;
2021-09-09 14:33:35 -06:00
static int buttons = 0;
static SDL_bool isRect = SDL_FALSE;
2021-09-09 14:33:35 -06:00
static SDL_bool wheel_x_active = SDL_FALSE;
static SDL_bool wheel_y_active = SDL_FALSE;
static float wheel_x = SCREEN_WIDTH * 0.5f;
static float wheel_y = SCREEN_HEIGHT * 0.5f;
2021-09-09 14:33:35 -06:00
static SDL_bool done = SDL_FALSE;
void DrawObject(SDL_Renderer *renderer, Object *object)
2021-09-09 14:33:35 -06:00
{
SDL_SetRenderDrawColor(renderer, object->r, object->g, object->b, 255);
if (object->isRect) {
SDL_FRect rect;
if (object->x1 > object->x2) {
rect.x = object->x2;
rect.w = object->x1 - object->x2;
} else {
rect.x = object->x1;
rect.w = object->x2 - object->x1;
}
if (object->y1 > object->y2) {
rect.y = object->y2;
rect.h = object->y1 - object->y2;
} else {
rect.y = object->y1;
rect.h = object->y2 - object->y1;
}
SDL_RenderFillRect(renderer, &rect);
} else {
SDL_RenderLine(renderer, object->x1, object->y1, object->x2, object->y2);
}
2021-09-09 14:33:35 -06:00
}
void DrawObjects(SDL_Renderer *renderer)
2021-09-09 14:33:35 -06:00
{
Object *next = objects;
2021-09-09 14:33:35 -06:00
while (next != NULL) {
DrawObject(renderer, next);
2021-09-09 14:33:35 -06:00
next = next->next;
}
}
void AppendObject(Object *object)
2021-09-09 14:33:35 -06:00
{
if (objects) {
Object *next = objects;
2021-09-09 14:33:35 -06:00
while (next->next != NULL) {
next = next->next;
}
next->next = object;
2021-09-09 14:33:35 -06:00
} else {
objects = object;
2021-09-09 14:33:35 -06:00
}
}
void loop(void *arg)
2021-09-09 14:33:35 -06:00
{
2021-11-23 04:01:10 -07:00
SDL_Renderer *renderer = (SDL_Renderer *)arg;
2021-09-09 14:33:35 -06:00
SDL_Event event;
/* Check for events */
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_MOUSE_WHEEL:
if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
event.wheel.x *= -1;
event.wheel.y *= -1;
}
if (event.wheel.x != 0.0f) {
wheel_x_active = SDL_TRUE;
/* "positive to the right and negative to the left" */
wheel_x += event.wheel.x * 10.0f;
}
if (event.wheel.x != 0.0f) {
wheel_y_active = SDL_TRUE;
/* "positive away from the user and negative towards the user" */
wheel_y -= event.wheel.x * 10.0f;
}
break;
case SDL_EVENT_MOUSE_MOTION:
if (active == NULL) {
2021-09-09 14:33:35 -06:00
break;
}
2021-09-09 14:33:35 -06:00
active->x2 = event.motion.x;
active->y2 = event.motion.y;
break;
case SDL_EVENT_MOUSE_BUTTONDOWN:
if (active == NULL) {
2021-09-09 14:33:35 -06:00
active = SDL_calloc(1, sizeof(*active));
active->x1 = active->x2 = event.button.x;
active->y1 = active->y2 = event.button.y;
active->isRect = isRect;
2021-09-09 14:33:35 -06:00
}
switch (event.button.button) {
case SDL_BUTTON_LEFT:
active->r = 255;
buttons |= SDL_BUTTON_LMASK;
break;
case SDL_BUTTON_MIDDLE:
active->g = 255;
buttons |= SDL_BUTTON_MMASK;
break;
case SDL_BUTTON_RIGHT:
active->b = 255;
buttons |= SDL_BUTTON_RMASK;
break;
case SDL_BUTTON_X1:
active->r = 255;
active->b = 255;
buttons |= SDL_BUTTON_X1MASK;
break;
case SDL_BUTTON_X2:
active->g = 255;
active->b = 255;
buttons |= SDL_BUTTON_X2MASK;
break;
2021-09-09 14:33:35 -06:00
}
break;
case SDL_EVENT_MOUSE_BUTTONUP:
if (active == NULL) {
2021-09-09 14:33:35 -06:00
break;
}
2021-09-09 14:33:35 -06:00
switch (event.button.button) {
case SDL_BUTTON_LEFT:
buttons &= ~SDL_BUTTON_LMASK;
break;
case SDL_BUTTON_MIDDLE:
buttons &= ~SDL_BUTTON_MMASK;
break;
case SDL_BUTTON_RIGHT:
buttons &= ~SDL_BUTTON_RMASK;
break;
case SDL_BUTTON_X1:
buttons &= ~SDL_BUTTON_X1MASK;
break;
case SDL_BUTTON_X2:
buttons &= ~SDL_BUTTON_X2MASK;
break;
2021-09-09 14:33:35 -06:00
}
if (buttons == 0) {
AppendObject(active);
2021-09-09 14:33:35 -06:00
active = NULL;
}
break;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP:
switch (event.key.keysym.sym) {
case SDLK_LSHIFT:
isRect = (event.key.state == SDL_PRESSED);
if (active) {
active->isRect = isRect;
}
break;
}
break;
case SDL_EVENT_QUIT:
2021-09-09 14:33:35 -06:00
done = SDL_TRUE;
break;
default:
break;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
/* Mouse wheel */
SDL_SetRenderDrawColor(renderer, 0, 255, 128, 255);
if (wheel_x_active) {
SDL_RenderLine(renderer, wheel_x, 0.0f, wheel_x, (float)SCREEN_HEIGHT);
}
if (wheel_y_active) {
SDL_RenderLine(renderer, 0.0f, wheel_y, (float)SCREEN_WIDTH, wheel_y);
}
/* Objects from mouse clicks */
DrawObjects(renderer);
if (active) {
DrawObject(renderer, active);
}
2021-09-09 14:33:35 -06:00
SDL_RenderPresent(renderer);
#ifdef __EMSCRIPTEN__
if (done) {
emscripten_cancel_main_loop();
}
#endif
}
int main(int argc, char *argv[])
2021-09-09 14:33:35 -06:00
{
2021-11-23 04:01:10 -07:00
SDL_Renderer *renderer;
2021-09-09 14:33:35 -06:00
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* Initialize SDL (Note: video is required to start event loop) */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
exit(1);
}
/* Create a window to display joystick axis position */
window = SDL_CreateWindow("Mouse Test", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH,
SCREEN_HEIGHT, 0);
if (window == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
return SDL_FALSE;
}
renderer = SDL_CreateRenderer(window, NULL, 0);
2021-09-09 14:33:35 -06:00
if (renderer == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
return SDL_FALSE;
}
/* Main render loop */
#ifdef __EMSCRIPTEN__
2021-11-23 04:01:10 -07:00
emscripten_set_main_loop_arg(loop, renderer, 0, 1);
2021-09-09 14:33:35 -06:00
#else
while (!done) {
2021-11-23 04:01:10 -07:00
loop(renderer);
2021-09-09 14:33:35 -06:00
}
#endif
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}