|
|
#pragma once
|
|
|
#include "QTracker.h"
|
|
|
#include <gdiplus.h>
|
|
|
|
|
|
// =======================
|
|
|
// QTransformTracker
|
|
|
//
|
|
|
// This class allows a rectangle or a GDI+ GraphicsPath to be moved and transformed
|
|
|
// in different fashions.
|
|
|
// It is more or less like MFC's CRectTracker, but has far more options.
|
|
|
// QTransformTracker is derived from QTracker (see: QTracker.h).
|
|
|
//
|
|
|
// If an object (rectangle or path) is loaded in QTransformTracker, it is surrounded
|
|
|
// by eight handles. Another handle is at the center point.
|
|
|
//
|
|
|
// QTransformTracker has the following modes of operation.
|
|
|
// - move drag the object at the body. If Shift is pressed, moving is restricted
|
|
|
// to horizontal, vertical or diagonal;
|
|
|
// - scale drag one of the eight handles. If Shift is pressed, the proportion of
|
|
|
// the object is preserved;
|
|
|
// - rotate press Ctrl, and drag one of the corner handles. If Shift is pressed,
|
|
|
// the rotation angle is restricted to a multiple of 15 degrees;
|
|
|
// - shear press Ctrl, and drag one of the edge handles. If Shift is not pressed,
|
|
|
// you can scale in the other direction;
|
|
|
//
|
|
|
// In general, all transformations are with respect to the opposite handle. If Alt is
|
|
|
// pressed, the transformations are with respect to the Center Point.
|
|
|
//
|
|
|
// If the space bar is pressed, all transformations revert to move.
|
|
|
//
|
|
|
// The Center Point can be moved by dragging it. If Shift is pressed, moving is restricted
|
|
|
// to horizontal, vertical or diagonal.
|
|
|
//
|
|
|
// The transformation is accumulated in a GDI+ Matrix. After tracking, it can be retrieved
|
|
|
// with the GetTransform() member function.
|
|
|
//
|
|
|
// During tracking, member function GetIndicatorString() gives textual information about
|
|
|
// the current operation. This may be presented on the status bar or used for other forms
|
|
|
// of user feedback.
|
|
|
//
|
|
|
// Usage:
|
|
|
// - load QTransformTracker with one of the Load() member functions;
|
|
|
// - at mouse down, call the base member function Track() (see: QTracker.h);
|
|
|
// - if Track() returns with a positive value, retrieve the transformation matrix
|
|
|
// with GetTransform().
|
|
|
//
|
|
|
// Note: QTransformTracker is incompatible with W95 or W98.
|
|
|
//===============================
|
|
|
// Version 1.0, August 20, 2003
|
|
|
// (c) Sjaak Priester, Amsterdam
|
|
|
// www.sjaakpriester.nl
|
|
|
//
|
|
|
// Freeware. Use at your own risk. Comments welcome.
|
|
|
namespace NItem
|
|
|
{
|
|
|
|
|
|
class QTransformTracker :
|
|
|
public QTracker
|
|
|
{
|
|
|
public:
|
|
|
class CPathItem
|
|
|
{
|
|
|
public:
|
|
|
CPathItem();
|
|
|
virtual ~CPathItem();
|
|
|
|
|
|
Gdiplus::Status TransformPoints(Gdiplus::Matrix& transform);
|
|
|
void GeneratePoints();
|
|
|
Status TransformPointsOnly(Gdiplus::Matrix& transform);
|
|
|
BOOL Load(Gdiplus::GraphicsPath& path, BOOL needRect = FALSE);
|
|
|
void OnDrawFull(CDC* pDC);
|
|
|
void OnUpdate(CDC* pDC, UINT nMode);
|
|
|
void Clear(void);
|
|
|
BOOL IsVisiblePath(const CPoint& point);
|
|
|
|
|
|
Gdiplus::GraphicsPath *m_pGraphicsPath;
|
|
|
Gdiplus::GraphicsPath * m_pDrawPath;
|
|
|
LPPOINT m_pPathPoints;
|
|
|
LPBYTE m_pPathTypes;
|
|
|
CRect m_rect;
|
|
|
BOOL m_needRect;
|
|
|
};
|
|
|
|
|
|
// Construction
|
|
|
QTransformTracker(); // to SetParent(CWnd* pWnd)
|
|
|
QTransformTracker(CWnd * pWnd); // pWnd points to the associated window
|
|
|
virtual ~QTransformTracker();
|
|
|
|
|
|
virtual void SetParent(CWnd* pWnd);
|
|
|
|
|
|
// Loading
|
|
|
void AddPath(Gdiplus::GraphicsPath& path, BOOL bNeedRect);
|
|
|
void Load(Gdiplus::GraphicsPath& path, bool bSetCenter = true, CDC * pDC = NULL);
|
|
|
void Load(CRect& rc, bool bSetCenter = true, CDC * pDC = NULL);
|
|
|
void Load(Gdiplus::Rect& rect, bool bSetCenter = true, CDC * pDC = NULL);
|
|
|
// Loads QTransformTracker with a GraphicsPath or a rectangle.
|
|
|
// After loading, transforming can be performed.
|
|
|
//
|
|
|
// If bSetCenter == true, the Center Point is set to the center point of the rectangle,
|
|
|
// or to the center point of the bounding rectangle of path.
|
|
|
// If bSetCenter == false, the Center Point is unchanged.
|
|
|
//
|
|
|
// If pDC is not NULL, pDC is updated.
|
|
|
|
|
|
void Clear(CDC * pDC = NULL);
|
|
|
// Clears any GraphicsPath or rectangle.
|
|
|
// After clearing, no transformation can be performed.
|
|
|
//
|
|
|
// If pDC is not NULL, pDC is updated.
|
|
|
|
|
|
bool IsLoaded(void) const { return m_bLoaded; }
|
|
|
|
|
|
virtual void Draw(CDC * pDC);
|
|
|
// Draws the Marker Rectangle, the static appearance of QTransformTracker.
|
|
|
// Drawing is done in NOT-XOR mode, meaning that a second call to Draw will
|
|
|
// erase the results of the first call.
|
|
|
// Typically, you should only call Draw() from the application's OnDraw-handler.
|
|
|
|
|
|
Gdiplus::Matrix * GetTransform(void) const { return m_Transform.Clone(); }
|
|
|
// Get the result of the tracking operation as a GDI+ transformation matrix.
|
|
|
// The return value is a clone; user should delete it.
|
|
|
|
|
|
BOOL OnSetCursor(CDC * pDC);
|
|
|
int OnSetCursor(CDC * pDC,CPoint pt);
|
|
|
// Should be called by the OnSetCursor-handler of the associated window.
|
|
|
// If QTransformTracker is loaded, it sets the cursor to indicate the mode of transform.
|
|
|
// You may also call this at an OnKeyUp/Down-handler for the Ctrl-key and space bar.
|
|
|
//
|
|
|
// Parameter:
|
|
|
// pDC pointer to (prepared) DC of associated window.
|
|
|
//
|
|
|
// Return:
|
|
|
// TRUE if OnSetCursor did set the cursor, FALSE otherwise.
|
|
|
|
|
|
LPCTSTR GetIndicatorString() const { return m_IndicatorString; }
|
|
|
|
|
|
// Options and appearance
|
|
|
UINT m_Options;
|
|
|
// The following options can be set by setting this variable to
|
|
|
// a combination of the following flags:
|
|
|
// - OptionRotate allows rotation (default);
|
|
|
// - OptionShear allows shearing (default);
|
|
|
// - OptionAllowMirror allows mirroring of object by scaling (default);
|
|
|
// - OptionCenter displays center point, allows Alt-functionality (default);
|
|
|
// - OptionCenterMove make the center point moveable by dragging (default);
|
|
|
// - OptionRotateReverseAlt reverses the function of the Alt key at rotation (default);
|
|
|
// - OptionMarkDotted draw the Mark Rectangle with a dotted line;
|
|
|
// - OptionTrackDotted draw the Track Rectangle with a dotted line (default);
|
|
|
// - OptionPathDotted draw the GraphicsPath with a dotted line.
|
|
|
// Note that the combination of OptionCenter == false and OptionCenterMove == true
|
|
|
// leads to undefined behaviour.
|
|
|
|
|
|
void SetCrossLineState(BOOL bView=TRUE);
|
|
|
void SetCrossLineColor(COLORREF color);
|
|
|
|
|
|
void SetMetrics(UINT handleSize, UINT innerMargin, UINT outerMargin, CDC * pDC = NULL);
|
|
|
void GetMetrics(UINT& handleSize, UINT& innerMargin, UINT& outerMargin) const;
|
|
|
// Set/Get some metrics in logical coordinates.
|
|
|
// handleSize size of handles on corners, edges and center. Default 4.
|
|
|
// innerMargin margin between loaded rectangle and Marker Rectangle. Default 4.
|
|
|
// outerMargin margin between Marker Rectangle and tracking rectangle. Default 2.
|
|
|
// If pDC is not NULL, pDC is updated.
|
|
|
|
|
|
COLORREF m_colorMark; // color of Marking Rectangle. Default: light gray.
|
|
|
COLORREF m_colorHandles; // color of handles on corners and edges. Default: black.
|
|
|
COLORREF m_colorCenter; // color of center. Default: black.
|
|
|
COLORREF m_colorTrack; // color of Tracking Rectangle. Default: black.
|
|
|
COLORREF m_colorPath; // color of tracking path. Default: black.
|
|
|
COLORREF m_colorCrossLine; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
|
|
// Some colors. Change these if you like.
|
|
|
|
|
|
enum CursorType
|
|
|
{
|
|
|
CursorNWSE, //0
|
|
|
CursorNESW, //1
|
|
|
CursorNS, //2
|
|
|
CursorWE, //3
|
|
|
CursorCenter, //4
|
|
|
CursorMove, //5
|
|
|
CursorCopy, //6
|
|
|
CursorRotate, //7
|
|
|
CursorShearHor, //8
|
|
|
CursorShearVert //9
|
|
|
};
|
|
|
static HCURSOR g_hCursor[10];
|
|
|
|
|
|
static bool LoadCursor(int type, UINT nResourceID, HINSTANCE hInst = NULL);
|
|
|
// Load one of the cursors QTransformTracker will display.
|
|
|
//
|
|
|
// Parameters:
|
|
|
// type one of the values of CursorType;
|
|
|
// nResourceID resource identifier of the cursor;
|
|
|
// hInst the module in which the cursor resides. If NULL, the cursor is
|
|
|
// taken from the apllication's resource.
|
|
|
//
|
|
|
// Return value: true if succeeded.
|
|
|
// QTransformTracker defaults to some MFC cursors.
|
|
|
protected:
|
|
|
BOOL m_bCopyObject;
|
|
|
BOOL m_bOnlyMove;
|
|
|
|
|
|
public:
|
|
|
|
|
|
bool SetTrackModeOnClick(UINT nFlags, CPoint point);
|
|
|
// Overrides from QTracker (see QTracker.h)
|
|
|
virtual int OnBeginTrack(UINT nFlags, CPoint point);
|
|
|
virtual int OnEndTrack(int trackResult);
|
|
|
virtual int OnMouseMessage(UINT msg, UINT nFlags, CPoint point);
|
|
|
virtual int OnKeyMessage(UINT msg, UINT nChar, UINT nRepCnt, UINT nFlags);
|
|
|
virtual void DrawFull(CDC* pDC, UINT nMode);
|
|
|
virtual void OnUpdate(CDC * pDC, UINT nMode);
|
|
|
virtual void DrawPath(CDC * pDC);
|
|
|
|
|
|
// Overridable in derived classes
|
|
|
virtual void SetIndicatorString(Mode mode, CPoint point, Gdiplus::REAL x, Gdiplus::REAL y = 0.0f);
|
|
|
// Override this function to adapt the indicator string.
|
|
|
|
|
|
// Implementation
|
|
|
void DrawMarkRect(CDC * pDC);
|
|
|
void DrawMarkRect(CDC* pDC, CRect rect, BOOL bNoEditMark);
|
|
|
void DrawCenter(CDC * pDC, POINT center, bool bTrack);
|
|
|
void DrawMarkRotate(CDC* pDC, CRect rect);
|
|
|
void DrawCenterRotate(CDC * pDC, POINT center, bool bTrack);
|
|
|
void DrawCrossLine(CDC* pDC,CPoint point);
|
|
|
CPoint GetHandlePoint(LPPOINT pPoints, int iHandle);
|
|
|
CRect GetHandleRect(int iHandle);
|
|
|
CRect GetHandleRect(LPPOINT pPoint,int iHandle);
|
|
|
BOOL SetCursor(int iHandle);
|
|
|
void SetPoints(bool bSetCenter);
|
|
|
void SetFixedPoints(bool bAlt);
|
|
|
CPoint RestrictPoint(CPoint point, CPoint pntBase);
|
|
|
void LoadDefaultCursors(void);
|
|
|
void InitParameter(void);
|
|
|
|
|
|
bool m_bLoaded;
|
|
|
bool m_bSpace;
|
|
|
bool m_bMapFlip;
|
|
|
bool m_bAlt;
|
|
|
|
|
|
Mode m_Mode;
|
|
|
//int m_Handle;
|
|
|
CRect m_StartRect;
|
|
|
CArray<CPathItem*,CPathItem*> m_ArrayPath;
|
|
|
|
|
|
POINT m_PointSrc[5]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5>ĸ<EFBFBD><C4B8>ǵ<EFBFBD><C7B5><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>
|
|
|
POINT m_PointDest[5]; //<2F>任<EFBFBD><E4BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>5<EFBFBD><35><EFBFBD><EFBFBD>
|
|
|
POINT m_PointTemp[5];
|
|
|
|
|
|
CPoint m_FixedSrc;
|
|
|
CPoint m_FixedDest;
|
|
|
|
|
|
Gdiplus::Matrix m_Transform;
|
|
|
Gdiplus::REAL m_StartPhi;
|
|
|
|
|
|
UINT m_HandleSize;
|
|
|
UINT m_InnerMargin;
|
|
|
UINT m_OuterMargin;
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD><DFB2><EFBFBD>
|
|
|
BOOL m_bCrossLine;
|
|
|
|
|
|
CString m_IndicatorString;
|
|
|
|
|
|
public:
|
|
|
CRect GetHandleRect(LPPOINT pPoint);
|
|
|
CSize GetHandleSize(void);
|
|
|
int NormalizeHit(int handle);
|
|
|
int HitTest(CPoint point);
|
|
|
bool IsLineForOutRect(CPoint point);
|
|
|
BOOL IsCopy(void);
|
|
|
void SetOnlyMove(BOOL bOnlyMove);
|
|
|
BOOL IsEmptyPath(void);
|
|
|
BOOL IsVisiblePath(CPoint point);
|
|
|
CRect GetInvalidateRect(void);
|
|
|
void GetPoint(LPCRECT pRect, POINT* pt, BOOL bOuterMargin);
|
|
|
|
|
|
BOOL CanDrawCenter = TRUE;
|
|
|
|
|
|
private:
|
|
|
// <20><><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD>ѡ<EFBFBD><D1A1>ͼԪ<CDBC><D4AA>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǽ<EFBFBD>¼ AddPath ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD> m_ArrayPath <20><><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD>ܷ<EFBFBD>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD>ζ<EFBFBD> AddPath ʱ<><CAB1><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>
|
|
|
CRect m_totalRect;
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
using namespace NItem;
|