You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/Module/GeoSigmaDraw/QTransformTracker.h

287 lines
10 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;