完成拖动,但是未完成释放
This commit is contained in:
parent
d2ac84894d
commit
b6bae9980b
|
|
@ -2,6 +2,7 @@ TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
GenericConsole \
|
GenericConsole \
|
||||||
|
SplitView \
|
||||||
WordsIDE \
|
WordsIDE \
|
||||||
libConfig \
|
libConfig \
|
||||||
libProjectManager \
|
libProjectManager \
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 4.15.0, 2023-08-13T11:50:05. -->
|
<!-- Written by QtCreator 4.15.0, 2023-08-20T21:48:18. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|
@ -346,7 +346,80 @@
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Projects/Cpp/build-QtNovelDesc-Desktop_Qt_5_12_11_MSVC2017_64bit-Debug/u_test</value>
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Projects/Cpp/build-QtNovelDesc-Desktop_Qt_5_12_11_MSVC2017_64bit-Debug/u_test</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
|
||||||
|
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||||
|
<value type="QString">cpu-cycles</value>
|
||||||
|
</valuelist>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||||
|
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
|
||||||
|
<value type="QString">-e</value>
|
||||||
|
<value type="QString">cpu-cycles</value>
|
||||||
|
<value type="QString">--call-graph</value>
|
||||||
|
<value type="QString">dwarf,4096</value>
|
||||||
|
<value type="QString">-F</value>
|
||||||
|
<value type="QString">250</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||||
|
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||||
|
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||||
|
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||||
|
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.Callgrind.Arguments"></value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||||
|
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||||
|
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.Memcheck.Arguments"></value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.ValgrindArguments"></value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||||
|
<value type="int">0</value>
|
||||||
|
<value type="int">1</value>
|
||||||
|
<value type="int">2</value>
|
||||||
|
<value type="int">3</value>
|
||||||
|
<value type="int">4</value>
|
||||||
|
<value type="int">5</value>
|
||||||
|
<value type="int">6</value>
|
||||||
|
<value type="int">7</value>
|
||||||
|
<value type="int">8</value>
|
||||||
|
<value type="int">9</value>
|
||||||
|
<value type="int">10</value>
|
||||||
|
<value type="int">11</value>
|
||||||
|
<value type="int">12</value>
|
||||||
|
<value type="int">13</value>
|
||||||
|
<value type="int">14</value>
|
||||||
|
</valuelist>
|
||||||
|
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:D:/Projects/Cpp/QtNovelDesc/WordsIDE/WordsIDE.pro</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">D:/Projects/Cpp/QtNovelDesc/WordsIDE/WordsIDE.pro</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/Projects/Cpp/build-QtNovelDesc-Desktop_Qt_5_12_11_MSVC2017_64bit-Debug/WordsIDE</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
</data>
|
</data>
|
||||||
<data>
|
<data>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
QT += gui widgets
|
||||||
|
|
||||||
|
TEMPLATE = lib
|
||||||
|
DEFINES += SPLITVIEW_LIBRARY
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
# You can make your code fail to compile if it uses deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
msvc{
|
||||||
|
QMAKE_CFLAGS += /utf-8
|
||||||
|
QMAKE_CXXFLAGS += /utf-8
|
||||||
|
}
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
splitview.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
SplitView_global.h \
|
||||||
|
splitview.h
|
||||||
|
|
||||||
|
# Default rules for deployment.
|
||||||
|
unix {
|
||||||
|
target.path = /usr/lib
|
||||||
|
}
|
||||||
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libConfig/release/ -llibConfig
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libConfig/debug/ -llibConfig
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../libConfig/ -llibConfig
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../libConfig
|
||||||
|
DEPENDPATH += $$PWD/../libConfig
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef SPLITVIEW_GLOBAL_H
|
||||||
|
#define SPLITVIEW_GLOBAL_H
|
||||||
|
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
#if defined(SPLITVIEW_LIBRARY)
|
||||||
|
# define SPLITVIEW_EXPORT Q_DECL_EXPORT
|
||||||
|
#else
|
||||||
|
# define SPLITVIEW_EXPORT Q_DECL_IMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // SPLITVIEW_GLOBAL_H
|
||||||
|
|
@ -0,0 +1,719 @@
|
||||||
|
#include "splitview.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDrag>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLineF>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QResizeEvent>
|
||||||
|
#include <QStyleOption>
|
||||||
|
#include <libConfig.h>
|
||||||
|
|
||||||
|
using namespace SplitFrame;
|
||||||
|
using namespace Config;
|
||||||
|
|
||||||
|
class ViewDragDrapCommon {
|
||||||
|
public:
|
||||||
|
BaseView *target;
|
||||||
|
static QString type_sign;
|
||||||
|
|
||||||
|
ViewDragDrapCommon(BaseView *inst) : target(inst) {}
|
||||||
|
ViewDragDrapCommon() : target(nullptr) {}
|
||||||
|
};
|
||||||
|
QString ViewDragDrapCommon::type_sign = "custom/drag-drop-view";
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ViewDragDrapCommon)
|
||||||
|
QDataStream &operator<<(QDataStream &out, const ViewDragDrapCommon &myObj) {
|
||||||
|
out << myObj.target;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
QDataStream &operator>>(QDataStream &in, ViewDragDrapCommon &myObj) {
|
||||||
|
qint64 handle;
|
||||||
|
in >> handle;
|
||||||
|
myObj.target = (BaseView *)handle;
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseView::BaseView(const QString &title, QWidget *view, bool empty, QWidget *parent) : QWidget(parent), title_header(nullptr), parent_store(nullptr) {
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
|
||||||
|
if (!empty) {
|
||||||
|
title_header = new DragHeader(this);
|
||||||
|
title_header->setText(title);
|
||||||
|
title_header->setMaximumHeight(22);
|
||||||
|
|
||||||
|
layout->addWidget(title_header, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->addWidget(view, 1);
|
||||||
|
setMouseTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseView::setTitle(const QString &title) {
|
||||||
|
QWidget::setWindowTitle(title);
|
||||||
|
title_header->setText(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BaseView::title() const { return this->title_header->text(); }
|
||||||
|
|
||||||
|
void BaseView::setIcon(const QIcon &icon) { this->title_header->setIcon(icon); }
|
||||||
|
|
||||||
|
QIcon BaseView::viewIcon() const { return title_header->icon(); }
|
||||||
|
|
||||||
|
void BaseView::registComp(QWidget *child) {
|
||||||
|
if (this->comps_list.contains(child))
|
||||||
|
return;
|
||||||
|
comps_list << child;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewPresent *BaseView::viewPanel() const {
|
||||||
|
const SplitRect *tnode = this;
|
||||||
|
while (!tnode->parentRect()) {
|
||||||
|
tnode = tnode->parentRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<ViewPresent *>(const_cast<SplitRect *>(tnode));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseView::closeView() {}
|
||||||
|
|
||||||
|
QWidget *BaseView::bind() const { return const_cast<BaseView *>(this); }
|
||||||
|
|
||||||
|
SplitRect *BaseView::parentRect() const { return parent_store; }
|
||||||
|
|
||||||
|
void BaseView::setParentRect(SplitRect *pinst) {
|
||||||
|
if (pinst) {
|
||||||
|
auto conv = pinst->bind();
|
||||||
|
setParent(conv);
|
||||||
|
} else
|
||||||
|
setParent(nullptr);
|
||||||
|
|
||||||
|
this->parent_store = pinst;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<SplitRect *, SplitRect *> BaseView::child() const { return std::make_pair<SplitRect *, SplitRect *>(nullptr, nullptr); }
|
||||||
|
|
||||||
|
void BaseView::replace(SplitRect *view, SplitRect *old) { throw new SimpleException<QString>("异常调用", "不能对ViewBase调用replace函数"); }
|
||||||
|
|
||||||
|
float BaseView::splitterWidth() const { return 0; }
|
||||||
|
|
||||||
|
float BaseView::splitterPos() const { return 0; }
|
||||||
|
|
||||||
|
SplitType BaseView::splitType() const { return SplitType::SPLIT_H; }
|
||||||
|
|
||||||
|
void BaseView::setSplitInfo(SplitType type, float pos, float width, bool relayout) {
|
||||||
|
throw new SimpleException<QString>("异常调用", "不能对ViewBase调用setSplitInfo函数");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF BaseView::outline() const { return this->rect(); }
|
||||||
|
|
||||||
|
void BaseView::relayout(const QRectF &outline) { this->setGeometry(outline.toRect()); }
|
||||||
|
|
||||||
|
void BaseView::insertPerceptionHandle(ViewPresent *obj) {
|
||||||
|
for (auto &it : comps_list) {
|
||||||
|
it->removeEventFilter(obj);
|
||||||
|
it->installEventFilter(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseView::paintEvent(QPaintEvent *ev) { QWidget::paintEvent(ev); }
|
||||||
|
|
||||||
|
void BaseView::retrieveComp(SplitRect *child_inst) { throw new SimpleException<QString>("非法操作", "BaseView不支持retrieveComp操作"); }
|
||||||
|
|
||||||
|
DockPanel::DockPanel(ViewPresent *host) : QWidget(host->bind()), size_host(host) { setWindowOpacity(50); }
|
||||||
|
|
||||||
|
void DockPanel::bind(BaseView *widget) { this->current_target = widget; }
|
||||||
|
|
||||||
|
BaseView *DockPanel::target() const { return this->current_target; }
|
||||||
|
|
||||||
|
void DockPanel::paintEvent(QPaintEvent *event) {
|
||||||
|
QWidget::paintEvent(event);
|
||||||
|
|
||||||
|
QPainter p(this);
|
||||||
|
p.setBrush(Qt::lightGray);
|
||||||
|
p.fillRect(this->rect(), Qt::lightGray);
|
||||||
|
|
||||||
|
auto rect = this->rect();
|
||||||
|
p.setPen(QPen(Qt::black, 4));
|
||||||
|
switch (active_comp) {
|
||||||
|
case ActiveArea::LEFT:
|
||||||
|
p.fillRect(QRectF(rect.topLeft(), QSizeF(rect.width() / 2, rect.height())), Qt::gray);
|
||||||
|
break;
|
||||||
|
case ActiveArea::RIGHT:
|
||||||
|
p.fillRect(QRectF(rect.center() - QPointF(0, rect.height() / 2), QSizeF(rect.width() / 2, rect.height())), Qt::gray);
|
||||||
|
break;
|
||||||
|
case ActiveArea::TOP:
|
||||||
|
p.fillRect(QRectF(rect.topLeft(), QSizeF(rect.width(), rect.height() / 2)), Qt::gray);
|
||||||
|
break;
|
||||||
|
case ActiveArea::BOTTOM:
|
||||||
|
p.fillRect(QRectF(rect.center() - QPointF(rect.width() / 2, 0), QSizeF(rect.width(), rect.height() / 2)), Qt::gray);
|
||||||
|
break;
|
||||||
|
case ActiveArea::CENTER:
|
||||||
|
p.fillRect(rect, Qt::gray);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setBrush(Qt::transparent);
|
||||||
|
|
||||||
|
auto lt0 = rect.center() - QPoint(50, 150);
|
||||||
|
p.drawRoundRect(QRectF(lt0, QSizeF(100, 300)));
|
||||||
|
|
||||||
|
auto lt1 = rect.center() - QPoint(150, 50);
|
||||||
|
p.drawRoundRect(QRectF(lt1, QSizeF(300, 100)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockPanel::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
auto tuple_list = view_rects();
|
||||||
|
if (std::get<0>(tuple_list).contains(event->pos())) {
|
||||||
|
this->active_comp = ActiveArea::LEFT;
|
||||||
|
} else if (std::get<1>(tuple_list).contains(event->pos())) {
|
||||||
|
this->active_comp = ActiveArea::RIGHT;
|
||||||
|
|
||||||
|
} else if (std::get<2>(tuple_list).contains(event->pos())) {
|
||||||
|
this->active_comp = ActiveArea::TOP;
|
||||||
|
|
||||||
|
} else if (std::get<3>(tuple_list).contains(event->pos())) {
|
||||||
|
this->active_comp = ActiveArea::BOTTOM;
|
||||||
|
|
||||||
|
} else if (std::get<4>(tuple_list).contains(event->pos())) {
|
||||||
|
this->active_comp = ActiveArea::CENTER;
|
||||||
|
} else {
|
||||||
|
this->active_comp = ActiveArea::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> DockPanel::view_rects() const {
|
||||||
|
auto rect = this->rect();
|
||||||
|
auto lt0 = rect.center() - QPoint(50, 150);
|
||||||
|
auto lt1 = rect.center() - QPoint(150, 50);
|
||||||
|
|
||||||
|
return std::make_tuple(QRectF(lt1, QSizeF(100, 100)), QRectF(lt1 + QPoint(200, 0), QSizeF(100, 100)), QRectF(lt0, QSizeF(100, 100)),
|
||||||
|
QRectF(lt0 + QPointF(0, 200), QSizeF(100, 100)), QRectF(lt1 + QPointF(100, 0), QSizeF(100, 100)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewPresent::ViewPresent(SplitRect *initial_view, QWidget *parent) : QWidget(parent), accept_panel(new DockPanel(this)) {
|
||||||
|
accept_panel->hide();
|
||||||
|
|
||||||
|
this->split_info_store = std::make_tuple(SplitType::SPLIT_H, 100, 7, 1);
|
||||||
|
initial_view->setParentRect(this);
|
||||||
|
setMouseTracking(true);
|
||||||
|
view_anchors << initial_view;
|
||||||
|
|
||||||
|
qRegisterMetaTypeStreamOperators<ViewDragDrapCommon>("ViewDragDrapCommon");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::setViewAdjust(bool state) { this->dragdrop_state = state; }
|
||||||
|
|
||||||
|
bool ViewPresent::adjustState() const { return this->dragdrop_state; }
|
||||||
|
|
||||||
|
void ViewPresent::append(SplitRect *inst, uint index) {
|
||||||
|
auto pos = splitterPos();
|
||||||
|
auto width = splitterWidth();
|
||||||
|
auto idx = index ? 1 : 0;
|
||||||
|
auto type = splitType();
|
||||||
|
|
||||||
|
if (view_anchors.size() == 2) {
|
||||||
|
view_anchors[idx]->setParentRect(nullptr);
|
||||||
|
view_anchors[idx]->bind()->setVisible(false);
|
||||||
|
view_anchors[idx] = inst;
|
||||||
|
view_anchors[idx]->setParentRect(this);
|
||||||
|
view_anchors[idx]->bind()->setVisible(true);
|
||||||
|
} else if (view_anchors.size() == 1) {
|
||||||
|
view_anchors.insert(idx, inst);
|
||||||
|
view_anchors[idx] = inst;
|
||||||
|
view_anchors[idx]->setParentRect(this);
|
||||||
|
view_anchors[idx]->bind()->setVisible(true);
|
||||||
|
} else {
|
||||||
|
view_anchors << inst;
|
||||||
|
view_anchors.last()->setParentRect(this);
|
||||||
|
view_anchors.last()->bind()->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->split_info_store = std::make_tuple(type, pos, width, idx);
|
||||||
|
this->relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
|
||||||
|
if (adjustState()) {
|
||||||
|
qDebug() << "adjust-move";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *ViewPresent::bind() const { return const_cast<ViewPresent *>(this); }
|
||||||
|
|
||||||
|
SplitRect *ViewPresent::parentRect() const { return nullptr; }
|
||||||
|
|
||||||
|
void ViewPresent::setParentRect(SplitRect *pinst) { throw new SimpleException<QString>("非法操作", "不允许对ViewPresent调用setParentRect!"); }
|
||||||
|
|
||||||
|
std::pair<SplitRect *, SplitRect *> ViewPresent::child() const {
|
||||||
|
SplitRect *inst0 = nullptr, *inst1 = nullptr;
|
||||||
|
if (view_anchors.size() > 1)
|
||||||
|
inst1 = view_anchors[1];
|
||||||
|
if (view_anchors.size() > 0)
|
||||||
|
inst0 = view_anchors[0];
|
||||||
|
|
||||||
|
return std::make_pair(inst0, inst1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::replace(SplitRect *view, SplitRect *old) {
|
||||||
|
if (!view_anchors.contains(old))
|
||||||
|
throw new SimpleException<QString>("参数错误", "指定替换的界面不属于此界面");
|
||||||
|
|
||||||
|
if (view_anchors.contains(view))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (old) {
|
||||||
|
old->bind()->setVisible(false);
|
||||||
|
old->setParentRect(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_anchors.replace(view_anchors.indexOf(old), view);
|
||||||
|
if (view) {
|
||||||
|
view->setParentRect(this);
|
||||||
|
view->bind()->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
float ViewPresent::splitterWidth() const { return std::get<2>(split_info_store); }
|
||||||
|
|
||||||
|
float ViewPresent::splitterPos() const { return std::get<1>(split_info_store); }
|
||||||
|
|
||||||
|
SplitType ViewPresent::splitType() const { return std::get<0>(split_info_store); }
|
||||||
|
|
||||||
|
void ViewPresent::setSplitInfo(SplitType type, float pos, float width, bool relayout) {
|
||||||
|
this->split_info_store = std::make_tuple(type, pos, width, std::get<3>(split_info_store));
|
||||||
|
if (relayout)
|
||||||
|
this->relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF ViewPresent::outline() const { return this->rect(); }
|
||||||
|
|
||||||
|
void ViewPresent::relayout(const QRectF &outline) { setGeometry(outline.toRect()); }
|
||||||
|
|
||||||
|
void ViewPresent::paintEvent(QPaintEvent *ev) {
|
||||||
|
QWidget::paintEvent(ev);
|
||||||
|
|
||||||
|
if (view_anchors.size() == 2) {
|
||||||
|
QPainter p(this);
|
||||||
|
auto handle_rect = handleRect();
|
||||||
|
p.fillRect(handle_rect, QBrush(Qt::gray));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &it : view_anchors)
|
||||||
|
it->bind()->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::retrieveComp(SplitRect *child_inst) {
|
||||||
|
if (!view_anchors.contains(child_inst))
|
||||||
|
throw new SimpleException<QString>("参数非法", "回收的指定视图不属于本ViewPresent");
|
||||||
|
|
||||||
|
if (child_inst)
|
||||||
|
child_inst->bind()->setVisible(false);
|
||||||
|
|
||||||
|
view_anchors.removeAll(child_inst);
|
||||||
|
relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::resizeEvent(QResizeEvent *ev) {
|
||||||
|
QWidget::resizeEvent(ev);
|
||||||
|
relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::mousePressEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mousePressEvent(event);
|
||||||
|
|
||||||
|
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
if (handleRect().contains(event->pos()))
|
||||||
|
this->press_flags = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::mouseReleaseEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mouseReleaseEvent(event);
|
||||||
|
|
||||||
|
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
this->press_flags = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mouseMoveEvent(event);
|
||||||
|
|
||||||
|
auto drag_rect = handleRect();
|
||||||
|
if (drag_rect.contains(event->pos())) {
|
||||||
|
if (splitType() == SplitType::SPLIT_H)
|
||||||
|
setCursor(QCursor(Qt::CursorShape::SplitHCursor));
|
||||||
|
else
|
||||||
|
setCursor(QCursor(Qt::CursorShape::SplitVCursor));
|
||||||
|
} else {
|
||||||
|
setCursor(QCursor(Qt::CursorShape::ArrowCursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->press_flags) {
|
||||||
|
auto pos = this->mapFromGlobal(event->globalPos());
|
||||||
|
auto split_margin = splitterWidth();
|
||||||
|
if (std::get<0>(split_info_store) == SplitType::SPLIT_H) {
|
||||||
|
setSplitInfo(splitType(), pos.x() - split_margin / 2, split_margin, true);
|
||||||
|
} else {
|
||||||
|
setSplitInfo(splitType(), pos.y() - split_margin / 2, split_margin, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewPresent::relayout() {
|
||||||
|
auto rects = viewRects();
|
||||||
|
|
||||||
|
if (view_anchors.size() == 2) {
|
||||||
|
view_anchors[0]->relayout(rects.first.toRect());
|
||||||
|
view_anchors[1]->relayout(rects.second.toRect());
|
||||||
|
} else if (view_anchors.size() == 1) {
|
||||||
|
view_anchors[0]->relayout(this->rect());
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QRectF, QRectF> ViewPresent::viewRects() {
|
||||||
|
auto xrect = this->rect();
|
||||||
|
|
||||||
|
auto type = (int)splitType();
|
||||||
|
if (!type) {
|
||||||
|
auto width0 = splitterPos();
|
||||||
|
if (width0 + splitterWidth() > xrect.width())
|
||||||
|
width0 = xrect.width() - splitterWidth();
|
||||||
|
if (width0 < 0)
|
||||||
|
width0 = 0;
|
||||||
|
|
||||||
|
setSplitInfo(splitType(), width0, splitterWidth(), false);
|
||||||
|
|
||||||
|
auto rect0 = QRectF(xrect.topLeft(), QSizeF(width0, xrect.height()));
|
||||||
|
auto rect1 = QRectF(xrect.topLeft() + QPointF(rect0.width() + splitterWidth(), 0),
|
||||||
|
QSizeF(xrect.width() - rect0.width() - splitterWidth(), xrect.height()));
|
||||||
|
return std::make_pair(rect0, rect1);
|
||||||
|
} else {
|
||||||
|
auto height0 = splitterPos();
|
||||||
|
if (height0 + splitterWidth() > xrect.height())
|
||||||
|
height0 = xrect.height() - splitterWidth();
|
||||||
|
if (height0 < 0)
|
||||||
|
height0 = 0;
|
||||||
|
|
||||||
|
setSplitInfo(splitType(), height0, splitterWidth(), false);
|
||||||
|
|
||||||
|
auto rect0 = QRectF(xrect.topLeft(), QSizeF(xrect.width(), height0));
|
||||||
|
auto rect1 = QRectF(xrect.topLeft() + QPointF(0, rect0.height() + splitterWidth()),
|
||||||
|
QSizeF(xrect.width(), xrect.height() - splitterWidth() - rect0.height()));
|
||||||
|
return std::make_pair(rect0, rect1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF ViewPresent::handleRect() const {
|
||||||
|
QRectF rect;
|
||||||
|
|
||||||
|
auto width_middle = splitterWidth() - 2;
|
||||||
|
if (splitType() == SplitType::SPLIT_H) {
|
||||||
|
rect = QRectF(splitterPos() + 1, 0, width_middle, outline().height());
|
||||||
|
} else {
|
||||||
|
rect = QRectF(0, splitterPos() + 1, outline().width(), width_middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
SplitView::SplitView(SplitRect *first, SplitRect *next, QWidget *parent) : QWidget(parent) {
|
||||||
|
this->split_info_value = std::make_tuple(SplitType::SPLIT_H, 100, 7);
|
||||||
|
this->child_store << first;
|
||||||
|
this->child_store << next;
|
||||||
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
first->setParentRect(this);
|
||||||
|
next->setParentRect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *SplitView::bind() const { return const_cast<SplitView *>(this); }
|
||||||
|
|
||||||
|
SplitRect *SplitView::parentRect() const { return parent_inst; }
|
||||||
|
|
||||||
|
void SplitView::setParentRect(SplitRect *pinst) {
|
||||||
|
if (pinst) {
|
||||||
|
auto pwidget = pinst->bind();
|
||||||
|
this->setParent(pwidget);
|
||||||
|
} else
|
||||||
|
this->setParent(nullptr);
|
||||||
|
|
||||||
|
this->parent_inst = pinst;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<SplitRect *, SplitRect *> SplitView::child() const { return std::make_pair(child_store[0], child_store[1]); }
|
||||||
|
|
||||||
|
float SplitView::splitterWidth() const { return std::get<2>(split_info_value); }
|
||||||
|
|
||||||
|
float SplitView::splitterPos() const { return std::get<1>(split_info_value); }
|
||||||
|
|
||||||
|
SplitType SplitView::splitType() const { return std::get<0>(split_info_value); }
|
||||||
|
|
||||||
|
void SplitView::setSplitInfo(SplitType type, float pos, float width, bool relayout) {
|
||||||
|
this->split_info_value = std::make_tuple(type, pos, width);
|
||||||
|
if (relayout)
|
||||||
|
this->relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::replace(SplitRect *view, SplitRect *old) {
|
||||||
|
if (child_store.contains(old) && !child_store.contains(view)) {
|
||||||
|
auto index = child_store.indexOf(old);
|
||||||
|
child_store.replace(index, view);
|
||||||
|
|
||||||
|
old->setParentRect(nullptr);
|
||||||
|
view->setParentRect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF SplitView::outline() const { return this->rect(); }
|
||||||
|
|
||||||
|
void SplitView::relayout(const QRectF &outlinex) {
|
||||||
|
this->setGeometry(outlinex.toRect());
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::retrieveComp(SplitRect *child_inst) {
|
||||||
|
auto pinst = parentRect();
|
||||||
|
|
||||||
|
auto sib = this->child().first;
|
||||||
|
if (child_inst == sib)
|
||||||
|
sib = this->child().second;
|
||||||
|
|
||||||
|
child_inst->bind()->setVisible(false);
|
||||||
|
pinst->replace(sib, this);
|
||||||
|
|
||||||
|
child_inst->setParentRect(nullptr);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::paintEvent(QPaintEvent *ev) {
|
||||||
|
QWidget::paintEvent(ev);
|
||||||
|
|
||||||
|
QPainter p(this);
|
||||||
|
QRectF rect = handleRect();
|
||||||
|
p.fillRect(rect, QBrush(Qt::gray, Qt::BrushStyle::SolidPattern));
|
||||||
|
|
||||||
|
for (auto &it : child_store)
|
||||||
|
it->bind()->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::resizeEvent(QResizeEvent *ev) {
|
||||||
|
QWidget::resizeEvent(ev);
|
||||||
|
relayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::mousePressEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mousePressEvent(event);
|
||||||
|
|
||||||
|
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
if (handleRect().contains(event->pos()))
|
||||||
|
this->press_flags = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::mouseReleaseEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mouseReleaseEvent(event);
|
||||||
|
|
||||||
|
if (event->button() == Qt::MouseButton::LeftButton) {
|
||||||
|
this->press_flags = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
QWidget::mouseMoveEvent(event);
|
||||||
|
|
||||||
|
auto drag_rect = handleRect() + QMargins(2, 2, 2, 2);
|
||||||
|
if (drag_rect.contains(event->pos())) {
|
||||||
|
if (splitType() == SplitType::SPLIT_H)
|
||||||
|
setCursor(QCursor(Qt::CursorShape::SplitHCursor));
|
||||||
|
else
|
||||||
|
setCursor(QCursor(Qt::CursorShape::SplitVCursor));
|
||||||
|
|
||||||
|
drags_flag = true;
|
||||||
|
} else {
|
||||||
|
setCursor(QCursor(Qt::CursorShape::ArrowCursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->press_flags) {
|
||||||
|
auto pos = this->mapFromGlobal(event->globalPos());
|
||||||
|
auto split_margin = splitterWidth();
|
||||||
|
if (std::get<0>(split_info_value) == SplitType::SPLIT_H) {
|
||||||
|
setSplitInfo(splitType(), pos.x() - split_margin / 2, split_margin, true);
|
||||||
|
} else {
|
||||||
|
setSplitInfo(splitType(), pos.y() - split_margin / 2, split_margin, true);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SplitView::eventFilter(QObject *watched, QEvent *event) {
|
||||||
|
if (watched != this && this->drags_flag && event->type() == QEvent::MouseMove) {
|
||||||
|
auto x = static_cast<QMouseEvent *>(event);
|
||||||
|
auto pos = mapFromGlobal(x->globalPos());
|
||||||
|
if (!handleRect().contains(pos)) {
|
||||||
|
setCursor(QCursor(Qt::CursorShape::ArrowCursor));
|
||||||
|
this->drags_flag = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SplitView::relayout() {
|
||||||
|
auto rects = viewRects();
|
||||||
|
auto pair = child();
|
||||||
|
|
||||||
|
auto awidget = dynamic_cast<QWidget *>(pair.first);
|
||||||
|
auto bwidget = dynamic_cast<QWidget *>(pair.second);
|
||||||
|
if (!awidget->isVisible())
|
||||||
|
awidget->setVisible(true);
|
||||||
|
if (!bwidget->isVisible())
|
||||||
|
bwidget->setVisible(true);
|
||||||
|
|
||||||
|
pair.first->relayout(std::get<0>(rects));
|
||||||
|
pair.second->relayout(std::get<1>(rects));
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<QRectF, QRectF> SplitView::viewRects() {
|
||||||
|
auto xrect = this->rect();
|
||||||
|
|
||||||
|
auto type = (int)splitType();
|
||||||
|
if (!type) {
|
||||||
|
auto width0 = splitterPos();
|
||||||
|
if (width0 + splitterWidth() > xrect.width())
|
||||||
|
width0 = xrect.width() - splitterWidth();
|
||||||
|
if (width0 < 0)
|
||||||
|
width0 = 0;
|
||||||
|
|
||||||
|
setSplitInfo(splitType(), width0, splitterWidth(), false);
|
||||||
|
|
||||||
|
auto rect0 = QRectF(xrect.topLeft(), QSizeF(width0, xrect.height()));
|
||||||
|
auto rect1 = QRectF(xrect.topLeft() + QPointF(rect0.width() + splitterWidth(), 0),
|
||||||
|
QSizeF(xrect.width() - rect0.width() - splitterWidth(), xrect.height()));
|
||||||
|
return std::make_pair(rect0, rect1);
|
||||||
|
} else {
|
||||||
|
auto height0 = splitterPos();
|
||||||
|
if (height0 + splitterWidth() > xrect.height())
|
||||||
|
height0 = xrect.height() - splitterWidth();
|
||||||
|
if (height0 < 0)
|
||||||
|
height0 = 0;
|
||||||
|
|
||||||
|
setSplitInfo(splitType(), height0, splitterWidth(), false);
|
||||||
|
|
||||||
|
auto rect0 = QRectF(xrect.topLeft(), QSizeF(xrect.width(), height0));
|
||||||
|
auto rect1 = QRectF(xrect.topLeft() + QPointF(0, rect0.height() + splitterWidth()),
|
||||||
|
QSizeF(xrect.width(), xrect.height() - splitterWidth() - rect0.height()));
|
||||||
|
return std::make_pair(rect0, rect1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF SplitView::handleRect() const {
|
||||||
|
QRectF rect;
|
||||||
|
|
||||||
|
auto width_middle = splitterWidth() - 2;
|
||||||
|
if (splitType() == SplitType::SPLIT_H) {
|
||||||
|
rect = QRectF(splitterPos() + 1, 0, width_middle, outline().height());
|
||||||
|
} else {
|
||||||
|
rect = QRectF(0, splitterPos() + 1, outline().width(), width_middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
DragHeader::DragHeader(BaseView *bind) : QFrame(bind->bind()), icon_store(new QLabel(this)), title_store(new QLabel(this)), view_core(bind) {
|
||||||
|
setFrameShadow(QFrame::Shadow::Raised);
|
||||||
|
setFrameShape(QFrame::Shape::Box);
|
||||||
|
setStyleSheet("background-color: rgb(200, 200, 255);");
|
||||||
|
|
||||||
|
auto layout = new QHBoxLayout(this);
|
||||||
|
layout->setMargin(1);
|
||||||
|
layout->setSpacing(2);
|
||||||
|
layout->addWidget(icon_store, 0);
|
||||||
|
layout->addWidget(title_store, 1);
|
||||||
|
|
||||||
|
auto hide = new QPushButton("-", this);
|
||||||
|
layout->addWidget(hide, 0);
|
||||||
|
hide->setMaximumSize(20, 20);
|
||||||
|
auto close = new QPushButton("X", this);
|
||||||
|
layout->addWidget(close, 0);
|
||||||
|
close->setMaximumSize(20, 20);
|
||||||
|
|
||||||
|
connect(hide, &QPushButton::clicked, [=]() {
|
||||||
|
auto con = this->view_core->parentRect();
|
||||||
|
con->retrieveComp(view_core);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(close, &QPushButton::clicked, [=]() {
|
||||||
|
hide->click();
|
||||||
|
view_core->closeView();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DragHeader::setIcon(const QIcon &icon) {
|
||||||
|
icon_inst = icon;
|
||||||
|
auto len = this->height() - 2;
|
||||||
|
this->icon_store->setPixmap(icon.pixmap(QSize(len, len)));
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon DragHeader::icon() const { return this->icon_inst; }
|
||||||
|
|
||||||
|
void DragHeader::setText(const QString &title) { this->title_store->setText(title); }
|
||||||
|
|
||||||
|
QString DragHeader::text() const { return title_store->text(); }
|
||||||
|
|
||||||
|
void DragHeader::mousePressEvent(QMouseEvent *event) {
|
||||||
|
if (event->button() == Qt::LeftButton && !std::get<0>(press_flag)) {
|
||||||
|
this->press_flag = std::make_tuple(true, event->pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DragHeader::mouseReleaseEvent(QMouseEvent *event) {
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
this->press_flag = std::make_tuple(false, QPointF());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DragHeader::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
if (std::get<0>(press_flag) && QLineF(std::get<1>(press_flag), event->pos()).length() > QApplication::startDragDistance()) {
|
||||||
|
view_core->viewPanel()->setViewAdjust(true);
|
||||||
|
|
||||||
|
QDrag *drag = new QDrag(this);
|
||||||
|
auto pix = view_core->grab();
|
||||||
|
drag->setPixmap(pix);
|
||||||
|
drag->setHotSpot(QPoint(20, 20));
|
||||||
|
|
||||||
|
QMimeData *mimeData = new QMimeData;
|
||||||
|
|
||||||
|
ViewDragDrapCommon wrap(view_core);
|
||||||
|
QByteArray buff;
|
||||||
|
QDataStream out(&buff, QIODevice::WriteOnly);
|
||||||
|
out << wrap;
|
||||||
|
|
||||||
|
mimeData->setData(ViewDragDrapCommon::type_sign, buff);
|
||||||
|
drag->setMimeData(mimeData);
|
||||||
|
|
||||||
|
drag->exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,236 @@
|
||||||
|
#ifndef SPLITVIEW_H
|
||||||
|
#define SPLITVIEW_H
|
||||||
|
|
||||||
|
#include "SplitView_global.h"
|
||||||
|
#include <QHash>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace SplitFrame {
|
||||||
|
class SplitRect;
|
||||||
|
class ViewPresent;
|
||||||
|
class BaseView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 承接堆放操作及设定摆放位置
|
||||||
|
*/
|
||||||
|
class SPLITVIEW_EXPORT DockPanel : public QWidget {
|
||||||
|
enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE };
|
||||||
|
|
||||||
|
public:
|
||||||
|
DockPanel(ViewPresent *host);
|
||||||
|
|
||||||
|
void bind(BaseView *widget);
|
||||||
|
BaseView *target() const;
|
||||||
|
|
||||||
|
virtual void paintEvent(QPaintEvent *event) override;
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ViewPresent *const size_host;
|
||||||
|
BaseView *current_target;
|
||||||
|
ActiveArea active_comp;
|
||||||
|
|
||||||
|
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> view_rects() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SplitType { SPLIT_H = 0, SPLIT_V = 1 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 分裂视图规划和约束组件
|
||||||
|
*/
|
||||||
|
class SplitRect {
|
||||||
|
public:
|
||||||
|
virtual ~SplitRect() = default;
|
||||||
|
|
||||||
|
virtual QWidget *bind() const = 0;
|
||||||
|
|
||||||
|
virtual SplitRect *parentRect() const = 0;
|
||||||
|
virtual void setParentRect(SplitRect *pinst) = 0;
|
||||||
|
|
||||||
|
virtual std::pair<SplitRect *, SplitRect *> child() const = 0;
|
||||||
|
virtual void replace(SplitRect *view, SplitRect *old) = 0;
|
||||||
|
virtual float splitterWidth() const = 0;
|
||||||
|
virtual float splitterPos() const = 0;
|
||||||
|
virtual SplitType splitType() const = 0;
|
||||||
|
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout = true) = 0;
|
||||||
|
|
||||||
|
virtual QRectF outline() const = 0;
|
||||||
|
virtual void relayout(const QRectF &outline) = 0;
|
||||||
|
virtual void retrieveComp(SplitRect *child) = 0;
|
||||||
|
|
||||||
|
virtual void paintEvent(QPaintEvent *ev) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SPLITVIEW_EXPORT SplitView : public QWidget, public SplitRect {
|
||||||
|
|
||||||
|
public:
|
||||||
|
SplitView(SplitRect *first, SplitRect *next, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
// SplitRect interface
|
||||||
|
public:
|
||||||
|
virtual QWidget *bind() const override;
|
||||||
|
virtual SplitRect *parentRect() const override;
|
||||||
|
virtual void setParentRect(SplitRect *pinst) override;
|
||||||
|
|
||||||
|
virtual std::pair<SplitRect *, SplitRect *> child() const override;
|
||||||
|
virtual float splitterWidth() const override;
|
||||||
|
virtual float splitterPos() const override;
|
||||||
|
virtual SplitType splitType() const override;
|
||||||
|
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override;
|
||||||
|
virtual void replace(SplitRect *view, SplitRect *old) override;
|
||||||
|
|
||||||
|
virtual QRectF outline() const override;
|
||||||
|
virtual void relayout(const QRectF &outline) override;
|
||||||
|
virtual void retrieveComp(SplitRect *child_inst) override;
|
||||||
|
|
||||||
|
// QWidget interface
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *ev) override;
|
||||||
|
virtual void resizeEvent(QResizeEvent *ev) override;
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
|
||||||
|
// QObject interface
|
||||||
|
public:
|
||||||
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SplitRect *parent_inst;
|
||||||
|
QList<SplitRect *> child_store;
|
||||||
|
// type, pos, width
|
||||||
|
std::tuple<SplitType, float, float> split_info_value;
|
||||||
|
bool press_flags = false, drags_flag = false;
|
||||||
|
|
||||||
|
virtual void relayout();
|
||||||
|
std::pair<QRectF, QRectF> viewRects();
|
||||||
|
QRectF handleRect() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DragHeader : public QFrame {
|
||||||
|
public:
|
||||||
|
DragHeader(BaseView *bind);
|
||||||
|
|
||||||
|
void setIcon(const QIcon &icon);
|
||||||
|
QIcon icon() const;
|
||||||
|
void setText(const QString &title);
|
||||||
|
QString text() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QIcon icon_inst;
|
||||||
|
QLabel *const icon_store, *const title_store;
|
||||||
|
BaseView *const view_core;
|
||||||
|
std::tuple<bool, QPointF> press_flag = std::make_tuple(false, QPointF());
|
||||||
|
|
||||||
|
// QWidget interface
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 基础内容视图组件
|
||||||
|
*/
|
||||||
|
class SPLITVIEW_EXPORT BaseView : public QWidget, public SplitRect {
|
||||||
|
public:
|
||||||
|
BaseView(const QString &title, QWidget *view, bool empty = false, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
virtual void setTitle(const QString &title);
|
||||||
|
virtual QString title() const;
|
||||||
|
|
||||||
|
virtual void setIcon(const QIcon &icon);
|
||||||
|
virtual QIcon viewIcon() const;
|
||||||
|
|
||||||
|
ViewPresent *viewPanel() const;
|
||||||
|
virtual void closeView();
|
||||||
|
|
||||||
|
// SplitRect interface
|
||||||
|
public:
|
||||||
|
virtual QWidget *bind() const override;
|
||||||
|
virtual SplitRect *parentRect() const override;
|
||||||
|
virtual void setParentRect(SplitRect *pinst) override;
|
||||||
|
virtual std::pair<SplitRect *, SplitRect *> child() const override;
|
||||||
|
virtual void replace(SplitRect *view, SplitRect *old) override;
|
||||||
|
virtual float splitterWidth() const override;
|
||||||
|
virtual float splitterPos() const override;
|
||||||
|
virtual SplitType splitType() const override;
|
||||||
|
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override;
|
||||||
|
virtual QRectF outline() const override;
|
||||||
|
virtual void relayout(const QRectF &outline) override;
|
||||||
|
|
||||||
|
virtual void insertPerceptionHandle(ViewPresent *obj);
|
||||||
|
virtual void paintEvent(QPaintEvent *ev) override;
|
||||||
|
virtual void retrieveComp(SplitRect *child_inst) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DragHeader *title_header;
|
||||||
|
SplitRect *parent_store;
|
||||||
|
QList<QWidget *> comps_list;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void registComp(QWidget *child);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 分裂视图呈现组件
|
||||||
|
*/
|
||||||
|
class SPLITVIEW_EXPORT ViewPresent : public QWidget, public SplitRect {
|
||||||
|
public:
|
||||||
|
ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 切换视图调整状态
|
||||||
|
* @param state 状态开关
|
||||||
|
*/
|
||||||
|
void setViewAdjust(bool state);
|
||||||
|
bool adjustState() const;
|
||||||
|
|
||||||
|
void append(SplitRect *inst, uint index);
|
||||||
|
|
||||||
|
// QObject interface
|
||||||
|
public:
|
||||||
|
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||||
|
|
||||||
|
// SplitRect interface
|
||||||
|
public:
|
||||||
|
virtual QWidget *bind() const override;
|
||||||
|
virtual SplitRect *parentRect() const override;
|
||||||
|
virtual void setParentRect(SplitRect *pinst) override;
|
||||||
|
|
||||||
|
virtual std::pair<SplitRect *, SplitRect *> child() const override;
|
||||||
|
virtual void replace(SplitRect *view, SplitRect *old) override;
|
||||||
|
virtual float splitterWidth() const override;
|
||||||
|
virtual float splitterPos() const override;
|
||||||
|
virtual SplitType splitType() const override;
|
||||||
|
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override;
|
||||||
|
virtual QRectF outline() const override;
|
||||||
|
virtual void relayout(const QRectF &outline) override;
|
||||||
|
virtual void retrieveComp(SplitRect *child_inst) override;
|
||||||
|
|
||||||
|
// QWidget interface
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *ev) override;
|
||||||
|
virtual void resizeEvent(QResizeEvent *ev) override;
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DockPanel *const accept_panel;
|
||||||
|
bool press_flags = false;
|
||||||
|
bool dragdrop_state = false;
|
||||||
|
QList<SplitRect *> view_anchors;
|
||||||
|
// 方向,splitter位置,splitter宽度,extend索引
|
||||||
|
std::tuple<SplitType, float, float, uint> split_info_store;
|
||||||
|
|
||||||
|
virtual void relayout();
|
||||||
|
std::pair<QRectF, QRectF> viewRects();
|
||||||
|
QRectF handleRect() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SplitFrame
|
||||||
|
|
||||||
|
#endif // SPLITVIEW_H
|
||||||
|
|
@ -12,11 +12,3 @@
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace Components;
|
using namespace Components;
|
||||||
using namespace MakeTools;
|
using namespace MakeTools;
|
||||||
|
|
||||||
|
|
||||||
SimpleException::SimpleException(const QString &msg)
|
|
||||||
: msg_store(msg) {}
|
|
||||||
|
|
||||||
const char *SimpleException::what() const{
|
|
||||||
return msg_store.toLocal8Bit();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,6 @@
|
||||||
#include <libConfig.h>
|
#include <libConfig.h>
|
||||||
#include <libProjectManager.h>
|
#include <libProjectManager.h>
|
||||||
|
|
||||||
class SimpleException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SimpleException(const QString &msg);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString msg_store;
|
|
||||||
|
|
||||||
// exception interface
|
|
||||||
public:
|
|
||||||
virtual const char *what() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
enum class Scale
|
enum class Scale
|
||||||
|
|
|
||||||
|
|
@ -53,24 +53,22 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
setMinimumSize(1000, 600);
|
setMinimumSize(1000, 600);
|
||||||
setWindowTitle("提线木偶");
|
setWindowTitle("提线木偶");
|
||||||
|
|
||||||
project_present->widget()->setVisible(false);
|
|
||||||
errors_present->setVisible(false);
|
|
||||||
|
|
||||||
auto mbar = menuBar();
|
auto mbar = menuBar();
|
||||||
initial_menubar(mbar);
|
initial_menubar(mbar);
|
||||||
|
|
||||||
setCentralWidget(this->split_first);
|
this->split_third->addWidget(this->center_frame->hostWidget());
|
||||||
this->split_first->addWidget(project_present);
|
this->split_third->addWidget(this->messages_frame);
|
||||||
this->split_first->addWidget(this->split_second);
|
|
||||||
|
|
||||||
this->split_second->addWidget(this->split_third);
|
this->split_second->addWidget(this->split_third);
|
||||||
this->split_second->addWidget(this->errors_present);
|
this->split_second->addWidget(this->errors_present);
|
||||||
|
|
||||||
this->split_third->addWidget(this->center_frame->hostWidget());
|
this->split_first->addWidget(project_present);
|
||||||
this->split_third->addWidget(this->messages_frame);
|
this->split_first->addWidget(this->split_second);
|
||||||
this->messages_frame->setTabPosition(QTabWidget::TabPosition::South);
|
|
||||||
|
|
||||||
|
project_present->setVisible(true);
|
||||||
this->active_docscollect->setPresent(this);
|
this->active_docscollect->setPresent(this);
|
||||||
|
setCentralWidget(this->split_first);
|
||||||
|
this->messages_frame->setTabPosition(QTabWidget::TabPosition::South);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {}
|
MainWindow::~MainWindow() {}
|
||||||
|
|
@ -177,12 +175,6 @@ void MainWindow::initial_menubar(QMenuBar *mbar) {
|
||||||
auto func = view->addMenu("功能视图");
|
auto func = view->addMenu("功能视图");
|
||||||
sync_kernel->widgetEnableSync(func, [this]() { return this->project_manager->isOpenning(); });
|
sync_kernel->widgetEnableSync(func, [this]() { return this->project_manager->isOpenning(); });
|
||||||
// 项目管理
|
// 项目管理
|
||||||
{
|
|
||||||
auto project_v = func->addAction("项目管理", [this](bool v) { XApp::disp_core->postCommand(CompVisible(this, project_present, v)); });
|
|
||||||
sync_kernel->actionCheckSync(project_v, [this]() -> bool { return this->project_present->isVisible(); });
|
|
||||||
}
|
|
||||||
func->addAction("引用统计");
|
|
||||||
func->addAction("脉络分蘖");
|
|
||||||
|
|
||||||
// 工具菜单
|
// 工具菜单
|
||||||
auto tool = mbar->addMenu("工具");
|
auto tool = mbar->addMenu("工具");
|
||||||
|
|
@ -222,10 +214,8 @@ void MainWindow::initial_commandlist(Schedule::CommandsDispatcher *host) {
|
||||||
host->registerCommand(new CloseProject());
|
host->registerCommand(new CloseProject());
|
||||||
|
|
||||||
host->registerCommand(new CompVisible(this, welcome_list, true));
|
host->registerCommand(new CompVisible(this, welcome_list, true));
|
||||||
host->registerCommand(new CompVisible(this, errors_present, true));
|
|
||||||
host->registerCommand(new CompVisible(this, project_present, true));
|
|
||||||
|
|
||||||
host->registerCommand(new NewFile(Route(), "", ""));
|
host->registerCommand(new NewFile(Route(), "", "txt"));
|
||||||
host->registerCommand(new NewPackage(""));
|
host->registerCommand(new NewPackage(""));
|
||||||
host->registerCommand(new NewProject(QDir(), ""));
|
host->registerCommand(new NewProject(QDir(), ""));
|
||||||
host->registerCommand(new OpenFile(Route()));
|
host->registerCommand(new OpenFile(Route()));
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
using namespace Components;
|
using namespace Components;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace DataModel;
|
using namespace DataModel;
|
||||||
|
using namespace Config;
|
||||||
|
|
||||||
DocumentsManager::DocumentsManager(Project::ProjectManager *project) : pjtins(project), present_ui(nullptr) { registViewPlugins(); }
|
DocumentsManager::DocumentsManager(Project::ProjectManager *project) : pjtins(project), present_ui(nullptr) { registViewPlugins(); }
|
||||||
|
|
||||||
|
|
@ -31,7 +32,7 @@ void DocumentsManager::createPackage(const Core::Route &link) { pjtins->operateA
|
||||||
void DocumentsManager::createFile(const Core::Route &group_path, const QString &name, const QString &suffix) {
|
void DocumentsManager::createFile(const Core::Route &group_path, const QString &name, const QString &suffix) {
|
||||||
auto all_types = fileTypes();
|
auto all_types = fileTypes();
|
||||||
if (!all_types.contains(suffix))
|
if (!all_types.contains(suffix))
|
||||||
throw new SimpleException("指定文件类型无法打开:" + suffix);
|
throw new SimpleException<QString>("创建文件错误", "指定文件类型无法打开:" + suffix);
|
||||||
|
|
||||||
auto midx = convertPath(group_path);
|
auto midx = convertPath(group_path);
|
||||||
auto fidx = projectManager()->operateAccess()->newFile(midx, name, suffix);
|
auto fidx = projectManager()->operateAccess()->newFile(midx, name, suffix);
|
||||||
|
|
@ -83,7 +84,7 @@ void DocumentsManager::openFile(const QList<Route> &doc_paths) {
|
||||||
|
|
||||||
auto info = pjtins->queryAccess()->queryInfo(convertPath(it));
|
auto info = pjtins->queryAccess()->queryInfo(convertPath(it));
|
||||||
if (!info.isFile())
|
if (!info.isFile())
|
||||||
throw new SimpleException("指向的节点不是文件节点");
|
throw new SimpleException<QString>("打开文件错误", "指向的节点不是文件节点");
|
||||||
|
|
||||||
auto view = factory_map[info.suffix()]->newInst(present_ui->hostWidget());
|
auto view = factory_map[info.suffix()]->newInst(present_ui->hostWidget());
|
||||||
doc_openning[it] = view;
|
doc_openning[it] = view;
|
||||||
|
|
@ -120,7 +121,7 @@ QModelIndex DocumentsManager::convertPath(const Core::Route &path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx == itor_node->parent()->rowCount())
|
if (idx == itor_node->parent()->rowCount())
|
||||||
throw new SimpleException("指定的path非法:/" + path.links().join("/"));
|
throw new SimpleException<QString>("路径转换错误", "指定的path非法:/" + path.links().join("/"));
|
||||||
}
|
}
|
||||||
return itor_node->index();
|
return itor_node->index();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,3 @@
|
||||||
using namespace Components;
|
using namespace Components;
|
||||||
|
|
||||||
MessagesPresent::MessagesPresent(QStandardItemModel *base, QWidget *parent) : QTableView(parent), items_present(base) { setModel(items_present); }
|
MessagesPresent::MessagesPresent(QStandardItemModel *base, QWidget *parent) : QTableView(parent), items_present(base) { setModel(items_present); }
|
||||||
|
|
||||||
QWidget *MessagesPresent::widget() const { return (QWidget *)this; }
|
|
||||||
|
|
||||||
QString MessagesPresent::name() const { return NAME(MessagesPresent); }
|
|
||||||
|
|
|
||||||
|
|
@ -10,18 +10,13 @@ namespace Components {
|
||||||
/**
|
/**
|
||||||
* @brief 显示各种提示信息
|
* @brief 显示各种提示信息
|
||||||
*/
|
*/
|
||||||
class MessagesPresent : public QTableView, public MakeTools::PresentBase {
|
class MessagesPresent : public QTableView {
|
||||||
public:
|
public:
|
||||||
MessagesPresent(QStandardItemModel *base, QWidget *parent = nullptr);
|
MessagesPresent(QStandardItemModel *base, QWidget *parent = nullptr);
|
||||||
virtual ~MessagesPresent() = default;
|
virtual ~MessagesPresent() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStandardItemModel *const items_present;
|
QStandardItemModel *const items_present;
|
||||||
|
|
||||||
// PresentBase interface
|
|
||||||
public:
|
|
||||||
virtual QWidget *widget() const override;
|
|
||||||
virtual QString name() const override;
|
|
||||||
};
|
};
|
||||||
} // namespace Components
|
} // namespace Components
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ using namespace DataModel;
|
||||||
ProjectPresent::ProjectPresent(CommandsDispatcher *core, DocumentsManager *mgr, QWidget *parent)
|
ProjectPresent::ProjectPresent(CommandsDispatcher *core, DocumentsManager *mgr, QWidget *parent)
|
||||||
: QWidget(parent), source(core), view_present(new QTreeView(this)) {
|
: QWidget(parent), source(core), view_present(new QTreeView(this)) {
|
||||||
auto layout = new QVBoxLayout(this);
|
auto layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
layout->addWidget(view_present);
|
layout->addWidget(view_present);
|
||||||
|
layout->setMargin(1);
|
||||||
|
|
||||||
view_present->setModel(mgr->projectManager()->model());
|
view_present->setModel(mgr->projectManager()->model());
|
||||||
view_present->setHeaderHidden(true);
|
view_present->setHeaderHidden(true);
|
||||||
|
|
||||||
|
|
@ -27,13 +28,6 @@ ProjectPresent::ProjectPresent(CommandsDispatcher *core, DocumentsManager *mgr,
|
||||||
|
|
||||||
QModelIndex ProjectPresent::currentIndex() const { return view_present->currentIndex(); }
|
QModelIndex ProjectPresent::currentIndex() const { return view_present->currentIndex(); }
|
||||||
|
|
||||||
QString ProjectPresent::name() const
|
|
||||||
{
|
|
||||||
return NAME(ProjectPresent);
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *ProjectPresent::widget() const { return (QWidget *)this; }
|
|
||||||
|
|
||||||
void ProjectPresent::menu_popup(const QPoint &p)
|
void ProjectPresent::menu_popup(const QPoint &p)
|
||||||
{
|
{
|
||||||
QMenu m;
|
QMenu m;
|
||||||
|
|
@ -51,7 +45,7 @@ void ProjectPresent::menu_popup(const QPoint &p)
|
||||||
auto menu = m.addMenu("新建文件");
|
auto menu = m.addMenu("新建文件");
|
||||||
auto views = mgr->fileTypes();
|
auto views = mgr->fileTypes();
|
||||||
for (auto &it : views) {
|
for (auto &it : views) {
|
||||||
menu->addAction(it, [this, &it, &index, mgr]() {
|
menu->addAction(it, [this, it, &index, mgr]() {
|
||||||
auto name = QInputDialog::getText(this, "输入文件名称", "文件名称");
|
auto name = QInputDialog::getText(this, "输入文件名称", "文件名称");
|
||||||
auto path = mgr->convertPath(index);
|
auto path = mgr->convertPath(index);
|
||||||
source->postCommand(NewFile(path, name, it));
|
source->postCommand(NewFile(path, name, it));
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,13 @@ namespace Components {
|
||||||
/**
|
/**
|
||||||
* @brief 项目视图
|
* @brief 项目视图
|
||||||
*/
|
*/
|
||||||
class ProjectPresent : public QWidget, public MakeTools::PresentBase {
|
class ProjectPresent : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ProjectPresent(Schedule::CommandsDispatcher *core, DataModel::DocumentsManager *mgr, QWidget *parent = nullptr);
|
explicit ProjectPresent(Schedule::CommandsDispatcher *core, DataModel::DocumentsManager *mgr, QWidget *parent = nullptr);
|
||||||
|
|
||||||
QModelIndex currentIndex() const;
|
QModelIndex currentIndex() const;
|
||||||
|
|
||||||
// PresentBase interface
|
|
||||||
public:
|
|
||||||
virtual QWidget *widget() const override;
|
|
||||||
virtual QString name() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Schedule::CommandsDispatcher *const source;
|
Schedule::CommandsDispatcher *const source;
|
||||||
QTreeView *const view_present;
|
QTreeView *const view_present;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
using namespace Components;
|
using namespace Components;
|
||||||
using namespace Enhancement;
|
using namespace Enhancement;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
using namespace Config;
|
||||||
|
|
||||||
class Impl_EditError2 : public MakeTools::EditException {
|
class Impl_EditError2 : public MakeTools::EditException {
|
||||||
public:
|
public:
|
||||||
|
|
@ -63,14 +64,14 @@ QString StorySourceEdit::name() const
|
||||||
void StorySourceEdit::load(const QFileInfo &target_file)
|
void StorySourceEdit::load(const QFileInfo &target_file)
|
||||||
{
|
{
|
||||||
if(!target_file.exists())
|
if(!target_file.exists())
|
||||||
throw new SimpleException("参数错误:传入的文件不存在");
|
throw new SimpleException<QString>("参数错误", "传入的文件不存在:" + target_file.absoluteFilePath());
|
||||||
if(!target_file.isFile())
|
if(!target_file.isFile())
|
||||||
throw new SimpleException("参数错误:传入参数非文件类型");
|
throw new SimpleException<QString>("参数错误", "传入参数非文件类型:" + target_file.absoluteFilePath());
|
||||||
|
|
||||||
filepath_store = target_file.absoluteFilePath();
|
filepath_store = target_file.canonicalFilePath();
|
||||||
QFile bin(filepath_store);
|
QFile bin(filepath_store);
|
||||||
if(!bin.open(QIODevice::ReadOnly|QIODevice::Text))
|
if(!bin.open(QIODevice::ReadOnly|QIODevice::Text))
|
||||||
throw new SimpleException("参数错误:指定的文件无法打开");
|
throw new SimpleException<QString>("参数错误", "指定的文件无法打开:" + target_file.absoluteFilePath());
|
||||||
|
|
||||||
QTextStream tin(&bin);
|
QTextStream tin(&bin);
|
||||||
tin.setCodec("UTF-8");
|
tin.setCodec("UTF-8");
|
||||||
|
|
@ -84,7 +85,7 @@ void StorySourceEdit::saveAs(const QString &path)
|
||||||
|
|
||||||
QFile bout(filepath_store);
|
QFile bout(filepath_store);
|
||||||
if(!bout.open(QIODevice::WriteOnly|QIODevice::Text))
|
if(!bout.open(QIODevice::WriteOnly|QIODevice::Text))
|
||||||
throw new SimpleException("参数错误:指定的文件无法打开");
|
throw new SimpleException<QString>("保存文件参数错误", "指定的文件无法打开:" + path);
|
||||||
|
|
||||||
QTextStream tout(&bout);
|
QTextStream tout(&bout);
|
||||||
tout.setCodec("UTF-8");
|
tout.setCodec("UTF-8");
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,30 @@ namespace Config {
|
||||||
virtual QString title() const = 0;
|
virtual QString title() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T> class SimpleException : public ParseException {
|
||||||
|
public:
|
||||||
|
SimpleException(const QString &title, const QString &reason) : ts(title), rs(reason) {
|
||||||
|
this->buffer = QString("%1:%2").arg(title, reason).toLocal8Bit();
|
||||||
|
}
|
||||||
|
|
||||||
|
T datas() const { return datas_store; }
|
||||||
|
void setDatas(T val) { this->datas_store = val; }
|
||||||
|
|
||||||
|
// exception interface
|
||||||
|
public:
|
||||||
|
virtual const char *what() const override { return this->buffer; }
|
||||||
|
|
||||||
|
// ParseException interface
|
||||||
|
public:
|
||||||
|
virtual QString reason() const override { return rs; }
|
||||||
|
virtual QString title() const override { return ts; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T datas_store;
|
||||||
|
QString ts, rs;
|
||||||
|
QByteArray buffer;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 配置读写交互端口
|
* @brief 配置读写交互端口
|
||||||
*/
|
*/
|
||||||
|
|
@ -27,7 +51,7 @@ namespace Config {
|
||||||
virtual ~Configration() = default;
|
virtual ~Configration() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 载入配置文件
|
* @brief 载入配置文件,如果文件不存在,则生成新文件
|
||||||
* @param path 指定配置文件路径
|
* @param path 指定配置文件路径
|
||||||
* @throw ParseException* 配置文件解析异常
|
* @throw ParseException* 配置文件解析异常
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,62 @@
|
||||||
#include <QCoreApplication>
|
#include "unnnn.h"
|
||||||
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
#include <QDomDocument>
|
#include <QDomDocument>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <splitview.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
using namespace SplitFrame;
|
||||||
{
|
|
||||||
QCoreApplication a(argc, argv);
|
|
||||||
|
|
||||||
QString value = "row:23212,col:5234";
|
int main(int argc, char *argv[]) {
|
||||||
QRegExp exp("(\\d+)");
|
QApplication a(argc, argv);
|
||||||
auto offset = exp.indexIn(value);
|
|
||||||
qDebug() << exp.cap(1);
|
|
||||||
|
|
||||||
exp.indexIn(value, offset + exp.cap(1).length());
|
// auto z = new QWidget();
|
||||||
qDebug() << exp.cap(1);
|
|
||||||
|
// auto v = new XWidget();
|
||||||
|
// v->setParent(z);
|
||||||
|
// v->setGeometry(0, 50, 200, 100);
|
||||||
|
|
||||||
|
// z->show();
|
||||||
|
|
||||||
|
auto win = new QMainWindow();
|
||||||
|
win->setMinimumSize(800, 600);
|
||||||
|
win->menuBar()->addMenu("文件");
|
||||||
|
auto tbar = new QToolBar();
|
||||||
|
win->addToolBar(Qt::ToolBarArea::LeftToolBarArea, tbar);
|
||||||
|
tbar->addAction("添加");
|
||||||
|
|
||||||
|
auto aview = new BaseView("hello", new QWidget);
|
||||||
|
auto bview = new BaseView("world", new QWidget);
|
||||||
|
auto cview = new BaseView("everyone", new QWidget);
|
||||||
|
|
||||||
|
auto conv0 = new SplitView(aview, bview);
|
||||||
|
conv0->setSplitInfo(SplitType::SPLIT_V, 100, 8, true);
|
||||||
|
auto conv = new ViewPresent(conv0);
|
||||||
|
win->setCentralWidget(conv);
|
||||||
|
conv->append(cview, 0);
|
||||||
|
|
||||||
|
aview->installEventFilter(conv);
|
||||||
|
bview->installEventFilter(conv);
|
||||||
|
cview->installEventFilter(conv);
|
||||||
|
|
||||||
|
win->show();
|
||||||
|
|
||||||
|
// auto w = new QWidget();
|
||||||
|
// QLabel w0, w1;
|
||||||
|
// w0.setPixmap(a.style()->standardIcon(QStyle::StandardPixmap::SP_ArrowUp).pixmap(QSize(20, 20)));
|
||||||
|
// w1.setText("hello");
|
||||||
|
// auto v = new QHBoxLayout(w);
|
||||||
|
// v->setMargin(0);
|
||||||
|
// v->setSpacing(1);
|
||||||
|
// v->addWidget(&w0, 0);
|
||||||
|
// v->addWidget(&w1, 1);
|
||||||
|
// w->show();
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
QT -= gui
|
QT += gui
|
||||||
|
|
||||||
QT += xml
|
QT += xml widgets
|
||||||
|
|
||||||
CONFIG += c++11 console
|
CONFIG += c++11 console
|
||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
|
|
@ -10,9 +10,27 @@ CONFIG -= app_bundle
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp
|
main.cpp \
|
||||||
|
unnnn.cpp
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
unnnn.h
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../SplitView/release/ -lSplitView
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../SplitView/debug/ -lSplitView
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../SplitView/ -lSplitView
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../SplitView
|
||||||
|
DEPENDPATH += $$PWD/../SplitView
|
||||||
|
|
||||||
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../GenericConsole/release/ -lGenericConsole
|
||||||
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../GenericConsole/debug/ -lGenericConsole
|
||||||
|
else:unix: LIBS += -L$$OUT_PWD/../GenericConsole/ -lGenericConsole
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../GenericConsole
|
||||||
|
DEPENDPATH += $$PWD/../GenericConsole
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
#include "unnnn.h"
|
#include "unnnn.h"
|
||||||
|
|
||||||
QString EditView::t = "txt";
|
#include <QPainter>
|
||||||
|
|
||||||
|
XWidget::XWidget(QWidget *parent) : QWidget(parent) {}
|
||||||
|
|
||||||
|
void XWidget::paintEvent(QPaintEvent *ev) {
|
||||||
|
QPainter p(this);
|
||||||
|
p.fillRect(this->rect(), Qt::red);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,12 @@
|
||||||
#define UNNNN_H
|
#define UNNNN_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
template <class TargetType> class TypeDefine {
|
class XWidget : public QWidget {
|
||||||
public:
|
public:
|
||||||
static QString suffix() { return TargetType::t; }
|
XWidget(QWidget *parent = nullptr);
|
||||||
};
|
virtual void paintEvent(QPaintEvent *ev);
|
||||||
|
|
||||||
class EditView : public TypeDefine<EditView> {
|
|
||||||
public:
|
|
||||||
static QString t;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UNNNN_H
|
#endif // UNNNN_H
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue