fixed for multiple windows with different thread contexts
This commit is contained in:
parent
34cc82dd70
commit
a950203e7b
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <QGlobalStatic>
|
#include <QGlobalStatic>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
QSK_QT_PRIVATE_BEGIN
|
||||||
#include <private/qquicktext_p.h>
|
#include <private/qquicktext_p.h>
|
||||||
|
@ -79,18 +82,23 @@ namespace
|
||||||
setWrapMode( static_cast< QQuickText::WrapMode >( options.wrapMode() ) );
|
setWrapMode( static_cast< QQuickText::WrapMode >( options.wrapMode() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin()
|
inline void begin()
|
||||||
{
|
{
|
||||||
classBegin();
|
classBegin();
|
||||||
QQuickTextPrivate::get( this )->updateOnComponentComplete = true;
|
QQuickTextPrivate::get( this )->updateOnComponentComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void end()
|
inline void end()
|
||||||
{
|
{
|
||||||
componentComplete();
|
componentComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF layedOutTextRect() const
|
inline void reset()
|
||||||
|
{
|
||||||
|
setText( QString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QRectF layedOutTextRect() const
|
||||||
{
|
{
|
||||||
auto that = const_cast< TextItem* >( this );
|
auto that = const_cast< TextItem* >( this );
|
||||||
return QQuickTextPrivate::get( that )->layedOutTextRect;
|
return QQuickTextPrivate::get( that )->layedOutTextRect;
|
||||||
|
@ -118,6 +126,46 @@ namespace
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextItemMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~TextItemMap()
|
||||||
|
{
|
||||||
|
qDeleteAll( m_hash );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TextItem* item()
|
||||||
|
{
|
||||||
|
const auto thread = QThread::currentThread();
|
||||||
|
|
||||||
|
QMutexLocker locker( &m_mutex );
|
||||||
|
|
||||||
|
auto it = m_hash.constFind( thread );
|
||||||
|
if ( it == m_hash.constEnd() )
|
||||||
|
{
|
||||||
|
auto textItem = new TextItem();
|
||||||
|
QObject::connect( thread, &QThread::finished,
|
||||||
|
textItem, [this, thread] { removeItem( thread ); } );
|
||||||
|
|
||||||
|
m_hash.insert( thread, textItem );
|
||||||
|
return textItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void removeItem( const QThread* thread )
|
||||||
|
{
|
||||||
|
auto textItem = m_hash.take( thread );
|
||||||
|
if ( textItem )
|
||||||
|
textItem->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMutex m_mutex;
|
||||||
|
QHash< const QThread*, TextItem* > m_hash;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -125,31 +173,34 @@ namespace
|
||||||
better use different items as we might end up in events internally
|
better use different items as we might end up in events internally
|
||||||
being sent, that leads to crashes because of it
|
being sent, that leads to crashes because of it
|
||||||
*/
|
*/
|
||||||
Q_GLOBAL_STATIC( TextItem, qskRenderHelper )
|
Q_GLOBAL_STATIC( TextItemMap, qskTextItemMap )
|
||||||
Q_GLOBAL_STATIC( TextItem, qskLayoutHelper )
|
|
||||||
|
|
||||||
QSizeF QskRichTextRenderer::textSize( const QString& text,
|
QSizeF QskRichTextRenderer::textSize( const QString& text,
|
||||||
const QFont& font, const QskTextOptions& options )
|
const QFont& font, const QskTextOptions& options )
|
||||||
{
|
{
|
||||||
auto& item = *qskLayoutHelper;
|
auto& textItem = *qskTextItemMap->item();
|
||||||
|
|
||||||
item.begin();
|
textItem.begin();
|
||||||
|
|
||||||
item.setFont( font );
|
textItem.setFont( font );
|
||||||
item.setOptions( options );
|
textItem.setOptions( options );
|
||||||
|
|
||||||
item.setWidth( -1 );
|
textItem.setWidth( -1 );
|
||||||
item.setText( text );
|
textItem.setText( text );
|
||||||
|
|
||||||
item.end();
|
textItem.end();
|
||||||
|
|
||||||
return QSizeF( item.implicitWidth(), item.implicitHeight() );
|
const QSizeF sz( textItem.implicitWidth(), textItem.implicitHeight() );
|
||||||
|
|
||||||
|
textItem.reset();
|
||||||
|
|
||||||
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QskRichTextRenderer::textRect( const QString& text,
|
QRectF QskRichTextRenderer::textRect( const QString& text,
|
||||||
const QFont& font, const QskTextOptions& options, const QSizeF& size )
|
const QFont& font, const QskTextOptions& options, const QSizeF& size )
|
||||||
{
|
{
|
||||||
auto& textItem = *qskLayoutHelper;
|
auto& textItem = *qskTextItemMap->item();
|
||||||
|
|
||||||
textItem.begin();
|
textItem.begin();
|
||||||
|
|
||||||
|
@ -164,7 +215,11 @@ QRectF QskRichTextRenderer::textRect( const QString& text,
|
||||||
|
|
||||||
textItem.end();
|
textItem.end();
|
||||||
|
|
||||||
return textItem.layedOutTextRect();
|
const auto rect = textItem.layedOutTextRect();
|
||||||
|
|
||||||
|
textItem.reset();
|
||||||
|
|
||||||
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskRichTextRenderer::updateNode( const QString& text,
|
void QskRichTextRenderer::updateNode( const QString& text,
|
||||||
|
@ -176,7 +231,7 @@ void QskRichTextRenderer::updateNode( const QString& text,
|
||||||
// are we killing internal caches of QQuickText, when always using
|
// are we killing internal caches of QQuickText, when always using
|
||||||
// the same item for the creation the text nodes. TODO ...
|
// the same item for the creation the text nodes. TODO ...
|
||||||
|
|
||||||
auto& textItem = *qskRenderHelper;
|
auto& textItem = *qskTextItemMap->item();
|
||||||
|
|
||||||
textItem.begin();
|
textItem.begin();
|
||||||
|
|
||||||
|
@ -220,5 +275,5 @@ void QskRichTextRenderer::updateNode( const QString& text,
|
||||||
}
|
}
|
||||||
|
|
||||||
textItem.updateTextNode( item->window(), node );
|
textItem.updateTextNode( item->window(), node );
|
||||||
textItem.setText( QString() );
|
textItem.reset();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue