bug,设置父引用为null的时候引发visible过程,导致其他视图被归类到空闲视图类别错误
This commit is contained in:
parent
e2bafb16fb
commit
75982278b4
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.15.0, 2024-02-07T16:25:47. -->
|
||||
<!-- Written by QtCreator 4.15.0, 2024-02-09T16:03:39. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
|
|
@ -112,7 +112,7 @@ void accept_panel::AcceptPanel::dragEnterEvent(QDragEnterEvent *ev)
|
|||
void accept_panel::AcceptPanel::dropEvent(QDropEvent *ev)
|
||||
{
|
||||
auto view = view_manager->adjustView();
|
||||
if(view){
|
||||
if(view && anchor_view != view){
|
||||
switch (target_type) {
|
||||
case HoverType::CUBE_LEFT:
|
||||
view_manager->doRetrieve(view);
|
||||
|
|
|
@ -146,6 +146,7 @@ void DockableView::adjustAccept(const QPoint &pos)
|
|||
|
||||
void DockableView::closeAccept()
|
||||
{
|
||||
this->manager_inst->doRetrieve(this);
|
||||
this->manager_inst->doClose(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,10 +79,11 @@ bool SplitPanel::isVisible() const
|
|||
|
||||
void SplitPanel::initViews(ViewRes *a, ViewRes *b)
|
||||
{
|
||||
this->split_member = std::make_pair(a, b);
|
||||
|
||||
a->setParentRes(this);
|
||||
b->setParentRes(this);
|
||||
this->split_member = std::make_pair(a, b);
|
||||
|
||||
this->sync_status();
|
||||
}
|
||||
|
||||
QWidget *SplitPanel::widget() const { return const_cast<SplitPanel *>(this); }
|
||||
|
@ -132,9 +133,9 @@ void SplitPanel::replaceView(ViewRes *_new, ViewRes *_old)
|
|||
throw new SimpleException<QString>("运行异常", "指定替换的视图不属于本组件");
|
||||
}
|
||||
|
||||
_new->setParentRes(this);
|
||||
auto elsev = except(_old);
|
||||
switch (std::get<1>(elsev)) {
|
||||
_new->setParentRes(this);
|
||||
switch (elsev.second) {
|
||||
case 0:
|
||||
this->split_member = std::make_pair(elsev.first, _new);
|
||||
break;
|
||||
|
@ -142,6 +143,7 @@ void SplitPanel::replaceView(ViewRes *_new, ViewRes *_old)
|
|||
this->split_member = std::make_pair(_new, elsev.first);
|
||||
}
|
||||
|
||||
_old->setParentRes(nullptr);
|
||||
sync_status();
|
||||
this->update();
|
||||
}
|
||||
|
|
|
@ -128,16 +128,16 @@ namespace split_frame {
|
|||
virtual ~SplitView() = default;
|
||||
|
||||
/**
|
||||
* @brief 载入视图成员
|
||||
* @brief 载入视图成员,构建父子引用关系
|
||||
* @param a 成员视图a
|
||||
* @param b 成员视图b
|
||||
*/
|
||||
virtual void initViews(ViewRes *a, ViewRes *b) = 0;
|
||||
|
||||
/**
|
||||
* @brief 构建子视图
|
||||
* @param old 不为nullptr
|
||||
* @param view 不为nullptr
|
||||
* @brief 使用新视图替换指定视图,重构呈现树
|
||||
* @param view 实例需要属于闲置视图,调用完成被重建父子引用
|
||||
* @param pos 实例属于呈现树,调用完成将被解除父子引用
|
||||
*/
|
||||
virtual void replaceView(ViewRes *_new, ViewRes *_old) = 0;
|
||||
|
||||
|
@ -231,23 +231,30 @@ namespace split_frame {
|
|||
*/
|
||||
virtual void appendPresentView(ViewBase *inst) = 0;
|
||||
|
||||
/**
|
||||
* @brief 测试指定视图是否处于呈现状态
|
||||
* @param inst 指定视图
|
||||
*/
|
||||
virtual bool isPresented(ViewBase *inst) const = 0;
|
||||
|
||||
/**
|
||||
* @brief 回收视图显示,转换视图为自由(闲置)状态
|
||||
* @param inst
|
||||
* @param inst 视图实例需要确实处于可视状态(临时显示或位于呈现树内)
|
||||
*/
|
||||
virtual void doRetrieve(ViewBase *inst) = 0;
|
||||
|
||||
/**
|
||||
* @brief 回收视图,清除内存实例
|
||||
* @param inst 视图实例需要处于闲置状态
|
||||
*/
|
||||
virtual void doClose(ViewBase *inst) = 0;
|
||||
|
||||
/**
|
||||
* @brief 替换指定视图
|
||||
* @param view
|
||||
* @param old
|
||||
* @brief 使用指定视图合并显示
|
||||
* @param view 需要合并的闲置视图
|
||||
* @param pos 指定合并目标位置
|
||||
*/
|
||||
virtual void siblingAttach(ViewBase *view, ViewRes *pos, SplitType ori) = 0;
|
||||
virtual void siblingAttach(ViewBase *view, ViewBase *pos, SplitType ori) = 0;
|
||||
};
|
||||
|
||||
} // namespace SplitFrame
|
||||
|
|
|
@ -17,26 +17,34 @@
|
|||
using namespace split_window;
|
||||
using namespace split_frame;
|
||||
|
||||
void SplitWindow::setRoot(split_frame::ViewRes *inst)
|
||||
|
||||
SplitWindow::SplitWindow(QWidget *parent) : QMainWindow(parent), view_root(nullptr), accept_port(new accept_panel::AcceptPanel(this, this)) {
|
||||
this->view_root = nullptr;
|
||||
accept_port->setVisible(false);
|
||||
}
|
||||
|
||||
SplitWindow::~SplitWindow() {}
|
||||
|
||||
void SplitWindow::tempShow(split_frame::DockType t, split_frame::ViewBase *target)
|
||||
{
|
||||
this->temp_show = target;
|
||||
target->setVisible(true);
|
||||
}
|
||||
|
||||
void SplitWindow::setPresentTarget(split_frame::ViewRes *inst)
|
||||
{
|
||||
if(inst){
|
||||
this->view_root = inst;
|
||||
inst->setParentRes(nullptr);
|
||||
this->setCentralWidget(inst->widget());
|
||||
}
|
||||
else{
|
||||
this->takeCentralWidget();
|
||||
this->view_root = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
SplitWindow::SplitWindow(QWidget *parent) : QMainWindow(parent), view_root(nullptr), accept_port(new accept_panel::AcceptPanel(this, this)) {
|
||||
this->setRoot(nullptr);
|
||||
accept_port->setVisible(false);
|
||||
this->view_root = inst;
|
||||
this->update();
|
||||
}
|
||||
|
||||
SplitWindow::~SplitWindow() {}
|
||||
|
||||
bool SplitWindow::eventFilter(QObject *sender, QEvent *ev)
|
||||
{
|
||||
switch (ev->type()) {
|
||||
|
@ -51,7 +59,7 @@ bool SplitWindow::eventFilter(QObject *sender, QEvent *ev)
|
|||
global_pos = dynamic_cast<QWidget *>(sender)->mapToGlobal(evn_pos);
|
||||
}
|
||||
|
||||
for (auto &cmp : this->views_store) {
|
||||
for (auto &cmp : this->presents_store) {
|
||||
auto local_pos = cmp->widget()->mapFromGlobal(global_pos);
|
||||
auto rect_shape = cmp->outlineRect();
|
||||
rect_shape.moveTopLeft(QPointF());
|
||||
|
@ -89,57 +97,70 @@ void SplitWindow::removeListener(split_frame::FreedomViewsListener *lsn)
|
|||
void SplitWindow::appendPresentView(split_frame::ViewBase *inst)
|
||||
{
|
||||
if(inst)
|
||||
this->views_store[inst->hashCode()] = inst;
|
||||
this->presents_store[inst->hashCode()] = inst;
|
||||
}
|
||||
|
||||
void SplitWindow::removePresentView(split_frame::ViewBase *inst)
|
||||
{
|
||||
if(inst)
|
||||
this->views_store.remove(inst->hashCode());
|
||||
this->presents_store.remove(inst->hashCode());
|
||||
}
|
||||
|
||||
void SplitWindow::present_remove(split_frame::ViewRes *inst)
|
||||
bool SplitWindow::isPresented(split_frame::ViewBase *inst) const
|
||||
{
|
||||
// 面板树中间节点
|
||||
if(inst != view_root && inst->parentRes()){
|
||||
return inst && presents_store.contains(inst->hashCode());
|
||||
}
|
||||
|
||||
|
||||
#include <libConfig.h>
|
||||
void SplitWindow::doRetrieve(split_frame::ViewBase *inst)
|
||||
{
|
||||
if(!isPresented(inst)){
|
||||
throw new Config::SimpleException<QString>("参数错误", "无法回收空闲视图!");
|
||||
}
|
||||
|
||||
// 呈现视图结构调整
|
||||
if(inst == temp_show){
|
||||
temp_show->setVisible(false);
|
||||
return;
|
||||
}
|
||||
else if (inst == view_root) {
|
||||
setPresentTarget();
|
||||
inst->setParentRes(nullptr);
|
||||
}
|
||||
else if(inst->parentRes() == view_root){
|
||||
auto pinst_root = inst->parentRes();
|
||||
|
||||
auto remains = pinst_root->except(inst);
|
||||
inst->setParentRes(nullptr);
|
||||
|
||||
setPresentTarget(remains.first);
|
||||
delete pinst_root;
|
||||
}
|
||||
else if(inst->parentRes()){
|
||||
auto pinst = inst->parentRes();
|
||||
|
||||
auto remains = pinst->except(inst);
|
||||
remains.first->setParentRes(nullptr);
|
||||
inst->setParentRes(nullptr);
|
||||
|
||||
// 父节点不是根节点
|
||||
auto ppinst = pinst->parentRes();
|
||||
if (ppinst) {
|
||||
ppinst->replaceView(remains.first, pinst);
|
||||
} else {
|
||||
this->setRoot(remains.first);
|
||||
}
|
||||
delete pinst;
|
||||
}
|
||||
else if(inst == view_root){
|
||||
setRoot(nullptr);
|
||||
inst->setParentRes(nullptr);
|
||||
}
|
||||
}
|
||||
void SplitWindow::doRetrieve(split_frame::ViewBase *inst)
|
||||
{
|
||||
// 呈现视图结构调整
|
||||
present_remove(inst);
|
||||
|
||||
// 回收当前视图
|
||||
for(auto &lsn : listener_list)
|
||||
lsn->freedomAppend(inst);
|
||||
|
||||
inst->setParentRes(nullptr);
|
||||
inst->setVisible(false);
|
||||
removePresentView(inst);
|
||||
|
||||
// 当前视图已被回收
|
||||
for(auto &lsn : listener_list)
|
||||
lsn->freedomAppend(inst);
|
||||
}
|
||||
|
||||
void SplitWindow::doClose(split_frame::ViewBase *inst)
|
||||
{
|
||||
// 呈现视图结构调整
|
||||
present_remove(inst);
|
||||
if(isPresented(inst))
|
||||
throw new Config::SimpleException<QString>("编码异常", "不能关闭非空闲视图!");
|
||||
|
||||
// 回收当前视图
|
||||
for(auto &lsn : listener_list)
|
||||
|
@ -149,11 +170,16 @@ void SplitWindow::doClose(split_frame::ViewBase *inst)
|
|||
delete inst;
|
||||
}
|
||||
|
||||
void SplitWindow::siblingAttach(ViewBase *view, ViewRes *pos, SplitType ori)
|
||||
void SplitWindow::siblingAttach(ViewBase *view, ViewBase *pos, SplitType ori)
|
||||
{
|
||||
auto remains_frm = pos->parentRes();
|
||||
doRetrieve(view);
|
||||
if(isPresented(view) && view != temp_show){
|
||||
throw new Config::SimpleException<QString>("参数错误", "只能使用空闲视图吸附重组!");
|
||||
}
|
||||
if(!isPresented(pos)){
|
||||
throw new Config::SimpleException<QString>("参数错误", "不能依据空闲视图吸附重组!");
|
||||
}
|
||||
|
||||
auto remains_frm = pos->parentRes();
|
||||
auto split_slot = new split_panel::SplitPanel(this, ori);
|
||||
remains_frm->replaceView(split_slot, pos);
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ namespace split_window {
|
|||
|
||||
private:
|
||||
QList<split_frame::FreedomViewsListener*> listener_list;
|
||||
QHash<qulonglong, split_frame::ViewBase*> views_store;
|
||||
split_frame::ViewRes *view_root;
|
||||
|
||||
QHash<qulonglong, split_frame::ViewBase*> presents_store;
|
||||
accept_panel::AcceptPanel *const accept_port;
|
||||
split_frame::ViewRes *view_root = nullptr, *temp_show = nullptr;
|
||||
split_frame::ViewBase *adjust_target = nullptr;
|
||||
|
||||
void present_remove(split_frame::ViewRes *inst);
|
||||
|
||||
public:
|
||||
SplitWindow(QWidget *parent = nullptr);
|
||||
|
@ -39,8 +39,11 @@ namespace split_window {
|
|||
void tempShow(split_frame::DockType t, split_frame::ViewBase *target);
|
||||
|
||||
|
||||
void setRoot(split_frame::ViewRes *inst);
|
||||
|
||||
/**
|
||||
* @brief 设置指定视图为根视图或者取消
|
||||
* @param inst
|
||||
*/
|
||||
void setPresentTarget(split_frame::ViewRes *inst = nullptr);
|
||||
|
||||
bool eventFilter(QObject *sender, QEvent *ev) override;
|
||||
|
||||
|
@ -50,9 +53,10 @@ namespace split_window {
|
|||
virtual void removeListener(split_frame::FreedomViewsListener *lsn) override;
|
||||
virtual void appendPresentView(split_frame::ViewBase *inst) override;
|
||||
virtual void removePresentView(split_frame::ViewBase *inst) override;
|
||||
virtual bool isPresented(split_frame::ViewBase *inst) const override;
|
||||
virtual void doRetrieve(split_frame::ViewBase *inst) override;
|
||||
virtual void doClose(split_frame::ViewBase *inst) override;
|
||||
virtual void siblingAttach(split_frame::ViewBase *view, split_frame::ViewRes *pos, split_frame::SplitType ori) override;
|
||||
virtual void siblingAttach(split_frame::ViewBase *view, split_frame::ViewBase *pos, split_frame::SplitType ori) override;
|
||||
virtual split_frame::ViewBase *adjustView() const override;
|
||||
virtual void setAdjustView(split_frame::ViewBase *target) override;
|
||||
};
|
||||
|
|
|
@ -20,12 +20,11 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
split_window::SplitWindow w;
|
||||
auto spb = new split_panel::SplitPanel(&w, split_frame::SplitType::SPLIT_H_LFIRST);
|
||||
w.setRoot(spb);
|
||||
|
||||
auto bview = new dock_panel::DockableView(&w, new QWidget, true);
|
||||
auto dview = new dock_panel::DockableView(&w, new QWidget, true);
|
||||
spb->initViews(bview, dview);
|
||||
|
||||
w.setPresentTarget(spb);
|
||||
a.installEventFilter(&w);
|
||||
|
||||
w.show();
|
||||
|
|
Loading…
Reference in New Issue