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.
750 lines
23 KiB
C++
750 lines
23 KiB
C++
#pragma once
|
|
|
|
#include <QVector>
|
|
#include <QList>
|
|
#include <QCursor>
|
|
#include <QObject>
|
|
#include <QRectF>
|
|
#include <QPen>
|
|
#include <QBrush>
|
|
|
|
#include <IxPtySource.h>
|
|
#include <IxRenderItem.h>
|
|
|
|
#include "ZxPaintParam.h"
|
|
#include "ZxRenderItemIterator.h"
|
|
#include "ZxHandleRef.h"
|
|
|
|
#include "iPlotBase_global.h"
|
|
|
|
class ZxRenderView;
|
|
class ZxSceneItem;
|
|
class ZxPaintParam;
|
|
//class QPainter;
|
|
class _ZxRenderChildIndex;
|
|
class ZxHandlePolicy;
|
|
class ZxEdit;
|
|
class ZxRenderItem;
|
|
class QSizeF;
|
|
class QPointF;
|
|
class ZxLayout;
|
|
class QFile;
|
|
class QDataStream;
|
|
class QAction;
|
|
class IxPtyItem;
|
|
class QMimeData;
|
|
|
|
class ZxSceneItem;
|
|
class QMenu;
|
|
class ZxTool;
|
|
|
|
/// 图元的根类
|
|
class I_PLOTBASE_EXPORT ZxRenderItem
|
|
: public QObject
|
|
, virtual public IxRenderItem
|
|
, virtual public IxPtySource
|
|
{
|
|
Q_OBJECT
|
|
ZX_DECLARE_DYNAMIC
|
|
|
|
public:
|
|
|
|
ZxRenderItem();
|
|
virtual ~ZxRenderItem();
|
|
|
|
void init();
|
|
|
|
virtual void onSerialize(ZxSerializer* ser);
|
|
virtual void onDeserialize(ZxSerializer* ser);
|
|
|
|
virtual void onLoadTempl(ZxSerializer* ser);
|
|
virtual void onSaveTempl(ZxSerializer* ser);
|
|
|
|
// 这是从外界调用的统一封装,模板
|
|
// bLoad 加载 or 保存
|
|
// bSelf 是否仅仅某类名称的,比如 TheorySource
|
|
void dealwithTempl(bool bLoad, bool bSelf);
|
|
virtual QString getTemplPath(bool bSelf);
|
|
|
|
bool loadTempl(QString s = ""); //模板的处理
|
|
bool saveTempl(QString s);
|
|
|
|
/// 指定父节点, 并加自动入父节点的子图元列表中
|
|
virtual void setParent(IxRenderItem* pParent);
|
|
|
|
/// 重新实现 QObject::setParent()
|
|
virtual void setParentObject(QObject* pParent);
|
|
|
|
/// 获取父节点的指针. 对于根结点, 这个函数返回NULL.
|
|
ZxRenderItem* getParent() const;
|
|
|
|
/// 获取根结点
|
|
ZxRenderItem* getRootItem() const;
|
|
|
|
/// 获取所在的场景
|
|
ZxSceneItem* getScene() const;
|
|
|
|
/// 获取当前工具
|
|
ZxTool* getCurrentTool() const;
|
|
|
|
/// 获取当前视图
|
|
ZxRenderView* getCurrentToolView() const;
|
|
|
|
/// 获取图元的显示名
|
|
virtual QString getTitle() const;
|
|
|
|
/// 获取图元的图标
|
|
virtual QIcon getIcon() const;
|
|
|
|
/// 递归绘图, 含自身和子图元
|
|
virtual void paint(QPainter* painter, const ZxPaintParam& param);
|
|
|
|
/// 绘制背景(位于子图元下方), 如无特殊情况, 普通内容应在此绘制
|
|
virtual void paintBack(QPainter* painter, const ZxPaintParam& param);
|
|
|
|
/// 绘制前景(位于子图元上方)
|
|
virtual void paintFront(QPainter* painter, const ZxPaintParam& param);
|
|
|
|
/// 画子图元(一般不需要重写)
|
|
virtual void paintChildren(QPainter* painter, const ZxPaintParam& param);
|
|
|
|
/// 绘制Edit和Policy
|
|
/// @note 此方法是独立的, 和绘制图元完全是不同的系统
|
|
virtual void paintEdit(QPainter* painter, const ZxPaintParam& param);
|
|
|
|
/// 获取子图元列表
|
|
const QVector<ZxRenderItem*>& getChildren() const;
|
|
|
|
/// 子图元数量, 等同于 size()
|
|
int count() const;
|
|
|
|
/// 子图元数量, 等同于 count()
|
|
int size() const;
|
|
|
|
/// 子图元数量是否为0, 等同于 empty()
|
|
bool isEmpty() const;
|
|
|
|
/// 子图元数量是否为0, 等同于 isEmpty()
|
|
bool empty() const;
|
|
|
|
/// 在指定位置插入子图元, 并自动把子图元的parent指向当前图元.
|
|
/// index 为 0 时插到前面, index为-1或等于size()时追加到最后.
|
|
void insert(int index, ZxRenderItem* pItem);
|
|
|
|
/// 替换子图元.
|
|
/// @param index 替换的位置
|
|
/// @param pItem 用来替换旧图元的新图元
|
|
/// @param bDelete 是否删除旧图元
|
|
/// @return bDelete为FALSE时返回旧图元, 否则返回NULL
|
|
ZxRenderItem* replace(int index, ZxRenderItem* pItem, bool bDelete);
|
|
|
|
/// 追加子图元
|
|
void append(ZxRenderItem* p);
|
|
|
|
/// 移除指定的子图元(不销毁)
|
|
void remove(ZxRenderItem* p);
|
|
|
|
/// 返回指定位置的子图元
|
|
ZxRenderItem* at(int i) const;
|
|
|
|
/// 返回指定子图元的位置索引, 如果没找到则返回-1. 对于空指针, 此方法总是返回-1.
|
|
int indexOf(const ZxRenderItem* p) const;
|
|
|
|
/// 从图元树上移除
|
|
ZxRenderItem* detach();
|
|
|
|
/// 删除所有子节点
|
|
virtual void clear();
|
|
|
|
// 在手动操作时, 判断此图元是否能容纳指定的子图元.
|
|
// 例如在曲线道里, 就可以对曲线以外的类型返回false.
|
|
//virtual bool canManualAdd(const ZxRenderItem* p) const;
|
|
|
|
/// 获取图元基础边框(位置)
|
|
virtual QRectF getBounds() const;
|
|
|
|
/// 获取图元的扩展边框. 默认是基础边框+外檐
|
|
QRectF getExtendedBounds() const;
|
|
|
|
/// 获取图元的外檐尺寸
|
|
virtual float getEavesSize() const;
|
|
|
|
/// 获取子图元坐标系下的边框(位置), 类似于Windows的Client Rect
|
|
QRectF getBoundsChildCoord() const;
|
|
|
|
/// 获取场景坐标系下的图元基础边框(位置)
|
|
QRectF getBoundsSceneCoord() const;
|
|
|
|
/// 获取场景坐标系下的图元扩展边框(位置)
|
|
QRectF getExtendedBoundsSceneCoord() const;
|
|
|
|
/// 获取图元x坐标, short for getX()
|
|
float x() const;
|
|
|
|
/// 获取图元y坐标, short for getY()
|
|
float y() const;
|
|
|
|
/// 获取图元左上角坐标, short for getPos()
|
|
QPointF pos() const;
|
|
|
|
/// 获取图元宽度, short for getWidth()
|
|
float width() const;
|
|
|
|
/// 获取图元高度, short for getHeight()
|
|
float height() const;
|
|
|
|
/// 获取图元x坐标
|
|
float getX() const;
|
|
|
|
/// 获取图元y坐标
|
|
float getY() const;
|
|
|
|
/// 获取图元左上角坐标
|
|
QPointF getPos() const;
|
|
|
|
/// 获取图元宽度
|
|
float getWidth() const;
|
|
|
|
/// 获取图元高度
|
|
float getHeight() const;
|
|
|
|
/// 设置图元边框
|
|
/// @param rect 边框
|
|
/// @param bSendEvent 是否发出 resize 和 move 事件, 默认为true.
|
|
/// @see onMove onResize
|
|
/// @note 普通情况都应该发事件, 但有一类逻辑问题可以用不发事件来解决, 见代码:
|
|
/// @code
|
|
/// void ZxPolyItem::setPoints(const QPolygonF & val)
|
|
/// {
|
|
/// m_points = val;
|
|
/// setBounds(m_points.boundingRect(), false);
|
|
/// }
|
|
///
|
|
/// void ZxPolyItem::onMove(const QPointF& ptOld, const QPointF& ptNew)
|
|
/// {
|
|
/// m_points.translate(ptNew - ptOld);
|
|
/// }
|
|
/// @endcode
|
|
virtual void setBounds(const QRectF& rect, bool bSendEvent = true);
|
|
|
|
/// 设置图元边框
|
|
/// @see setBounds(const QRectF &, bool)
|
|
virtual void setBounds(float x, float y, float width, float height, bool bSendEvent = true);
|
|
|
|
/// 移动图元
|
|
/// @param x X坐标
|
|
/// @param y Y坐标
|
|
/// @note 此方法会发出move事件, 如果不想发出事件, 请用 setBounds 方法
|
|
/// @see onMove
|
|
void move(float x, float y);
|
|
|
|
/// 移动图元
|
|
/// @param pos 坐标
|
|
/// @note 此方法会发出move事件, 如果不想发出事件, 请用 setBounds 方法
|
|
/// @see onMove
|
|
void move(const QPointF& pos);
|
|
|
|
/// 改变图元尺寸
|
|
/// @param width 宽度
|
|
/// @param height 高度
|
|
/// @note 此方法会发出resize事件, 如果不想发出事件, 请用 setBounds 方法.
|
|
/// @see onResize
|
|
void resize(float width, float height);
|
|
|
|
/// 改变图元尺寸
|
|
/// @param sz 尺寸
|
|
/// @note 此方法会发出resize事件, 如果不想发出事件, 请用 setBounds 方法.
|
|
/// @see onResize
|
|
void resize(const QSizeF & sz);
|
|
|
|
|
|
/// 移动图元
|
|
/// @param x X坐标
|
|
/// @note 此方法会发出move事件, 如果不想发出事件, 请用 setBounds 方法
|
|
/// @see onMove
|
|
void setX(float x);
|
|
|
|
/// 移动图元
|
|
/// @param y Y坐标
|
|
/// @note 此方法会发出move事件, 如果不想发出事件, 请用 setBounds 方法
|
|
/// @see onMove
|
|
void setY(float y);
|
|
|
|
/// 改变图元宽度
|
|
/// @param width 宽度
|
|
/// @note 此方法会发出resize事件, 如果不想发出事件, 请用 setBounds 方法.
|
|
/// @see onResize
|
|
void setWidth(float width);
|
|
|
|
/// 改变图元高度
|
|
/// @param height 高度
|
|
/// @note 此方法会发出resize事件, 如果不想发出事件, 请用 setBounds 方法.
|
|
/// @see onResize
|
|
void setHeight(float height);
|
|
|
|
// 位置改变
|
|
virtual void onMove(const QPointF& ptOld, const QPointF& ptNew);
|
|
|
|
// 尺寸改变
|
|
virtual void onResize(const QSizeF & szOld, const QSizeF & szNew);
|
|
|
|
/// 查找指定位置处的控制点
|
|
ZxHandleRef findHandle(const QPointF& pos, float fHandleSize, bool bSelectedOnly);
|
|
|
|
/// 查找指定位置处的控制点
|
|
ZxHandleRef findHandle(float x, float y, float fHandleSize, bool bSelectedOnly);
|
|
|
|
/// 查找指定位置处的单个图元
|
|
/// @param pos 查找的坐标
|
|
/// @param bRecursive true表示查找所有子孙节点, false表示只查找直接子节点. 默认为true.
|
|
/// @param filter 查找条件, 这是一个过滤函数. 默认为NULL, 匹配所有图元.
|
|
/// @return 第一个匹配的图元
|
|
ZxRenderItem* findItem(const QPointF& pos, ZxFilterFun filter = NULL, bool bRecursive = true);
|
|
|
|
/// 查找指定位置处的单个图元
|
|
/// @param x 查找的X坐标
|
|
/// @param y 查找的Y坐标
|
|
/// @param bRecursive true表示查找所有子孙节点, false表示只查找直接子节点. 默认为true.
|
|
/// @param filter 查找条件, 这是一个过滤函数. 默认为NULL, 匹配所有图元.
|
|
/// @return 第一个匹配的图元
|
|
virtual ZxRenderItem* findItem(float x, float y, ZxFilterFun filter = NULL, bool bRecursive = true);
|
|
|
|
/// 查找指定位置处的多个图元
|
|
/// @param pos 查找的坐标
|
|
/// @param bRecursive true表示查找所有子孙节点, false表示只查找直接子节点. 默认为true.
|
|
/// @param filter 查找条件, 这是一个过滤函数. 默认为NULL, 匹配所有图元.
|
|
/// @return 所有匹配的图元
|
|
QList<ZxRenderItem*> findItems(const QPointF& pos, ZxFilterFun filter = NULL, bool bRecursive = true);
|
|
|
|
|
|
/// 查找指定位置处的多个图元
|
|
/// @param x 查找的X坐标
|
|
/// @param y 查找的Y坐标
|
|
/// @param bRecursive true表示查找所有子孙节点, false表示只查找直接子节点. 默认为true.
|
|
/// @param filter 查找条件, 这是一个过滤函数. 默认为NULL, 匹配所有图元.
|
|
/// @return 所有匹配的图元
|
|
virtual QList<ZxRenderItem*> findItems(float x, float y, ZxFilterFun filter = NULL, bool bRecursive = true);
|
|
|
|
/// 查找指定类型的子(孙)图元
|
|
template<typename T>
|
|
T findChildItem(bool recursive = true)
|
|
{
|
|
int n = this->count();
|
|
for (int i = n - 1; i >= 0; i--)
|
|
{
|
|
ZxRenderItem* c = at(i);
|
|
T p = 0;
|
|
if (recursive)
|
|
{
|
|
p = c->findChildItem<T>(true);
|
|
}
|
|
if (p == 0)
|
|
{
|
|
p = dynamic_cast<T>(c);
|
|
}
|
|
if (p)
|
|
{
|
|
return p;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// 检测指定点处是否位于图元内部
|
|
virtual bool isItemBody(float x, float y);
|
|
|
|
/// 图元标志集
|
|
Flags getFlags() const;
|
|
void setFlags(Flags flags);
|
|
|
|
/// 是否选中
|
|
bool isSelected() const;
|
|
|
|
virtual bool isEqual(const IxRenderItem* pAnother) const;
|
|
|
|
/// 设置选中标志
|
|
void setSelected(bool b);
|
|
|
|
public:
|
|
|
|
/// 选中状态改变
|
|
virtual void onSelectedChanged();
|
|
|
|
/// 选择本图元
|
|
/// @note 此方法不但设置图元选中状态, 而且把图元加入场景的选中列表中.
|
|
/// @see setSelected(bool)
|
|
virtual void select(bool bClearOldSelect = true);
|
|
|
|
/// 取消选择本图元.
|
|
/// @note 此方法不但取消图元选中状态, 而且从场景的选中列表中删除图元.
|
|
/// @see setSelected(bool)
|
|
virtual void deselect(bool bRecursive = false);
|
|
|
|
/// 是否可见
|
|
bool isVisible() const;
|
|
void setVisible(bool b);
|
|
|
|
/// 可见状态改变
|
|
virtual void onVisibleChanged();
|
|
|
|
/// 显示, 相当于setVisible(true)
|
|
void show();
|
|
|
|
/// 隐藏, 相当于setVisible(false)
|
|
void hide();
|
|
|
|
/// 是否隐藏, 等于 !isVisible()
|
|
bool isHidden() const;
|
|
|
|
/// 是否可选
|
|
bool isSelectable() const;
|
|
void setSelectable(bool b);
|
|
|
|
/// 可选状态改变
|
|
virtual void onSelectableChanged();
|
|
|
|
/// 是否锁定位置
|
|
bool isLockPos() const;
|
|
void setLockPos(bool b);
|
|
|
|
/// 锁定位置状态改变
|
|
virtual void onLockPosChanged();
|
|
|
|
/// 是否锁定尺寸
|
|
bool isLockSize() const;
|
|
void setLockSize(bool b);
|
|
|
|
/// 锁定尺寸状态改变
|
|
virtual void onLockSizeChanged();
|
|
|
|
/// 是否只读
|
|
bool isReadOnly() const;
|
|
void setReadOnly(bool b);
|
|
|
|
/// 只读状态改变
|
|
virtual void onReadOnlyChanged();
|
|
|
|
/// 是否剪裁
|
|
bool isClipping() const;
|
|
void setClipping(bool b);
|
|
|
|
/// 剪裁状态改变
|
|
virtual void onClippingChanged();
|
|
|
|
/// 是否偏移坐标
|
|
bool hasLocalCoord() const;
|
|
void setLocalCoord(bool b);
|
|
|
|
/// 偏移坐标状态改变
|
|
virtual void onLocalCoordChanged();
|
|
|
|
/// 获取坐标系所属的图元.
|
|
/// @return 往祖先结点找, 返回最近一个hasLocalCoord()的图元. 没找到则返回图元树的根结点.
|
|
virtual ZxRenderItem* getCoordItem() const;
|
|
|
|
/// 是否自动尺寸
|
|
bool isAutoSize() const;
|
|
void setAutoSize(bool b);
|
|
|
|
/// 自动尺寸标志改变
|
|
virtual void onAutoSizeChanged();
|
|
|
|
/// 是否自动布局
|
|
bool isAutoLayout() const;
|
|
void setAutoLayout(bool b);
|
|
|
|
/// 自动布局标志改变
|
|
virtual void onAutoLayoutChanged();
|
|
|
|
/// 绘图时是否反走样
|
|
bool isAntiAlias() const;
|
|
void setAntiAlias(bool b);
|
|
|
|
/// 反走样标志改变
|
|
virtual void onAntiAliasChanged();
|
|
|
|
|
|
/// 是否紧缩
|
|
bool isShrink() const;
|
|
void setShrink(bool b);
|
|
|
|
/// 紧缩标志改变
|
|
virtual void onShrinkChanged();
|
|
|
|
/// 是否需要重新布局
|
|
bool needLayout() const;
|
|
|
|
/// 是否强制重新布局
|
|
bool isForceLayout() const;
|
|
|
|
/// 刷新布局
|
|
void updateLayout(bool bForce = false);
|
|
|
|
/// 可否手动删除
|
|
bool canManualDelete() const;
|
|
void setManualDelete(bool b = true);
|
|
|
|
/// 是否静态Policy
|
|
bool isStaticPolicy() const;
|
|
void setStaticPolicy(bool b);
|
|
|
|
/// 是否平凡Policy
|
|
bool isOrdinaryPolicy() const;
|
|
void setOrdinaryPolicy(bool b);
|
|
|
|
/// 实际上是否锁定位置
|
|
bool isActuallyLockPos() const;
|
|
bool isActuallyLockSize() const;
|
|
|
|
/// 刷新
|
|
/// @note 刷新图元所占的区域, 包括附着在图元上的Policy等所占的区域
|
|
virtual void update();
|
|
|
|
/// 刷新指定区域(图元的当前坐标系)
|
|
virtual void update(const QRectF& rect);
|
|
|
|
|
|
/// 准备右键菜单
|
|
virtual void onPrepareContextMenu(QMenu * pMenu, const QPointF& pos);
|
|
|
|
/// 从本图元坐标系转到子图元坐标系
|
|
QPointF mapToChild(const QPointF& pos) const;
|
|
/// 从子图元坐标系转到本图元坐标系
|
|
QPointF mapFromChild(const QPointF& pos) const;
|
|
/// 从本图元坐标系转到子图元坐标系
|
|
QRectF mapToChild(const QRectF& rect) const;
|
|
/// 从子图元坐标系转到本图元坐标系
|
|
QRectF mapFromChild(const QRectF& rect) const;
|
|
|
|
|
|
/// 从其他图元坐标系转到本图元坐标系
|
|
QPointF mapFrom(ZxRenderItem* item, const QPointF& pt) const;
|
|
|
|
/// 从本图元坐标系转到其他图元坐标系
|
|
QPointF mapTo(ZxRenderItem* item, const QPointF& pt) const;
|
|
|
|
/// 从本图元坐标系转到文档坐标系
|
|
QPointF mapToScene(const QPointF& pos) const;
|
|
|
|
/// 从文档图元坐标系转到本坐标系
|
|
QPointF mapFromScene(const QPointF& pos) const;
|
|
|
|
/// 从本图元坐标系转到文档坐标系
|
|
QRectF mapToScene(const QRectF& rect) const;
|
|
|
|
/// 从文档图元坐标系转到本坐标系
|
|
QRectF mapFromScene(const QRectF& rect) const;
|
|
|
|
/// 填属性表
|
|
virtual void fillPtyPano(IxPtyPano* sheet);
|
|
|
|
/// 获取标志集的字符串, 用来显示和调试
|
|
virtual QString getFlagsString() const;
|
|
|
|
/// 是否有祖先图元被选中
|
|
/// @note 在某些操作中, 选中某个图元时相当于把整棵子树全选中了. 这个函数提了供一种快速检测这种状态的方法.
|
|
virtual bool isAncestorSelected() const;
|
|
|
|
/// 判断本图元是否指定图元的祖先
|
|
/// @note 这的祖先指图元树上的关系, 不是类的继承关系. 任何图元都不是它自己的祖先
|
|
bool isAncestorOf(const ZxRenderItem* p) const;
|
|
|
|
/// 判断本图元是否指定图元的子孙
|
|
/// @note 这的子孙指图元树的上的关系, 不是类的继承关系. 任何图元都不是它自己的子孙
|
|
bool isDescendantOf(const ZxRenderItem* p) const;
|
|
|
|
// 左键双击
|
|
virtual void onLeftDoubleClick(const QPointF& pt);
|
|
|
|
// 左键单击
|
|
virtual void onLeftClick(const QPointF& pt);
|
|
|
|
// parent指针被改变
|
|
/// @note 不是parent的内容被改变
|
|
virtual void onParentChanged();
|
|
|
|
/// 不变性(完整性)验证. 这个函数里有一堆ASSERT, 验证图元未损坏.
|
|
/// @note ZxSceneItem 要求子图元必须是几个特定图层, 在ZxSceneItem::invariant() 中就可以加上这些验证.
|
|
/// @note 此为契约编程的概念, C++无法自动调用此方法, 但底层会在paint等使用频繁使用的函数里调用. 必要时模块层也可以显示调用.
|
|
virtual void invariant() const;
|
|
|
|
/// 加载文件
|
|
template <typename T>
|
|
static T load(const QString& filePath)
|
|
{
|
|
ZxRenderItem* p = load(filePath);
|
|
T p1 = dynamic_cast<T>(p);
|
|
if (p1 == 0 && p != 0)
|
|
{
|
|
Q_ASSERT(false);
|
|
delete p;
|
|
}
|
|
return p1;
|
|
}
|
|
|
|
/// 加载
|
|
static ZxRenderItem* load(const QString& filePath);
|
|
static ZxRenderItem* load(QFile& file);
|
|
static ZxRenderItem* load(QDataStream& stream);
|
|
|
|
/// 保存
|
|
virtual bool save(const QString& filePath) const;
|
|
virtual bool save(QFile& file) const;
|
|
virtual bool save(QDataStream& stream) const;
|
|
|
|
/// 克隆图元
|
|
/// @note 此函数自动使用序列化来克隆图元, 一般情况下无需重写.
|
|
virtual IxRenderItem* clone() const;
|
|
|
|
/// 克隆图元
|
|
/// @note 此函数自动使用序列化来克隆图元, 一般情况下无需重写.
|
|
template <typename T>
|
|
T clone() const
|
|
{
|
|
ZxRenderItem* p = this->clone();
|
|
T ret = dynamic_cast<T>(p);
|
|
if (ret == 0)
|
|
{
|
|
delete p;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/// 图元导出为图片文件
|
|
/// @param fileName 文件路径.
|
|
/// @param format 图片格式, 支持Qt所支持的格式和"SVG".
|
|
/// @param quality 暂未使用, 请设为-1
|
|
/// @return 导出成功返回true, 失败返回false.
|
|
virtual bool exportImage(const QString& fileName, const char * format = 0, int quality = -1) const;
|
|
|
|
/// 获取图元树迭代器
|
|
virtual ZxRenderItemIterator getRenderTree();
|
|
|
|
/// 设置布局器
|
|
virtual void setLayout(ZxLayout* p);
|
|
|
|
/// 查找多个图元的最近公共祖先节点
|
|
static ZxRenderItem* findCommonAncestor(const QList<ZxRenderItem*> & items);
|
|
|
|
/// 获取当前活动的属性表条目.
|
|
/// @note 用户在属性表里修改属性后, 通常会有一个回调, 例如调用对象的setXXXX()函数.
|
|
/// 在这些回调函数里, 我们就可以用getPropertyItem(bool)来获取当前所修改的属性表条目.
|
|
/// @param bOnlyWhenIsFirst 是否仅在当前图元是第一个图元时才返回.
|
|
/// @return 当前活动的(用户正在修改的)属性条目. 如果当前没有活动条目, 此函数返回NULL.
|
|
/// @see findPropertyItem(const QString &, bool)
|
|
static IxPtyItem * getPropertyItem(bool bOnlyWhenIsFirst = true);
|
|
|
|
/// 从当前活动的属性表里查找指定条目.
|
|
/// @note 用户在属性表里修改属性后, 通常会有一个回调, 例如调用对象的setXXXX()函数.
|
|
/// 在这些回调函数里, findPropertyItem()来查找当前所修改的属性表中的指定条目.
|
|
/// @param key 指定条目的名称(路径), 如 "井头.井名.字体"
|
|
/// @param bOnlyWhenIsFirst 是否仅在当前图元是第一个图元时才返回.
|
|
/// @return 找到的条目, 当前没有活动条目或者查找失败时返回NULL.
|
|
/// @see getPropertyItem(bool)
|
|
static IxPtyItem * findPropertyItem(const QString& key, bool bOnlyWhenIsFirst = true);
|
|
|
|
protected:
|
|
|
|
/// 布局操作, 可重写, 默认操作是使用布局器布局.
|
|
/// \li 无论needLayout()的值是什么, 都要做布局.
|
|
/// \li 布局完了以后一定要setNeedLaout(false)
|
|
/// \li 此方法内要递归调用子图元的 doLayout()
|
|
virtual void onLayout();
|
|
|
|
public:
|
|
|
|
/// 在需要布局的时候调用 onLayout() 重新布局
|
|
void doLayout();
|
|
|
|
/// 获取属性窗口
|
|
virtual IxPtyPano* getPtyPano(bool tryOuter = true) const;
|
|
|
|
/// 获取图元的编辑器
|
|
/// @param bCreate 是否创建
|
|
/// @return 图元的编辑器, bCreate为true时保证返回可用的编辑器, 否则可能为NULL.
|
|
/// @note 每个图元都关联着一个编辑器
|
|
/// @see emitSigInstallPolicies() sigInstallPolicies() onInstallPolicies()
|
|
virtual ZxEdit* getEdit(bool bCreate = true) const;
|
|
|
|
// short for getEdit()->getHandlePolicy()
|
|
ZxHandlePolicy* getHandlePolicy() const;
|
|
|
|
/// The recommended size for the widget.
|
|
/// If the value is an invalid size, no size is recommended.
|
|
/// The default implementation of sizeHint() returns an invalid size if there is no layout for this item, and returns the layout's preferred size otherwise.
|
|
virtual QSizeF getSizeHint() const;
|
|
|
|
/// 调用 onInstallPolicies(), 然后发出信号 sigInstallPolicies()
|
|
void emitSigInstallPolicies();
|
|
|
|
/// (内部使用)
|
|
/// \internal
|
|
ZxRenderItem* getClippedBy();
|
|
|
|
static void saveMulti(QDataStream& stream, const QList<ZxRenderItem*> & list);
|
|
static QList<ZxRenderItem*> loadMulti(QDataStream& stream);
|
|
|
|
|
|
public slots:
|
|
|
|
protected:
|
|
|
|
/// 在此函数内安装编辑策略
|
|
virtual void onInstallPolicies();
|
|
|
|
virtual bool needPaintSelf(QPainter* painter, const ZxPaintParam& param) const;
|
|
virtual bool needPaintDescendants(QPainter* painter, const ZxPaintParam& param) const;
|
|
|
|
virtual void onApplyAutoSize();
|
|
|
|
virtual void onChildItemAdded(ZxRenderItem* p);
|
|
|
|
virtual void onChildItemRemoved(ZxRenderItem* p);
|
|
|
|
private:
|
|
|
|
void checkNeedLayoutFlagConsistency();
|
|
bool _findItems(QList<ZxRenderItem*> & list, float x, float y, \
|
|
ZxFilterFun filter, bool bRecursive);
|
|
void _insert(int index, ZxRenderItem* p);
|
|
void _setNeedLayout(bool bNeed);
|
|
void _setForceLayout(bool bForce);
|
|
_ZxRenderChildIndex* get_item_index_map();
|
|
|
|
private:
|
|
|
|
// QList内部用的是指针数组, 我们直接用指针数据效率可能更高
|
|
QVector<ZxRenderItem*> m_vecChildren;
|
|
|
|
// 父节点
|
|
ZxRenderItem* m_pParent;
|
|
|
|
// 外接矩形
|
|
QRectF m_rectBounds;
|
|
|
|
// 标志集
|
|
Flags m_nFlags;
|
|
|
|
// 当前的编辑器, 如内嵌文本输入框
|
|
mutable ZxEdit* m_pEdit;
|
|
|
|
// 布局器
|
|
ZxLayout* m_pLayout;
|
|
|
|
// 子图元位置索引, 加快indexOf等操作
|
|
_ZxRenderChildIndex * m_pChildIndex;
|
|
|
|
bool m_bInDoLayout : 1; // for debug
|
|
bool m_bHasOldOnLayout : 1; // for debug
|
|
bool m_bInPainting : 1; // for debug
|
|
|
|
friend class ZxRenderView;
|
|
friend class ZxSceneItem;
|
|
friend class ZxSelectionPrivate;
|
|
friend class ZxLayout;
|
|
};
|
|
|
|
I_PLOTBASE_EXPORT QString zxSplitTagName(const QString& s);
|