完成拖动,但是未完成释放

This commit is contained in:
玉宇清音 2023-08-21 01:22:48 +08:00
parent d2ac84894d
commit b6bae9980b
20 changed files with 1213 additions and 96 deletions

View File

@ -2,6 +2,7 @@ TEMPLATE = subdirs
SUBDIRS += \
GenericConsole \
SplitView \
WordsIDE \
libConfig \
libProjectManager \

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<data>
<variable>EnvironmentId</variable>
@ -346,7 +346,80 @@
<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>
</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>
</data>
<data>

35
SplitView/SplitView.pro Normal file
View File

@ -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

View File

@ -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

719
SplitView/splitview.cpp Normal file
View File

@ -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();
}
}

236
SplitView/splitview.h Normal file
View File

@ -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

View File

@ -12,11 +12,3 @@
using namespace Core;
using namespace Components;
using namespace MakeTools;
SimpleException::SimpleException(const QString &msg)
: msg_store(msg) {}
const char *SimpleException::what() const{
return msg_store.toLocal8Bit();
}

View File

@ -7,19 +7,6 @@
#include <libConfig.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 {
enum class Scale

View File

@ -53,24 +53,22 @@ MainWindow::MainWindow(QWidget *parent)
setMinimumSize(1000, 600);
setWindowTitle("提线木偶");
project_present->widget()->setVisible(false);
errors_present->setVisible(false);
auto mbar = menuBar();
initial_menubar(mbar);
setCentralWidget(this->split_first);
this->split_first->addWidget(project_present);
this->split_first->addWidget(this->split_second);
this->split_third->addWidget(this->center_frame->hostWidget());
this->split_third->addWidget(this->messages_frame);
this->split_second->addWidget(this->split_third);
this->split_second->addWidget(this->errors_present);
this->split_third->addWidget(this->center_frame->hostWidget());
this->split_third->addWidget(this->messages_frame);
this->messages_frame->setTabPosition(QTabWidget::TabPosition::South);
this->split_first->addWidget(project_present);
this->split_first->addWidget(this->split_second);
project_present->setVisible(true);
this->active_docscollect->setPresent(this);
setCentralWidget(this->split_first);
this->messages_frame->setTabPosition(QTabWidget::TabPosition::South);
}
MainWindow::~MainWindow() {}
@ -177,12 +175,6 @@ void MainWindow::initial_menubar(QMenuBar *mbar) {
auto func = view->addMenu("功能视图");
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("工具");
@ -222,10 +214,8 @@ void MainWindow::initial_commandlist(Schedule::CommandsDispatcher *host) {
host->registerCommand(new CloseProject());
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 NewProject(QDir(), ""));
host->registerCommand(new OpenFile(Route()));

View File

@ -5,6 +5,7 @@
using namespace Components;
using namespace Core;
using namespace DataModel;
using namespace Config;
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) {
auto all_types = fileTypes();
if (!all_types.contains(suffix))
throw new SimpleException("指定文件类型无法打开:" + suffix);
throw new SimpleException<QString>("创建文件错误", "指定文件类型无法打开:" + suffix);
auto midx = convertPath(group_path);
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));
if (!info.isFile())
throw new SimpleException("指向的节点不是文件节点");
throw new SimpleException<QString>("打开文件错误", "指向的节点不是文件节点");
auto view = factory_map[info.suffix()]->newInst(present_ui->hostWidget());
doc_openning[it] = view;
@ -120,7 +121,7 @@ QModelIndex DocumentsManager::convertPath(const Core::Route &path) {
}
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();
}

View File

@ -3,7 +3,3 @@
using namespace Components;
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); }

View File

@ -10,18 +10,13 @@ namespace Components {
/**
* @brief
*/
class MessagesPresent : public QTableView, public MakeTools::PresentBase {
class MessagesPresent : public QTableView {
public:
MessagesPresent(QStandardItemModel *base, QWidget *parent = nullptr);
virtual ~MessagesPresent() = default;
private:
QStandardItemModel *const items_present;
// PresentBase interface
public:
virtual QWidget *widget() const override;
virtual QString name() const override;
};
} // namespace Components

View File

@ -13,8 +13,9 @@ using namespace DataModel;
ProjectPresent::ProjectPresent(CommandsDispatcher *core, DocumentsManager *mgr, QWidget *parent)
: QWidget(parent), source(core), view_present(new QTreeView(this)) {
auto layout = new QVBoxLayout(this);
layout->addWidget(view_present);
layout->setMargin(1);
view_present->setModel(mgr->projectManager()->model());
view_present->setHeaderHidden(true);
@ -27,13 +28,6 @@ ProjectPresent::ProjectPresent(CommandsDispatcher *core, DocumentsManager *mgr,
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)
{
QMenu m;
@ -51,7 +45,7 @@ void ProjectPresent::menu_popup(const QPoint &p)
auto menu = m.addMenu("新建文件");
auto views = mgr->fileTypes();
for (auto &it : views) {
menu->addAction(it, [this, &it, &index, mgr]() {
menu->addAction(it, [this, it, &index, mgr]() {
auto name = QInputDialog::getText(this, "输入文件名称", "文件名称");
auto path = mgr->convertPath(index);
source->postCommand(NewFile(path, name, it));

View File

@ -13,18 +13,13 @@ namespace Components {
/**
* @brief
*/
class ProjectPresent : public QWidget, public MakeTools::PresentBase {
class ProjectPresent : public QWidget {
Q_OBJECT
public:
explicit ProjectPresent(Schedule::CommandsDispatcher *core, DataModel::DocumentsManager *mgr, QWidget *parent = nullptr);
QModelIndex currentIndex() const;
// PresentBase interface
public:
virtual QWidget *widget() const override;
virtual QString name() const override;
private:
Schedule::CommandsDispatcher *const source;
QTreeView *const view_present;

View File

@ -9,6 +9,7 @@
using namespace Components;
using namespace Enhancement;
using namespace Core;
using namespace Config;
class Impl_EditError2 : public MakeTools::EditException {
public:
@ -63,14 +64,14 @@ QString StorySourceEdit::name() const
void StorySourceEdit::load(const QFileInfo &target_file)
{
if(!target_file.exists())
throw new SimpleException("参数错误:传入的文件不存在");
throw new SimpleException<QString>("参数错误", "传入的文件不存在:" + target_file.absoluteFilePath());
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);
if(!bin.open(QIODevice::ReadOnly|QIODevice::Text))
throw new SimpleException("参数错误:指定的文件无法打开");
throw new SimpleException<QString>("参数错误", "指定的文件无法打开:" + target_file.absoluteFilePath());
QTextStream tin(&bin);
tin.setCodec("UTF-8");
@ -84,7 +85,7 @@ void StorySourceEdit::saveAs(const QString &path)
QFile bout(filepath_store);
if(!bout.open(QIODevice::WriteOnly|QIODevice::Text))
throw new SimpleException("参数错误:指定的文件无法打开");
throw new SimpleException<QString>("保存文件参数错误", "指定的文件无法打开:" + path);
QTextStream tout(&bout);
tout.setCodec("UTF-8");

View File

@ -17,6 +17,30 @@ namespace Config {
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
*/
@ -27,7 +51,7 @@ namespace Config {
virtual ~Configration() = default;
/**
* @brief
* @brief
* @param path
* @throw ParseException*
*/

View File

@ -1,18 +1,62 @@
#include <QCoreApplication>
#include "unnnn.h"
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QDomDocument>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QMenuBar>
#include <QPushButton>
#include <QStyle>
#include <QToolBar>
#include <splitview.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
using namespace SplitFrame;
QString value = "row:23212,col:5234";
QRegExp exp("(\\d+)");
auto offset = exp.indexIn(value);
qDebug() << exp.cap(1);
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
exp.indexIn(value, offset + exp.cap(1).length());
qDebug() << exp.cap(1);
// auto z = new QWidget();
// 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();
}

View File

@ -1,6 +1,6 @@
QT -= gui
QT += gui
QT += xml
QT += xml widgets
CONFIG += c++11 console
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
SOURCES += \
main.cpp
main.cpp \
unnnn.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!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

View File

@ -1,3 +1,10 @@
#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);
}

View File

@ -2,15 +2,12 @@
#define UNNNN_H
#include <QString>
#include <QWidget>
template <class TargetType> class TypeDefine {
class XWidget : public QWidget {
public:
static QString suffix() { return TargetType::t; }
};
class EditView : public TypeDefine<EditView> {
public:
static QString t;
XWidget(QWidget *parent = nullptr);
virtual void paintEvent(QPaintEvent *ev);
};
#endif // UNNNN_H