406 lines
12 KiB
C++
406 lines
12 KiB
C++
//
|
|
// Window and input event handling
|
|
//
|
|
#include <algorithm>
|
|
#include <SDL.h>
|
|
#include <SDL_opengles2.h>
|
|
#include "events.h"
|
|
|
|
// #define EVENTS_DEBUG
|
|
|
|
void EventHandler::windowResizeEvent(int width, int height)
|
|
{
|
|
if(width<=0 || height<=0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
printf("windowResizeEvnet: %d, %d\n", width, height);
|
|
glViewport(0, 0, width, height);
|
|
mCamera.setWindowSize(width, height);
|
|
|
|
m_InteractionMode = (int)MODE_PAN;
|
|
}
|
|
|
|
SDL_Renderer* EventHandler::GetRenderer()
|
|
{
|
|
return m_pRenderer;
|
|
}
|
|
|
|
void EventHandler::SetInteractionMode(int mode)
|
|
{
|
|
m_InteractionMode = mode;
|
|
}
|
|
|
|
void EventHandler::initWindow(const char* title)
|
|
{
|
|
// Create SDL window
|
|
/*
|
|
mpWindow =
|
|
SDL_CreateWindow(title,
|
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
|
mCamera.windowSize().width, mCamera.windowSize().height,
|
|
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE| SDL_WINDOW_SHOWN);
|
|
*/
|
|
|
|
SDL_CreateWindowAndRenderer(mCamera.windowSize().width, mCamera.windowSize().height,
|
|
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE| SDL_WINDOW_SHOWN,
|
|
&mpWindow, &m_pRenderer);
|
|
|
|
|
|
|
|
mWindowID = SDL_GetWindowID(mpWindow);
|
|
|
|
printf("Window Created!!!! Width:%d, Height: %d\n", mCamera.windowSize().width, mCamera.windowSize().height);
|
|
|
|
// Create OpenGLES 2 context on SDL window
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
|
SDL_GL_SetSwapInterval(1);
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
|
SDL_GLContext glc = SDL_GL_CreateContext(mpWindow);
|
|
|
|
// Set clear color to black
|
|
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
// Initialize viewport
|
|
windowResizeEvent(mCamera.windowSize().width, mCamera.windowSize().height);
|
|
|
|
m_nEventType = 0;
|
|
|
|
m_fDeltaX = 0;
|
|
m_fDeltaY = 0;
|
|
}
|
|
|
|
void EventHandler::swapWindow()
|
|
{
|
|
SDL_GL_SwapWindow(mpWindow);
|
|
}
|
|
|
|
void EventHandler::zoom(float fDelta)
|
|
{
|
|
//float zoomDelta = mouseWheelDown ? -cMouseWheelZoomDelta : cMouseWheelZoomDelta;
|
|
|
|
float zoomDelta = 0.0f;
|
|
|
|
if(fDelta>0)
|
|
{
|
|
zoomDelta = -cMouseWheelZoomDelta;
|
|
}
|
|
else
|
|
{
|
|
zoomDelta = cMouseWheelZoomDelta;
|
|
}
|
|
mCamera.setZoomDelta(zoomDelta);
|
|
|
|
}
|
|
|
|
void EventHandler::zoomEventMouse(bool mouseWheelDown, int x, int y)
|
|
{
|
|
float preZoomWorldX, preZoomWorldY;
|
|
mCamera.windowToWorldCoords(mMousePositionX, mMousePositionY, preZoomWorldX, preZoomWorldY);
|
|
|
|
// Zoom by scaling up/down in 0.05 increments
|
|
float zoomDelta = mouseWheelDown ? -cMouseWheelZoomDelta : cMouseWheelZoomDelta;
|
|
mCamera.setZoomDelta(zoomDelta);
|
|
|
|
// Zoom to point: Keep the world coords under mouse position the same before and after the zoom
|
|
float postZoomWorldX, postZoomWorldY;
|
|
mCamera.windowToWorldCoords(mMousePositionX, mMousePositionY, postZoomWorldX, postZoomWorldY);
|
|
Vec2 deltaWorld = { postZoomWorldX - preZoomWorldX, postZoomWorldY - preZoomWorldY };
|
|
mCamera.setPanDelta (deltaWorld);
|
|
}
|
|
|
|
void EventHandler::zoomEventPinch (float pinchDist, float pinchX, float pinchY)
|
|
{
|
|
float preZoomWorldX, preZoomWorldY;
|
|
mCamera.normWindowToWorldCoords(pinchX, pinchY, preZoomWorldX, preZoomWorldY);
|
|
|
|
// Zoom in/out by positive/negative mPinch distance
|
|
float zoomDelta = pinchDist * cPinchScale;
|
|
mCamera.setZoomDelta(zoomDelta);
|
|
|
|
// Zoom to point: Keep the world coords under pinch position the same before and after the zoom
|
|
float postZoomWorldX, postZoomWorldY;
|
|
mCamera.normWindowToWorldCoords(pinchX, pinchY, postZoomWorldX, postZoomWorldY);
|
|
Vec2 deltaWorld = { postZoomWorldX - preZoomWorldX, postZoomWorldY - preZoomWorldY };
|
|
mCamera.setPanDelta (deltaWorld);
|
|
}
|
|
|
|
void EventHandler::SetMouseButtonDownPosition(int x, int y)
|
|
{
|
|
mMouseButtonDownX = x;
|
|
mMouseButtonDownY = y;
|
|
|
|
mMouseButtonDown = true;
|
|
|
|
mCamera.setBasePan();
|
|
|
|
}
|
|
|
|
void EventHandler::SetMouseButtonUpPosition(int x, int y)
|
|
{
|
|
m_nEventType = 3;
|
|
|
|
mMouseButtonDown = false;
|
|
}
|
|
|
|
void EventHandler::panEventMouse(int x, int y)
|
|
{
|
|
m_nEventType = 1;
|
|
|
|
int deltaX = mCamera.windowSize().width / 2 + (x - mMouseButtonDownX),
|
|
deltaY = mCamera.windowSize().height / 2 + (y - mMouseButtonDownY);
|
|
|
|
if(m_InteractionMode&InteractionMode::MODE_WIDTHLEVEL)
|
|
{
|
|
m_fDeltaX = x - mMouseButtonDownX;
|
|
m_fDeltaY = y - mMouseButtonDownY;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
float deviceX, deviceY;
|
|
mCamera.windowToDeviceCoords(deltaX, deltaY, deviceX, deviceY);
|
|
|
|
|
|
Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(),
|
|
mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() };
|
|
mCamera.setPan(pan);
|
|
/*
|
|
int deltaX = mCamera.windowSize().width / 2 + (x - mMouseButtonDownX),
|
|
deltaY = mCamera.windowSize().height / 2 + (y - mMouseButtonDownY);
|
|
|
|
m_nEventType = 1;
|
|
m_fDeltaX = x - mMouseButtonDownX;
|
|
m_fDeltaY = y - mMouseButtonDownY;
|
|
|
|
return;
|
|
float deviceX, deviceY;
|
|
mCamera.windowToDeviceCoords(deltaX, deltaY, deviceX, deviceY);
|
|
|
|
Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(),
|
|
mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() };
|
|
mCamera.setPan(pan);
|
|
*/
|
|
}
|
|
|
|
void EventHandler::panEventFinger(float x, float y)
|
|
{
|
|
m_nEventType = 2;
|
|
|
|
if(m_InteractionMode&InteractionMode::MODE_WIDTHLEVEL)
|
|
{
|
|
int nWidth = mCamera.windowSize().width;
|
|
int nHeight = mCamera.windowSize().height;
|
|
m_fDeltaX = (x - mFingerDownX)*nWidth;
|
|
m_fDeltaY = (y - mFingerDownY)*nHeight;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
float deltaX = 0.5f + (x - mFingerDownX),
|
|
deltaY = 0.5f + (y - mFingerDownY);
|
|
|
|
float deviceX, deviceY;
|
|
mCamera.normWindowToDeviceCoords(deltaX, deltaY, deviceX, deviceY);
|
|
|
|
Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(),
|
|
mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() };
|
|
mCamera.setPan(pan);
|
|
|
|
/*
|
|
float deltaX = 0.5f + (x - mFingerDownX),
|
|
deltaY = 0.5f + (y - mFingerDownY);
|
|
|
|
m_nEventType = 2;
|
|
|
|
int nWidth = mCamera.windowSize().width;
|
|
int nHeight = mCamera.windowSize().height;
|
|
m_fDeltaX = (x - mFingerDownX)*nWidth;
|
|
m_fDeltaY = (y - mFingerDownY)*nHeight;
|
|
|
|
return;
|
|
|
|
float deviceX, deviceY;
|
|
mCamera.normWindowToDeviceCoords(deltaX, deltaY, deviceX, deviceY);
|
|
|
|
Vec2 pan = { mCamera.basePan().x + deviceX / mCamera.zoom(),
|
|
mCamera.basePan().y + deviceY / mCamera.zoom() / mCamera.aspect() };
|
|
mCamera.setPan(pan);
|
|
*/
|
|
}
|
|
|
|
int EventHandler::GetEventType()
|
|
{
|
|
return m_nEventType;
|
|
}
|
|
|
|
float EventHandler::GetDeltaX()
|
|
{
|
|
return m_fDeltaX;
|
|
}
|
|
|
|
float EventHandler::GetDeltaY()
|
|
{
|
|
return m_fDeltaY;
|
|
}
|
|
|
|
void EventHandler::processEvents()
|
|
{
|
|
// Handle events
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event))
|
|
{
|
|
switch (event.type)
|
|
{
|
|
case SDL_QUIT:
|
|
std::terminate();
|
|
break;
|
|
|
|
case SDL_WINDOWEVENT:
|
|
{
|
|
if (event.window.windowID == mWindowID
|
|
&& event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
|
{
|
|
int width = event.window.data1, height = event.window.data2;
|
|
windowResizeEvent(width, height);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SDL_MOUSEWHEEL:
|
|
{
|
|
// SDL_MOUSEWHEEL regression?
|
|
// m->y no longer reliable (often y is 0 when mouse wheel is spun up or down), use m->preciseY instead
|
|
SDL_MouseWheelEvent *m = (SDL_MouseWheelEvent*)&event;
|
|
#ifdef EVENTS_DEBUG
|
|
printf ("SDL_MOUSEWHEEL= x,y=%d,%d preciseX,preciseY=%f,%f\n", m->x, m->y, m->preciseX, m->preciseY);
|
|
#endif
|
|
bool mouseWheelDown = (m->preciseY < 0.0);
|
|
|
|
if(m_InteractionMode&InteractionMode::MODE_SCROLL)
|
|
{
|
|
zoomEventMouse(mouseWheelDown, mMousePositionX, mMousePositionY);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SDL_MOUSEMOTION:
|
|
{
|
|
SDL_MouseMotionEvent *m = (SDL_MouseMotionEvent*)&event;
|
|
mMousePositionX = m->x;
|
|
mMousePositionY = m->y;
|
|
if (mMouseButtonDown && !mFingerDown && !mPinch)
|
|
panEventMouse(mMousePositionX, mMousePositionY);
|
|
break;
|
|
}
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
{
|
|
SDL_MouseButtonEvent *m = (SDL_MouseButtonEvent*)&event;
|
|
if (m->button == SDL_BUTTON_LEFT && !mFingerDown && !mPinch)
|
|
{
|
|
mMouseButtonDown = true;
|
|
mMouseButtonDownX = m->x;
|
|
mMouseButtonDownY = m->y;
|
|
mCamera.setBasePan();
|
|
}
|
|
|
|
if (m->button == SDL_BUTTON_RIGHT && !mFingerDown && !mPinch)
|
|
{
|
|
printf("C++: 오른쪽 마우스 버튼이 눌렸습니다! 좌표: x=%d, y=%d\n", m->x, m->y);
|
|
|
|
//mMouseButtonDown = true;
|
|
//mMouseButtonDownX = m->x;
|
|
//mMouseButtonDownY = m->y;
|
|
//mCamera.setBasePan();
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
{
|
|
SDL_MouseButtonEvent *m = (SDL_MouseButtonEvent*)&event;
|
|
if (m->button == SDL_BUTTON_LEFT)
|
|
{
|
|
mMouseButtonDown = false;
|
|
|
|
m_nEventType = 3;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SDL_FINGERMOTION:
|
|
if (mFingerDown)
|
|
{
|
|
SDL_TouchFingerEvent *m = (SDL_TouchFingerEvent*)&event;
|
|
|
|
// Finger down and finger moving must match
|
|
if (m->fingerId == mFingerDownId)
|
|
panEventFinger(m->x, m->y);
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
break;
|
|
|
|
case SDL_FINGERDOWN:
|
|
if (!mPinch)
|
|
{
|
|
// Finger already down means multiple fingers, which is handled by multigesture event
|
|
if (mFingerDown)
|
|
mFingerDown = false;
|
|
else
|
|
{
|
|
SDL_TouchFingerEvent *m = (SDL_TouchFingerEvent*)&event;
|
|
|
|
mFingerDown = true;
|
|
mFingerDownX = m->x;
|
|
mFingerDownY = m->y;
|
|
mFingerDownId = m->fingerId;
|
|
mCamera.setBasePan();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SDL_MULTIGESTURE:
|
|
{
|
|
SDL_MultiGestureEvent *m = (SDL_MultiGestureEvent*)&event;
|
|
if (m->numFingers == 2 && fabs(m->dDist) >= cPinchZoomThreshold)
|
|
{
|
|
mPinch = true;
|
|
mFingerDown = false;
|
|
mMouseButtonDown = false;
|
|
|
|
if(m_InteractionMode&InteractionMode::MODE_SCROLL)
|
|
{
|
|
zoomEventPinch(m->dDist, m->x, m->y);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case SDL_FINGERUP:
|
|
m_nEventType = 4;
|
|
mFingerDown = false;
|
|
mPinch = false;
|
|
break;
|
|
}
|
|
|
|
#ifdef EVENTS_DEBUG
|
|
printf ("event=%d mousePos=%d,%d mouseButtonDown=%d fingerDown=%d pinch=%d aspect=%f window=%dx%d\n",
|
|
event.type, mMousePositionX, mMousePositionY, mMouseButtonDown, mFingerDown, mPinch, mCamera.aspect(), mCamera.windowSize().width, mCamera.windowSize().height);
|
|
printf (" zoom=%f pan=%f,%f\n", mCamera.zoom(), mCamera.pan()[0], mCamera.pan()[1]);
|
|
#endif
|
|
}
|
|
}
|