#include "QQuickDetailsViewLayoutBuilder.h" #include "QQuickDetailsViewMananger.h" QQuickDetailsViewRowBuilder::QQuickDetailsViewRowBuilder(IDetailsViewRow* inRow, QQuickItem* inRootItem) : mRow(inRow) , mRootItem(inRootItem) { setHeightProxy(nullptr); } QPair QQuickDetailsViewRowBuilder::makeNameValueSlot() { QQmlEngine* engine = qmlEngine(mRootItem); QQmlContext* context = qmlContext(mRootItem); QQmlContext* newContext = new QQmlContext(context, mRootItem); QQmlComponent rootComp(newContext->engine()); rootComp.setData(R"( import QtQuick; import QtQuick.Controls; import Qt5Compat.GraphicalEffects import ColorPalette Rectangle{ id: topLevelRect anchors.fill: parent color: hoverHandler.hovered ? ColorPalette.theme.rowBackgroundHover : ColorPalette.theme.rowBackground border.color: ColorPalette.theme.rowBorder border.width: 0.5 Behavior on color { ColorAnimation { duration: 100 } } HoverHandler { id: hoverHandler } Image { id: indicator visible: detailsDelegate.isTreeNode && detailsDelegate.hasChildren x: padding + (detailsDelegate.depth * detailsDelegate.indent) anchors.verticalCenter: parent.verticalCenter mipmap: true source: detailsDelegate.expanded ? "qrc:/resources/Icon/expand.png" : "qrc:/resources/Icon/unexpand.png" width: 12 height: 12 ColorOverlay { anchors.fill: parent source: parent color: ColorPalette.theme.rowIndicator opacity: 1.0 } } Item{ id: nameEditorContent height: parent.height anchors.left: parent.left anchors.leftMargin: padding + (detailsDelegate.isTreeNode ? (detailsDelegate.depth + 1) * detailsDelegate.indent : 0) anchors.right: splitter.left anchors.verticalCenter: parent.verticalCenter } Item{ id: valueEditorContent implicitHeight: 25 anchors.left: splitter.left anchors.leftMargin: 10 anchors.rightMargin: 10 anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } Rectangle{ id: splitter width: 3 height: parent.height color : ColorPalette.theme.rowBackground x: detailsView.SpliterPencent * detailsView.width - 1 Rectangle{ id: visibleSplitter width: 1 height: parent.height color: ColorPalette.theme.rowSplitter anchors.horizontalCenter: parent.horizontalCenter } MouseArea { id: dragArea hoverEnabled: true cursorShape: containsMouse ? Qt.SplitHCursor : Qt.ArrowCursor anchors.fill: parent drag.target: splitter drag.axis: Drag.XAxis drag.minimumX: 10 + 1 drag.maximumX: detailsView.width - 10 - 1 onPositionChanged: { detailsView.SpliterPencent = (splitter.x + 1) / detailsView.width } } } Rectangle { id: gradientBox visible: detailsDelegate.depth > 0 width: 5 x: padding + (detailsDelegate.depth * detailsDelegate.indent) - 10 height: parent.height gradient: Gradient { orientation: Gradient.Horizontal GradientStop { position: 0.0; color: ColorPalette.theme.rowShadowStart } GradientStop { position: 1.0; color: ColorPalette.theme.rowShadowEnd } } } } )", QUrl()); QQuickItem* slotItem = qobject_cast(rootComp.create(newContext)); if (!rootComp.errors().isEmpty()) { qDebug() << rootComp.errorString(); } slotItem->setParentItem(mRootItem); return { slotItem->childItems()[1] ,slotItem->childItems()[2] }; } QQuickItem* QQuickDetailsViewRowBuilder::rootItem() const { return mRootItem; } IDetailsViewRow* QQuickDetailsViewRowBuilder::row() const { return mRow; } QQuickItem* QQuickDetailsViewRowBuilder::setupItem(QQuickItem* inParent, QString inQmlCode) { QQmlEngine* engine = qmlEngine(inParent); QQmlContext* context = qmlContext(inParent); QQmlComponent comp(engine); QQmlComponent nameComp(engine); comp.setData(inQmlCode.toLocal8Bit(), QUrl()); QVariantMap initialProperties; initialProperties["parent"] = QVariant::fromValue(inParent); auto item = qobject_cast(comp.createWithInitialProperties(initialProperties, context)); if (!comp.errors().isEmpty()) { qDebug() << comp.errorString(); } item->setParentItem(inParent); return item; } void QQuickDetailsViewRowBuilder::setupLabel(QQuickItem* inParent, QString inText) { QQuickItem* lableItem = setupItem(inParent, R"( import QtQuick; import QtQuick.Controls; import ColorPalette; Item{ property string lableText implicitHeight: 25 width: parent.width anchors.verticalCenter: parent.verticalCenter Text { anchors.fill: parent verticalAlignment: Text.AlignVCenter clip: true elide: Text.ElideRight text: lableText color: ColorPalette.theme.labelPrimary } } )"); lableItem->setProperty("lableText", inText); } void QQuickDetailsViewRowBuilder::setHeightProxy(QQuickItem* inProxyItem) { QQmlEngine* engine = qmlEngine(mRootItem); QQmlContext* context = qmlContext(mRootItem); context->parentContext()->setContextProperty("heightProxy", inProxyItem); } void QQuickDetailsViewRowBuilder::makePropertyRow(QPropertyHandle* inHandle) { QQmlEngine* engine = qmlEngine(mRootItem); QQmlContext* context = qmlContext(mRootItem); QPair slotItem = makeNameValueSlot(); QQuickItem* nameEditor = inHandle->setupNameEditor(slotItem.first); QQuickItem* valueEditor = inHandle->steupValueEditor(slotItem.second); context->parentContext()->setContextProperty("heightProxy", valueEditor ? valueEditor : nameEditor); } QQuickDetailsViewLayoutBuilder::QQuickDetailsViewLayoutBuilder(IDetailsViewRow* inRow) : mRootRow(inRow) { } IDetailsViewRow* QQuickDetailsViewLayoutBuilder::row() const { return mRootRow; } void QQuickDetailsViewLayoutBuilder::addCustomRow(std::function creator, QString inOverrideName) { QSharedPointer child(new QDetailsViewRow_Custom(creator)); child->setName(inOverrideName); mRootRow->addChild(child); child->attachChildren(); } void QQuickDetailsViewLayoutBuilder::addProperty(QPropertyHandle* inPropertyHandle, QString inOverrideName) { QSharedPointer child(new QDetailsViewRow_Property(inPropertyHandle)); child->setName(inOverrideName.isEmpty() ? inPropertyHandle->getName() : inOverrideName); mRootRow->addChild(child); child->attachChildren(); } void QQuickDetailsViewLayoutBuilder::addObject(QObject* inObject) { addProperty(QPropertyHandle::FindOrCreate(inObject)); }