145 lines
4.4 KiB
C++
145 lines
4.4 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
// This class handles manipulation of drawing object (rectangle) as a reaction
|
|
// to multi touch gestures
|
|
//
|
|
// Initially, we define rectangle to be in the center of the client area. So whenever
|
|
// user resize window the rectangle is placed in the middle of client window with
|
|
// a width set to half of width of client window and height set to half of the heights of
|
|
// client window. Rectangle is placed in the center of the client area.
|
|
//
|
|
// By using the fingers the user can zoom in, zoom out, move or rotate the rectangle.
|
|
//
|
|
|
|
#include "CDrawingObject.h"
|
|
|
|
// Default constructor
|
|
CDrawingObject::CDrawingObject()
|
|
{
|
|
// main window application is responsible to invoke ResetObject function to initialize variables.
|
|
// It shoudl be done whenever main window gets WM_SIZE message.
|
|
}
|
|
|
|
// Destructor
|
|
CDrawingObject::~CDrawingObject()
|
|
{
|
|
}
|
|
|
|
// This function resets rectangle object information and it's called by main app
|
|
// whenever a user resizes client area
|
|
// in:
|
|
// cxClient - new width of client window
|
|
// cyClient - new heights size of client window
|
|
void CDrawingObject::ResetObject(const int cxClient, const int cyClient)
|
|
{
|
|
// Initial positon of center point is the middle point of client window
|
|
_ptCenter.x = cxClient/2;
|
|
_ptCenter.y = cyClient/2;
|
|
|
|
// Initial width and height are half a size of client window
|
|
_szRect.cx = cxClient/2;
|
|
_szRect.cy = cyClient/2;
|
|
|
|
// Initial scaling factor is 1.0 (no scaling)
|
|
_dScalingFactor = 1.0;
|
|
|
|
// Initial rotation angle is 0.0 (no rotation)
|
|
_dRotationAngle = 0.0;
|
|
}
|
|
|
|
// This function will be called by the main app whenever WM_PAINT message is
|
|
// received. It is responsible to redraw the rectangle. Here we calculate the
|
|
// positon of the rectangle corners.
|
|
// in:
|
|
// hdc - handle to device context
|
|
void CDrawingObject::Paint(HDC hdc)
|
|
{
|
|
// create new blue pen with a width 1
|
|
HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
|
|
|
|
// select new pen for drawing
|
|
HGDIOBJ hPenOld = SelectObject(hdc, hPen);
|
|
|
|
// first create a polyline that describes the rectangle scaled by the
|
|
// scaling factor
|
|
POINT ptRect[5];
|
|
|
|
// upper left cofner
|
|
ptRect[0].x = -(LONG)(_dScalingFactor * _szRect.cx/2);
|
|
ptRect[0].y = -(LONG)(_dScalingFactor * _szRect.cy/2);
|
|
|
|
// upper right corner
|
|
ptRect[1].x = -ptRect[0].x;
|
|
ptRect[1].y = ptRect[0].y;
|
|
|
|
// lower right corner
|
|
ptRect[2].x = ptRect[1].x;
|
|
ptRect[2].y = -ptRect[0].y;
|
|
|
|
// lower left corner
|
|
ptRect[3].x = ptRect[0].x;
|
|
ptRect[3].y = ptRect[2].y;
|
|
|
|
// upper left corner, we are closing the rectangle
|
|
ptRect[4] = ptRect[0];
|
|
|
|
// now we should rotate and translate the rectangle
|
|
double dCos = cos(_dRotationAngle);
|
|
double dSin = sin(_dRotationAngle);
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
LONG lDX = ptRect[i].x;
|
|
LONG lDY = ptRect[i].y;
|
|
|
|
// rotation
|
|
ptRect[i].x = (LONG)(lDX*dCos + lDY*dSin);
|
|
ptRect[i].y = (LONG)(lDY*dCos - lDX*dSin);
|
|
|
|
// translation
|
|
ptRect[i].x += _ptCenter.x;
|
|
ptRect[i].y += _ptCenter.y;
|
|
}
|
|
|
|
Polyline(hdc, ptRect,5);
|
|
|
|
// draw diagonals
|
|
MoveToEx(hdc, ptRect[0].x, ptRect[0].y, NULL);
|
|
LineTo(hdc, ptRect[2].x, ptRect[2].y);
|
|
MoveToEx(hdc, ptRect[1].x, ptRect[1].y, NULL);
|
|
LineTo(hdc, ptRect[3].x, ptRect[3].y);
|
|
|
|
// select old pen
|
|
SelectObject(hdc, hPenOld);
|
|
|
|
// destroy new pen
|
|
DeleteObject(hPen);
|
|
}
|
|
|
|
// This function is responsible for manipulation of the rectangle.
|
|
// It is called from CManipulationEventSink class.
|
|
// in:
|
|
// translationDeltaX - shift of the x-coordinate (1/100 of pixel units)
|
|
// translationDeltaY - shift of the y-coordinate (1/100 of pixel units)
|
|
// scaleDelta - scale factor (zoom in/out)
|
|
// rotationDelta - rotation angle in radians
|
|
void CDrawingObject::ApplyManipulationDelta(
|
|
const FLOAT translationDeltaX,
|
|
const FLOAT translationDeltaY,
|
|
const FLOAT scaleDelta,
|
|
const FLOAT rotationDelta)
|
|
{
|
|
_ptCenter.x += (LONG) (translationDeltaX / 100.0);
|
|
_ptCenter.y += (LONG) (translationDeltaY / 100.0);
|
|
|
|
_dScalingFactor *= scaleDelta;
|
|
|
|
_dRotationAngle -= rotationDelta; // we are substracting because Y-axis is down
|
|
}
|