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.
nmWATI/Include/iPlot/iPlotBase/ZxRenderView.h

557 lines
16 KiB
C

#pragma once
#include <QAbstractScrollArea>
#include <QVector>
#include <QPoint>
#include <QPixmap>
#include "ZxRenderItem.h"
#include "ZxSceneItem.h"
#include "ZxRenderItemIterator.h"
#include "IxRedoUndo.h"
#include "iPlotBase_global.h"
class QActionGroup;
class QUndoCommand;
class ZxToolState;
class ZxTool;
class QMenu;
class QComboBox;
class QPixmap;
class QPushButton;
class QPrinter;
class ZxSelectionOutline
{
public:
QPixmap pixmap;
int xc;
int yc;
};
// 图形视图(图元显示和操作)
class I_PLOTBASE_EXPORT ZxRenderView
: public QAbstractScrollArea
, virtual public IxDynObj
, virtual public IxRedoUndo
{
Q_OBJECT
ZX_DECLARE_DYNAMIC
public:
ZxRenderView(QWidget* parent = 0);
virtual ~ZxRenderView();
enum ZoomMode
{
eZoomFree,
eZoomFitWidth,
eZoomFitHeight,
eZoomFitWindow
};
public:
// 强制显示隐藏滚动条
void forceShowScrollBar(bool bHori, bool bVisible);
// 获取图元树迭代器
ZxRenderItemIterator getRenderTree() const;
// 堆栈相关
virtual QUndoStack* getUndoStack();
virtual void pushCommand(QUndoCommand* cmd);
// 场景
virtual void setScene(ZxSceneItem* p, bool bOwnScene = false);
virtual ZxSceneItem* getScene() const;
// 获取当前工具正在操作视图
static ZxRenderView* getCurrentToolView();
// 获取(建议的)控制点尺寸
double getHandleSize(); // mm
// 获取(建议的)控制点尺寸, 并转到文档坐标(随着缩放率变化)
double getHandleSizeSceneCoord(); // mm
// 快照模式开关,快照模式下重绘速度快, 但只在显示区域发生变化时才刷新快照.
virtual void setSnapshotMode(bool b);
virtual bool isSnapshotMode() const;
QPixmap getSnapshot(); //获取快照
virtual void repaintSnapshot();//立即刷新快照, 在非快照模式下无效果.
virtual void updateSnapshot();//刷新快照, 但不是立即刷新, 在非快照模式下无效果.
// 是否显示纸张页面及边框
void setPaperMode(bool b);
public:
// 准备右键菜单
virtual void onPrepareContextMenu(QMenu* pMenu, const QPointF& pos);
// 获取选择区域的轮廓(实际上可能是详图, 不一定就是线框轮廓)
virtual ZxSelectionOutline getSelectionOutline(int nMouseX, int nMouseY, \
const QColor overlapColor = QColor(0, 127, 255, 63), \
ZxFilterFun filter = 0);
// 从本视图坐标系转到文档坐标系
QPointF mapToScene(const QPointF& pos) const;
QRectF mapToScene(const QRectF& rect) const;
QSizeF mapToScene(const QSizeF & sz) const;
// 从文档坐标系转到本视图坐标系
QPointF mapFromScene(const QPointF& pos) const;
QRectF mapFromScene(const QRectF& rect) const;
QSizeF mapFromScene(const QSizeF & sz) const;
// 从本视图坐标系转到全局坐标系
QPointF mapToGlobal(const QPointF& pos) const;
QPoint mapToGlobal(const QPoint& pos) const;
// 从全局坐标系转到本视图坐标系
QPointF mapFromGlobal(const QPointF& pos) const;
QPoint mapFromGlobal(const QPoint& pos) const;
// 缩放模式
virtual void setZoomMode(ZoomMode mode, bool reLayout = true);
ZoomMode getZoomMode() const;
// 获取缩放倍数
double getZoomRatioX() const;
double getZoomRatioY() const;
double getZoomRatio() const;
// 获取缩放模式或百分比, 以便用来显示给用户.
QString getZoomString() const;
// 缩放到指定区域
virtual void zoomTo(const QRectF& rectSceneCoord);
// 把场景的某点对应到视图的某点
virtual void scrollScenePosToViewPos(const QPointF& ptScene, const QPointF& ptView);
// 把场景的某点显示到视图中心
virtual void scrollScenePosToViewCenter(const QPointF& ptScene);
// 把矩形变为和视图一样的长宽比例
virtual QRectF adjustRectFitViewAspect(const QRectF& rect);
// 获取屏幕DPI
static int getDpiX();
static int getDpiY();
// 获取屏幕每毫米的像素数
static double getPpmmX();
static double getPpmmY();
// 还原鼠标光标.
// 一般是箭头, 但也可能是其它, 所以不能用 setCursor(Qt::ArrowCursor);
virtual void restoreCursor();
signals:
// 信号: 有图元被移出图件树
void sigItemDetached(ZxRenderItem* pItem);
// 信号:双击
void sigLeftDoubleClick(const QPointF& pt);
// 信号:单击
void sigLeftClick(const QPointF& pt);
// 信号为了PF同步新增的信号
void sigZoomedX(double r, bool reLayout);
void sigZoomedY(double r, bool reLayout);
void sigMouseWheel(const QPointF& pt, int delta);
void sigZoomStrChanged(const QString& s, bool reLayout = true);
// 信号:缩放
void sigZoomedIn();
void sigZoomedOut();
void sigZoomedRaw();
public slots:
// 设置缩放倍数(例如2.5倍)
virtual void setZoomRatioX(double r, bool reLayout);
virtual void setZoomRatioY(double r, bool reLayout);
virtual void slotMouseWheel(const QPointF& pt, int delta);
// 设置缩放模式或百分比.
// @param s 输入"120"或"120%"均表示放大到1.2倍
// @param reLayout 是否立即重新布局
virtual void slotZoomStrChanged(const QString& s, bool reLayout);
// 放大/缩小/初始
virtual void zoomIn();
virtual void zoomOut();
virtual void zoomRaw();
virtual void zoomInOnly();
virtual void zoomOutOnly();
// 处理保存
virtual void slotSaveAsImg();
// 处理打印动作
virtual void slotPrint();
virtual void slotPrintPreview();
virtual void print(QPrinter *printer);
virtual void printPreview(QPrinter *printer);
// 相当于 viewport()->update(...)
virtual void updateViewport();
// 相当于 viewport()->update(...)
virtual void slotUpdateViewport(const QRect&);
// 相当于 viewport()->repaint(...)
virtual void repaintViewport();
private:
void notifyItemDetached(ZxRenderItem* pItem);
protected slots:
virtual void slotZoomEditingFinished();
virtual void slotZoomComboIndexChanged(const QString& text);
void slotTheOwnedSceneDestroyed(QObject* p);
public:
// 画背景及纸张
virtual void paintPaper(QPainter* painter);
// 画工具、Policy、控制点、辅助线等前景
// @note 打印和输出图片时不画这一层
virtual void paintOverlay(QPainter* painter);
// 画文档内容
virtual void paintScene(QPainter* painter, const ZxPaintParam& param);
// 用默认的ZxPaintParam来绘图
virtual void paintScene(QPainter* painter);
// 在指定画布上绘制图形(无前景和背景)
// deviceRect: 设备坐标范围,坐标单位为像素,如果为空,则表示按照图形实际大小输出
// expose: 文档坐标范围,如果为空表示输出完整图形
virtual void paint(QPainter* painter, QRect deviceRect = QRect(), QRectF expose = QRectF(), bool isPreview = false);
protected:
virtual void paintEvent(QPaintEvent *);
virtual void resizeEvent(QResizeEvent *);
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseMoveEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
virtual void mouseDoubleClickEvent(QMouseEvent *);
virtual void wheelEvent(QWheelEvent *);
virtual void keyPressEvent(QKeyEvent *);
virtual void keyReleaseEvent(QKeyEvent *);
virtual void customContextMenuRequested(const QPoint &pos);
virtual void enterEvent(QEvent *);
virtual void leaveEvent(QEvent *);
virtual void hideEvent(QHideEvent *);
virtual void focusInEvent(QFocusEvent *);
virtual void focusOutEvent(QFocusEvent *);
virtual void closeEvent(QCloseEvent *);
protected:
virtual QSizeF getViewportSizePixel() const;
// 见Qt文档, 滚动位置发生变化
virtual void scrollContentsBy ( int dx, int dy );
// 根据缩放模式计算出缩放率
virtual void calcZoomRatio();
// 计算转换矩阵
static void calcMatrix(QMatrix & m, double scaleX, double scaleY, double x0, double y0);
// 计算转换矩阵
void calcMatrix(QMatrix & m, double x0, double y0);
// 更新转换矩阵
virtual void calcMatrix();
private:
void _setZoomRatio(double f, bool reLayout, bool sync, bool bX);
// 以下函数在QWdiget里是非虚的, 不能重写.
// 但他们又很容易和viewport里的混淆, 所以设为private的, 避免误用
// 如果确实要用, 可使用限定符调用基类的: QAbstractScrollArea::update()
// (已封闭) use viewport()->update(...) instead.
void update();
// (已封闭) use viewport()->repaint(...) instead.
void repaint();
// (已封闭) use viewport()->update(...) instead.
void update(int x, int y, int w, int h);
// (已封闭) use viewport()->update(...) instead.
void update(const QRect&);
// (已封闭) use viewport()->update(...) instead.
void update(const QRegion&);
// (已封闭) use viewport()->repaint(...) instead.
void repaint(int x, int y, int w, int h);
// (已封闭) use viewport()->repaint(...) instead.
void repaint(const QRect &);
// (已封闭) use viewport()->repaint(...) instead.
void repaint(const QRegion &);
// (已封闭) use paint(...) instead
void render(QPaintDevice *target, const QPoint &targetOffset = QPoint(),
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
// (已封闭) use paint(...) instead
void render(QPainter* painter, const QPoint &targetOffset = QPoint(),
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
// 打印或者打印预览
virtual void print(QPrinter *printer, bool isPreview);
public:
// 相当于 viewport()->update(...)
virtual void updateViewport(int x, int y, int w, int h);
// 相当于 viewport()->update(...)
virtual void updateViewport(const QRect&);
// @see void updateViewport(const QRect&)
virtual void updateViewport(const QRectF&);
// 相当于 viewport()->update(...)
virtual void updateViewport(const QRegion&);
// 相当于 viewport()->repaint(...)
virtual void repaintViewport(int x, int y, int w, int h);
// 相当于 viewport()->repaint(...)
virtual void repaintViewport(const QRect &);
// 相当于 viewport()->repaint(...)
virtual void repaintViewport(const QRegion &);
// 文档发生改变
virtual void onDocUpdate(const QRectF * pSceneRect);
// 布局. 包括更新滚动条范围, 做页面布局, 计算矩阵等
virtual void layoutViewport(QRectF * pSceneBounds = 0);
// 获取窗口边距
virtual void getMargins(double * top, double * left, double * bottom, double * right) const;
// 设置窗口边距
virtual void setMargins(double top, double left, double bottom, double right);
// 获取文档坐标系下的窗口边距
virtual void getMarginsSceneCoord(double * top, double * left, double * bottom, double * right) const;
// 获取文档范围
virtual QRectF getSceneBounds() const;
// 获取加上缩进后的文档范围
virtual QRectF getSceneBoundsWithMargins() const;
// 获取当前缩放率下视口能显示的最大文档尺寸
virtual QSizeF getViewportSizeMillimeter() const;
// 获取当前可见的场景区域
virtual QRectF getViewportRectSceneCoord() const;
// 滚动位置
virtual QPointF getScrollPos() const;
virtual void setScrollPos(const QPointF& pos);
virtual void setScrollPos(double x, double y);
// 水平滚动位置
virtual void setHorizontalScrollPos(double pos);
virtual void setVerticalScrollPos(double pos);
// 设置缩放下拉栏是否可见
void setZoomComboVisible(bool b);
// 不变性检测
virtual void invariant() const;
// 对齐方式.
// 暂时只支持居中和不居中
virtual void setAlignment(Qt::Alignment alignment);
virtual Qt::Alignment getAlignment() const;
#ifdef _SCAN_OLD_CODE_
virtual void setSmartHorizontalScrollPos(bool b);
bool isSmartHorizontalScrollPos() const;
virtual void setSmartVerticalScrollPos(bool b);
bool isSmartVerticalScrollPos() const;
#endif
public:
// 获取视图中所有工具
QVector<ZxTool*> getTools() const;
// 活动工具
virtual ZxTool* getActiveTool() const;
virtual void setActiveTool(int index);
virtual void setActiveTool(ZxTool* p);
virtual void setActiveTool(const QString& sToolText);
// 默认工具
virtual ZxTool* getDefaultTool() const;
virtual void setDefaultTool(int index);
virtual void setDefaultTool(ZxTool* p);
// 把工具加到视图中.
// @ pTool 要添加的工具. 可以为0, 0将显示为分隔线.
// 注: 视图将负责销毁工具
int addTool(ZxTool* pTool);
// 获取指定action, 触发action可激活工具
QAction* getToolAction(int index) const;
QAction* getToolAction(ZxTool* p) const;
// 删除全部工具
virtual void clearTools();
// 活动视图
bool isActiveView() const;
bool activateView();
// 当前视图被激活/被取消激活
virtual void onActivated(QWidget* pOldActiveView);
virtual void onDeactivated(QWidget* pNewActiveView);
// 工具的状态和另一个视图同步(单次同步)
void syncActiveToolWith(const ZxRenderView* pOther);
// 从另一个视图中复制工具
void copyToolsFrom(const ZxRenderView* pOther);
protected:
// void onSerialize(ZxSerializer* ser);
// void onDeserialize(ZxSerializer* ser);
bool checkAndDoLayout();
virtual void onViewportParamChanged();
virtual void onSelectionChanged(ZxSelection& selection);
// 转换矩阵, 用作painter的 matrix
QMatrix getMatrixDocToView() const;
// 转换矩阵
QMatrix getMatrixViewToDoc() const;
virtual void onIdle();
public:
void setCursorKeeping(bool bKeeping);
private:
// scene
// |<----------------------------------------->|
// |==============================|<---------->|
// min page
void setHorizontalScrollInfo(double fMin, double fScene, double fView);
void setVerticalScrollInfo(double fMin, double fScene, double fView);
void prepareBackBuffer();
private slots:
void slotActivateTool();
private:
// 场景指针
ZxSceneItem* m_pScene;
// Action & Tool
QVector<QAction*> m_vecToolActions;
QVector<ZxTool*> m_vecTools;
QActionGroup* m_pToolActionGroup;
int m_nDefaultTool;
int m_nActiveTool;
// 用作painter的world matrix
QMatrix* m_pMatrixDocToView;
QMatrix* m_pMatrixViewToDoc;
static double m_fCachedPpmmX;
static double m_fCachedPpmmY;
// 工具的状态, 同时只有一个工具激活, 所以没必要每个工具都记一份
ZxToolState* m_pToolState;
// 缩放
QComboBox* m_pComboZoom;
ZoomMode m_nZoomMode;
double m_fZoomX;
double m_fZoomY;
double m_fMarginLeft;
double m_fMarginTop;
double m_fMarginRight;
double m_fMarginBottom;
double m_fScrollOriginX;
double m_fScrollOriginY;
QRectF m_rectLastBounds; // 用来检测是否需要重新布局
QSizeF m_sizeLastViewport;
QPixmap m_snapshot;
QPixmap m_backBuffer;
Qt::Alignment m_nAlignment;
bool m_bSnapshotMode;
bool m_bPaperMode;
bool m_bNeedRepaintSnapshot;
bool m_bInLayoutViewport;
#ifdef _SCAN_OLD_CODE_
bool m_bSmartHorizontalScrollPos : 1;
bool m_bSmartVerticalScrollPos : 1;
#endif
bool m_bOwnScene;
bool m_bPainting;
bool m_bHover;
bool m_bNoBackBuffer; // 不使用后台缓存 (此变量不影响Qt自带的防闪烁机制)
private:
// 临时变量
bool m_bKeepingCursor; //对于Polygon生成过程中不能恢复为箭头
bool m_bActive;//临时
friend class ZxTool;
friend class ZxSceneItem;
friend class ZxCompoundTool;
};