|
|
#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();
|
|
|
|
|
|
// 获取(建议的)控制点尺寸
|
|
|
float getHandleSize(); // mm
|
|
|
|
|
|
// 获取(建议的)控制点尺寸, 并转到文档坐标(随着缩放率变化)
|
|
|
float 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;
|
|
|
|
|
|
// 获取缩放倍数
|
|
|
float getZoomRatioX() const;
|
|
|
float getZoomRatioY() const;
|
|
|
float 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 float getPpmmX();
|
|
|
static float getPpmmY();
|
|
|
|
|
|
// 还原鼠标光标.
|
|
|
// 一般是箭头, 但也可能是其它, 所以不能用 setCursor(Qt::ArrowCursor);
|
|
|
virtual void restoreCursor();
|
|
|
|
|
|
signals:
|
|
|
|
|
|
// 信号: 有图元被移出图件树
|
|
|
void sigItemDetached(ZxRenderItem* pItem);
|
|
|
|
|
|
// 信号:双击
|
|
|
void sigLeftDoubleClick(const QPointF& pt);
|
|
|
|
|
|
// 信号:为了PF同步新增的信号
|
|
|
void sigZoomedX(float r, bool reLayout);
|
|
|
void sigZoomedY(float 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(float r, bool reLayout);
|
|
|
virtual void setZoomRatioY(float 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, float scaleX, float scaleY, float x0, float y0);
|
|
|
|
|
|
// 计算转换矩阵
|
|
|
void calcMatrix(QMatrix & m, float x0, float y0);
|
|
|
|
|
|
// 更新转换矩阵
|
|
|
virtual void calcMatrix();
|
|
|
|
|
|
private:
|
|
|
|
|
|
void _setZoomRatio(float 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(float * top, float * left, float * bottom, float * right) const;
|
|
|
|
|
|
// 设置窗口边距
|
|
|
virtual void setMargins(float top, float left, float bottom, float right);
|
|
|
|
|
|
// 获取文档坐标系下的窗口边距
|
|
|
virtual void getMarginsSceneCoord(float * top, float * left, float * bottom, float * 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(float x, float y);
|
|
|
|
|
|
// 水平滚动位置
|
|
|
virtual void setHorizontalScrollPos(float pos);
|
|
|
virtual void setVerticalScrollPos(float 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(float fMin, float fScene, float fView);
|
|
|
void setVerticalScrollInfo(float fMin, float fScene, float 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 float m_fCachedPpmmX;
|
|
|
static float m_fCachedPpmmY;
|
|
|
|
|
|
// 工具的状态, 同时只有一个工具激活, 所以没必要每个工具都记一份
|
|
|
ZxToolState* m_pToolState;
|
|
|
|
|
|
// 缩放
|
|
|
QComboBox* m_pComboZoom;
|
|
|
ZoomMode m_nZoomMode;
|
|
|
float m_fZoomX;
|
|
|
float m_fZoomY;
|
|
|
|
|
|
float m_fMarginLeft;
|
|
|
float m_fMarginTop;
|
|
|
float m_fMarginRight;
|
|
|
float m_fMarginBottom;
|
|
|
float m_fScrollOriginX;
|
|
|
float 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;
|
|
|
};
|