dynamic object creation inside tooltip

The mainItem is now a Component, which gets created on demand and passed
to the tooltip dialog.

Positioning is a bit off now, but it basically seems to work as we'd
like it to.
This commit is contained in:
Sebastian Kügler 2013-04-05 04:27:52 +02:00
parent 8eab0f20f2
commit e0c7eaafad
3 changed files with 76 additions and 21 deletions

View File

@ -40,11 +40,12 @@ import org.kde.plasma.extras 2.0 as PlasmaExtras
MouseArea { MouseArea {
id: tooltip id: tooltip
property alias mainText: tooltipMaintext.text // string property string mainText: tooltipMaintext.text // string
property alias subText: tooltipSubtext.text // string property string subText: tooltipSubtext.text // string
property alias iconSource: tooltipIcon.source // icon name property string iconSource: tooltipIcon.source // icon name
property alias image: tooltipImage.source // string / url to the image property string image: tooltipImage.source // string / url to the image
property Item target: parent property Item target: parent
property alias mainItem: tooltipWindow.mainItem
// private props // private props
property int _s: theme.iconSizes.small / 2 property int _s: theme.iconSizes.small / 2
@ -52,11 +53,28 @@ MouseArea {
hoverEnabled: true hoverEnabled: true
onEntered: { onEntered: {
print("entered"); print("entered");
tooltipWindow.visible = true; show();
tooltipHideTimer.running = false;
} }
onExited: { onExited: {
print("exit"); print("exit");
hide();
}
function show() {
var mi = tooltip.mainItem;
if (mi == null) {
mi = tooltipWindow.mainComponent.createObject( tooltip.target, { "mainText": tooltip.mainText, "subText": tooltip.subText, "iconSource": tooltip.iconSource, "image": tooltip.image });
} else {
// TODO: update properties
}
//return;
tooltipWindow.visualParent = tooltip.target;
tooltipWindow.mainItem = mi;
tooltipWindow.visible = true;
tooltipHideTimer.running = false;
}
function hide() {
tooltipHideTimer.running = true tooltipHideTimer.running = true
} }
@ -64,10 +82,11 @@ MouseArea {
id: tooltipHideTimer id: tooltipHideTimer
running: false running: false
repeat: false repeat: false
interval: 50 interval: 0
onTriggered: { onTriggered: {
//print("Hiding tooltip ..."); //print("Hiding tooltip ...");
tooltipWindow.visible = false; tooltipWindow.visible = false;
tooltipWindow.mainItem.destroy();
} }
} }
@ -75,31 +94,40 @@ MouseArea {
id: tooltipWindow id: tooltipWindow
visualParent: tooltip.target visualParent: tooltip.target
mainItem: PlasmaCore.FrameSvgItem { mainComponent: Component {
id: tooltipSvg id: tooltipSvg
//imagePath: "widgets/tooltip" //imagePath: "widgets/tooltip"
width: childrenRect.width + margins.left + margins.right + 2*_s // width: childrenRect.width + margins.left + margins.right + 2*_s
height: childrenRect.height + margins.top + margins.bottom + 2*_s // height: childrenRect.height + margins.top + margins.bottom + 2*_s
Item { Item {
id: tooltipContentItem id: tooltipContentItem
x: tooltipSvg.margins.left + _s x: _s
y: tooltipSvg.margins.top + _s y: _s
width: childrenRect.width + _s width: childrenRect.width + _s
height: childrenRect.height height: childrenRect.height
property string mainText: "Default mainText" // string
property string subText: "Default subText" // string
property string iconSource: "klipper" // icon name
property string image: "" // string / url to the image
property int maxTextSize: Math.max(tooltipMaintext.paintedWidth, tooltipSubtext.paintedWidth) property int maxTextSize: Math.max(tooltipMaintext.paintedWidth, tooltipSubtext.paintedWidth)
property int maxSize: theme.iconSizes.desktop * 6 property int maxSize: theme.iconSizes.desktop * 6
property int preferredTextWidth: Math.min(maxTextSize, maxSize) property int preferredTextWidth: Math.min(maxTextSize, maxSize)
property int _s: theme.iconSizes.small / 2
Image { Image {
id: tooltipImage id: tooltipImage
source: image
} }
PlasmaCore.IconItem { PlasmaCore.IconItem {
id: tooltipIcon id: tooltipIcon
width: theme.iconSizes.desktop width: theme.iconSizes.desktop
height: width height: width
source: iconSource
anchors { anchors {
leftMargin: _s leftMargin: _s
} }
@ -109,7 +137,7 @@ MouseArea {
level: 3 level: 3
width: parent.preferredTextWidth width: parent.preferredTextWidth
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: tooltipWindow.mainText text: mainText
anchors { anchors {
left: (tooltipImage.source != "") ? tooltipImage.right : tooltipIcon.right left: (tooltipImage.source != "") ? tooltipImage.right : tooltipIcon.right
leftMargin: _s*2 leftMargin: _s*2
@ -120,7 +148,7 @@ MouseArea {
id: tooltipSubtext id: tooltipSubtext
width: parent.preferredTextWidth width: parent.preferredTextWidth
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: tooltipWindow.subText text: subText
opacity: 0.5 opacity: 0.5
anchors { anchors {
left: tooltipMaintext.left left: tooltipMaintext.left
@ -129,6 +157,8 @@ MouseArea {
top: tooltipMaintext.bottom top: tooltipMaintext.bottom
} }
} }
Component.onCompleted: print("XXX Tooltip mainItem created.")
Component.onDestruction: print("XXX Tooltip mainItem destroyed.")
} }
} }
} }

View File

@ -51,6 +51,16 @@ void ToolTip::setTarget(QQuickItem *target)
} }
} }
QQmlComponent* ToolTip::mainComponent() const
{
return m_mainComponent.data();
}
void ToolTip::setMainComponent(QQmlComponent* mainComponent)
{
m_mainComponent = mainComponent;
}
QQuickItem *ToolTip::mainItem() const QQuickItem *ToolTip::mainItem() const
{ {
return m_mainItem.data(); return m_mainItem.data();
@ -77,12 +87,12 @@ void ToolTip::setMainItem(QQuickItem *mainItem)
//mainItem->setParent(contentItem()); //mainItem->setParent(contentItem());
//mainItem->setProperty("parent", QVariant::fromValue(contentItem())); //mainItem->setProperty("parent", QVariant::fromValue(contentItem()));
if (mainItem->metaObject()->indexOfSignal("widthChanged")) { // if (mainItem->metaObject()->indexOfSignal("widthChanged")) {
connect(mainItem, SIGNAL(widthChanged()), m_syncTimer, SIGNAL(start())); // connect(mainItem, SIGNAL(widthChanged()), m_syncTimer, SIGNAL(start()));
} // }
if (mainItem->metaObject()->indexOfSignal("heightChanged")) { // if (mainItem->metaObject()->indexOfSignal("heightChanged")) {
connect(mainItem, SIGNAL(heightChanged()), m_syncTimer, SIGNAL(start())); // connect(mainItem, SIGNAL(heightChanged()), m_syncTimer, SIGNAL(start()));
} // }
} }
//if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene //if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene
@ -118,7 +128,14 @@ void ToolTip::setVisible(const bool visible)
ToolTipDialog *dlg = ToolTipDialog::instance(); ToolTipDialog *dlg = ToolTipDialog::instance();
qDebug() << visible; qDebug() << visible;
if (visible) { if (visible) {
qDebug() << " showing tooltip: " << ToolTipDialog::instance(); //dlg->mainItem()->deleteLater();
// QObject *myObject = m_mainComponent.data()->create();
// QQuickItem *item = qobject_cast<QQuickItem*>(myObject);
qDebug() << "XXX Setting visible: " << mainItem();
setMainItem(mainItem());
qDebug() << "XXX showing tooltip: " << ToolTipDialog::instance();
dlg->setMainItem(mainItem()); dlg->setMainItem(mainItem());
dlg->setVisualParent(m_visualParent.data()); dlg->setVisualParent(m_visualParent.data());
dlg->setPosition(dlg->popupPosition(visualParent())); dlg->setPosition(dlg->popupPosition(visualParent()));
@ -128,6 +145,7 @@ void ToolTip::setVisible(const bool visible)
// raise(); // raise();
} else { } else {
dlg->setVisible(false); dlg->setVisible(false);
//dlg->mainItem()->deleteLater();
} }
//QQuickWindow::setVisible(visible); //QQuickWindow::setVisible(visible);
} }

View File

@ -24,6 +24,7 @@
#include <QTimer> #include <QTimer>
#include <QQuickWindow> #include <QQuickWindow>
#include <QQmlComponent>
#include <QWeakPointer> #include <QWeakPointer>
#include <QtCore/QVariant> #include <QtCore/QVariant>
@ -48,6 +49,7 @@ class ToolTip : public QObject
* The main QML item that will be displayed in the Dialog * The main QML item that will be displayed in the Dialog
*/ */
Q_PROPERTY(QQuickItem *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged) Q_PROPERTY(QQuickItem *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged)
Q_PROPERTY(QQmlComponent *mainComponent READ mainComponent WRITE setMainComponent NOTIFY mainComponentChanged)
/** /**
* The main QML item that will be displayed in the Dialog * The main QML item that will be displayed in the Dialog
@ -67,6 +69,9 @@ public:
QQuickItem *target() const; QQuickItem *target() const;
void setTarget(QQuickItem *target); void setTarget(QQuickItem *target);
QQmlComponent* mainComponent() const;
void setMainComponent(QQmlComponent *mainComponent);
QQuickItem *mainItem() const; QQuickItem *mainItem() const;
void setMainItem(QQuickItem *mainItem); void setMainItem(QQuickItem *mainItem);
@ -80,12 +85,14 @@ public:
Q_SIGNALS: Q_SIGNALS:
void targetChanged(); void targetChanged();
void mainComponentChanged();
void mainItemChanged(); void mainItemChanged();
void visualParentChanged(); void visualParentChanged();
void visibleChanged(); void visibleChanged();
private: private:
QTimer *m_syncTimer; QTimer *m_syncTimer;
QWeakPointer<QQmlComponent> m_mainComponent;
QWeakPointer<QQuickItem> m_mainItem; QWeakPointer<QQuickItem> m_mainItem;
QWeakPointer<QQuickItem> m_visualParent; QWeakPointer<QQuickItem> m_visualParent;
QWeakPointer<QQuickItem> m_declarativeItemContainer; QWeakPointer<QQuickItem> m_declarativeItemContainer;