Merge branch 'uwerat-master' into material-theme

This commit is contained in:
Peter Hartmann 2022-05-31 15:15:12 +02:00
commit 4ec93e2422
20 changed files with 189 additions and 149 deletions

View File

@ -232,7 +232,7 @@ jobs:
run: |
$Env:PATH += ";lib;plugins\skins"
echo "starting iotdashboard"
Start-Process .\examples\bin\iotdashboard
Start-Process .\examples\bin\iotdashboard -ArgumentList "-qwindowgeometry 1024x600+0+0"
Start-Sleep -s 10
- uses: OrbitalOwen/desktop-screenshot-action@0.1
with:
@ -244,6 +244,8 @@ jobs:
build-windows-qt-lts:
name: Windows Qt 6.2 (LTS) build
runs-on: windows-latest
env:
QSG_RHI_BACKEND: opengl
steps:
- uses: actions/checkout@v2
- name: Cache Qt
@ -287,7 +289,7 @@ jobs:
run: |
$Env:PATH += ";lib;plugins\skins"
echo "starting gallery"
Start-Process .\examples\bin\gallery
Start-Process .\examples\bin\gallery -ArgumentList "-qwindowgeometry 1024x600+0+0"
Start-Sleep -s 10
- uses: OrbitalOwen/desktop-screenshot-action@0.1
with:
@ -299,6 +301,8 @@ jobs:
build-windows-qt-current:
name: Windows Qt 6.3 (current) build
runs-on: windows-latest
env:
QSG_RHI_BACKEND: opengl
steps:
- uses: actions/checkout@v2
- name: Cache Qt
@ -342,7 +346,7 @@ jobs:
run: |
$Env:PATH += ";lib;plugins\skins"
echo "starting gallery"
Start-Process .\examples\bin\gallery
Start-Process .\examples\bin\gallery -ArgumentList "-qwindowgeometry 1024x600+0+0"
Start-Sleep -s 10
- uses: OrbitalOwen/desktop-screenshot-action@0.1
with:

View File

@ -11,7 +11,6 @@
#include <QskBoxNode.h>
#include <QskBoxShapeMetrics.h>
#include <QskTextColors.h>
#include <QskTextNode.h>
#include <QskTextOptions.h>
#include <QskFunctions.h>
@ -164,7 +163,9 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode(
const auto radius = 0.5 * scaleRect.width();
const auto spacing = speedometer->spacingHint( Q::TickLabels );
QFontMetricsF fontMetrics( speedometer->effectiveFont( Q::TickLabels ) );
const auto font = speedometer->effectiveFont( Q::TickLabels );
const QFontMetricsF fontMetrics( font );
auto angle = startAngle;
@ -172,6 +173,9 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode(
const auto needleRadius = radius - tickSize.height();
// Create a series of tickmarks from minimum to maximum
auto labelNode = ticksNode->firstChild();
for ( int i = 0; i < labels.count(); ++i, angle += step )
{
const qreal cos = qFastCos( qDegreesToRadians( angle ) );
@ -188,11 +192,10 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode(
vertexData += 2;
// only create a text node if there is a label for it:
if ( labels.count() > i )
{
const QString& text = labels.at( i );
const auto& text = labels.at( i );
if ( !text.isEmpty() )
{
const auto w = qskHorizontalAdvance( fontMetrics, text );
const auto h = fontMetrics.height();
const auto adjustX = ( -0.5 * cos - 0.5 ) * w;
@ -203,23 +206,17 @@ QSGNode* SpeedometerSkinlet::updateLabelsNode(
const QRectF numbersRect( numbersX, numbersY, w, h );
QskTextNode* numbersNode;
labelNode = QskSkinlet::updateTextNode(
speedometer, labelNode, numbersRect, Qt::AlignCenter | Qt::AlignHCenter,
text, font, QskTextOptions(), QskTextColors( color ), Qsk::Normal );
if ( ticksNode->childCount() > i )
if ( labelNode )
{
numbersNode = static_cast< QskTextNode* >( ticksNode->childAtIndex( i ) );
}
else
{
numbersNode = new QskTextNode();
}
if ( labelNode->parent() != ticksNode )
ticksNode->appendChildNode( labelNode );
const auto font = speedometer->effectiveFont( Q::TickLabels );
numbersNode->setTextData( speedometer, text, numbersRect, font, QskTextOptions(),
QskTextColors( color ), Qt::AlignCenter | Qt::AlignHCenter, Qsk::Normal );
if ( ticksNode->childCount() <= i )
ticksNode->appendChildNode( numbersNode );
labelNode = labelNode->nextSibling();
}
}
}

View File

@ -9,15 +9,8 @@ SUBDIRS += \
messagebox \
mycontrols \
thumbnails \
tabview
lessThan(QT_MAJOR_VERSION, 6) {
# the shader for the drop shadows has not yet been migrated
# to work with Qt 6
SUBDIRS += iotdashboard
}
tabview \
iotdashboard
qtHaveModule(svg) {

View File

@ -66,7 +66,11 @@ namespace
menu->addOption( "image://shapes/Diamond/Yellow", "Save As" );
menu->addOption( "image://shapes/Ellipse/Red", "Setup" );
menu->addSeparator();
menu->addOption( "image://shapes/Hexagon/PapayaWhip", "Help" );
menu->addOption( "image://shapes/Hexagon/PapayaWhip", "Quit" );
// see https://github.com/uwerat/qskinny/issues/192
connect( menu, &QskMenu::triggered,
[]( int index ) { if ( index == 3 ) qApp->quit(); } );
menu->setOrigin( geometry().bottomLeft() );
menu->open();

View File

@ -6,7 +6,10 @@
#include "LightDisplaySkinlet.h"
#include "LightDisplay.h"
#include "nodes/BoxShadowNode.h"
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
#include "nodes/BoxShadowNode.h"
#endif
#include "nodes/RadialTickmarksNode.h"
#include <QskArcMetrics.h>
@ -72,7 +75,7 @@ QRectF LightDisplaySkinlet::subControlRect( const QskSkinnable* skinnable,
{
QRectF valueTextRect = subControlRect( skinnable, contentsRect, LightDisplay::Panel );
const QFontMetricsF fm( skinnable->effectiveFont( subControl ) );
const qreal fontWidth = fm.width( QStringLiteral( "100 %" ) );
const qreal fontWidth = qskHorizontalAdvance( fm, QStringLiteral( "100 %" ) );
const QPointF center = valueTextRect.center();
const QRectF rect( center.x() - fontWidth / 2, center.y() - fm.height() / 2, fontWidth, fm.height() );
return rect;
@ -134,6 +137,7 @@ QSGNode* LightDisplaySkinlet::updateSubNode(
{
return updateBoxNode( skinnable, node, LightDisplay::Panel );
}
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
case GrooveRole:
{
const QRectF grooveRect = display->subControlRect( LightDisplay::Groove );
@ -156,6 +160,7 @@ QSGNode* LightDisplaySkinlet::updateSubNode(
return shadowNode;
}
#endif
case ColdAndWarmArcRole:
{
return updateArcNode( skinnable, node, LightDisplay::ColdAndWarmArc );
@ -209,7 +214,7 @@ QSizeF LightDisplaySkinlet::textLabelsSize( const LightDisplay* display ) const
{
const QFontMetricsF fm( display->effectiveFont( LightDisplay::LeftLabel ) );
qreal w = fm.width( QStringLiteral( " 100" ) );
qreal w = qskHorizontalAdvance( fm, QStringLiteral( " 100" ) );
qreal h = fm.height();
return { w, h };

View File

@ -4,7 +4,10 @@
*****************************************************************************/
#include "ShadowedBox.h"
#include "nodes/BoxShadowNode.h"
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
#include "nodes/BoxShadowNode.h"
#endif
#include <QskBoxNode.h>
#include <QskBoxBorderMetrics.h>
@ -21,6 +24,7 @@ namespace
Skinlet()
{
setOwnedBySkinnable( true );
setNodeRoles( { ShadowRole, PanelRole } );
}
@ -46,6 +50,7 @@ namespace
switch ( nodeRole )
{
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
case ShadowRole:
{
auto shadowNode = static_cast< BoxShadowNode* >( node );
@ -64,6 +69,7 @@ namespace
return shadowNode;
}
#endif
case PanelRole:
{
auto boxNode = static_cast< QskBoxNode* >( node );

View File

@ -1,20 +1,20 @@
<RCC>
<qresource prefix="/">
<file>images/main-icon.png</file>
<file>images/dashboard.png</file>
<file>images/rooms.png</file>
<file>images/devices.png</file>
<file>images/statistics.png</file>
<file>images/storage.png</file>
<file>images/members.png</file>
<file>images/logout.png</file>
<file>images/indoor-temperature.png</file>
<file>images/humidity.png</file>
<file>images/main-icon.svg</file>
<file>images/dashboard.svg</file>
<file>images/rooms.svg</file>
<file>images/devices.svg</file>
<file>images/statistics.svg</file>
<file>images/storage.svg</file>
<file>images/members.svg</file>
<file>images/logout.svg</file>
<file>images/indoor-temperature.svg</file>
<file>images/humidity.svg</file>
<file>images/up.svg</file>
<file>images/down.svg</file>
<file>images/lamps.png</file>
<file>images/music-system.png</file>
<file>images/ac.png</file>
<file>images/router.png</file>
<file>images/lamps.svg</file>
<file>images/music-system.svg</file>
<file>images/ac.svg</file>
<file>images/router.svg</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 942 B

View File

@ -30,7 +30,6 @@ SOURCES += \
main.cpp \
SOURCES += \
nodes/BoxShadowNode.cpp \
nodes/DiagramDataNode.cpp \
nodes/DiagramSegmentsNode.cpp \
nodes/RadialTickmarksNode.cpp
@ -61,11 +60,19 @@ HEADERS += \
UsageDiagram.h
HEADERS += \
nodes/BoxShadowNode.h \
nodes/DiagramDataNode.h \
nodes/DiagramSegmentsNode.h \
nodes/RadialTickmarksNode.h
lessThan(QT_MAJOR_VERSION, 6) {
# the shader for the drop shadows has not yet been migrated
# to work with Qt 6
SOURCES += nodes/BoxShadowNode.cpp
HEADERS += nodes/BoxShadowNode.h
}
RESOURCES += \
images.qrc \
fonts.qrc \

View File

@ -60,6 +60,8 @@ int main( int argc, char* argv[] )
QGuiApplication app( argc, argv );
qskSetup->setItemUpdateFlag( QskQuickItem::PreferRasterForTextures, true );
Qsk::addGraphicProvider( QString(), new GraphicProvider() );
// disable default skins

View File

@ -10,11 +10,13 @@
#include <QskRgbValue.h>
#include <QskSlider.h>
#include <QskTextColors.h>
#include <QskTextNode.h>
#include <QskTextOptions.h>
#include <QskSGNode.h>
#include <QskFunctions.h>
#include <QFontMetricsF>
#include <QSGFlatColorMaterial>
#include <QSGGeometryNode>
#include <cmath>
@ -287,40 +289,38 @@ QSGNode* CustomSliderSkinlet::updateDecorationNode(
const int tickCount = std::floor( slider->boundaryLength() / slider->stepSize() ) + 1;
auto labelNode = static_cast< QskTextNode* >( decorationNode->firstChild() );
auto stepStride = slider->stepSize() / slider->boundaryLength() * decorationRect.width();
auto x = decorationRect.x();
const auto y = decorationRect.y();
auto labelNode = decorationNode->firstChild();
const QFontMetrics fm( qskLabelFont );
for ( int i = 0; i < tickCount; i += 100 )
{
if ( labelNode == nullptr )
const auto text = QString::number( slider->minimum() + slider->stepSize() * i, 'f', 0 );
const auto w = qskHorizontalAdvance( fm, text );
const auto h = fm.height();
labelNode = QskSkinlet::updateTextNode( slider, labelNode,
QRectF( x - 0.5 * w, y, w, h ), Qt::AlignHCenter, text, qskLabelFont,
QskTextOptions(), QskTextColors( QskRgb::Grey700 ), Qsk::Normal );
if ( labelNode )
{
labelNode = new QskTextNode;
decorationNode->appendChildNode( labelNode );
if ( labelNode->parent() != decorationNode )
decorationNode->appendChildNode( labelNode );
labelNode = labelNode->nextSibling();
}
auto labelText = QString::number( slider->minimum() + slider->stepSize() * i, 'f', 0 );
labelNode->setTextData( slider, labelText, QRectF( x, y, 0, 0 ),
qskLabelFont, QskTextOptions(), QskTextColors( QskRgb::Grey700 ),
Qt::AlignHCenter, Qsk::Normal );
labelNode = static_cast< decltype( labelNode ) >( labelNode->nextSibling() );
x += 100 * stepStride;
}
// Remove unused labels
while ( labelNode )
{
auto sibling = static_cast< decltype( labelNode ) >( labelNode->nextSibling() );
decorationNode->removeChildNode( labelNode );
delete labelNode;
labelNode = sibling;
}
QskSGNode::removeAllChildNodesAfter( decorationNode, labelNode );
return decorationNode;
}
@ -344,12 +344,6 @@ QSGNode* CustomSliderSkinlet::updateHandleNode(
handleNode->update( handleRect, fillRect.right(), handleColor );
// finally the value label
auto labelNode = static_cast< QskTextNode* >( handleNode->firstChild() );
if ( labelNode == nullptr )
{
labelNode = new QskTextNode;
handleNode->appendChildNode( labelNode );
}
QFont font( QStringLiteral( "Roboto" ) );
font.setPixelSize( 26 );
@ -361,8 +355,12 @@ QSGNode* CustomSliderSkinlet::updateHandleNode(
const auto text = QString::number( slider->value(), 'f', 0 );
labelNode->setTextData( slider, text, textRect, font, QskTextOptions(),
QskTextColors( Qt::white ), Qt::AlignHCenter, Qsk::Normal );
auto labelNode = QskSkinlet::updateTextNode( slider, handleNode->firstChild(),
textRect, Qt::AlignHCenter, text, font, QskTextOptions(),
QskTextColors( Qt::white ), Qsk::Normal );
if ( labelNode->parent() != handleNode )
handleNode->appendChildNode( labelNode );
return handleNode;
}
@ -373,7 +371,7 @@ QSizeF CustomSliderSkinlet::sizeHint( const QskSkinnable* skinnable,
auto size = Inherited::sizeHint( skinnable, which, constraint );
if ( which == Qt::PreferredSize && size.height() >= 0 )
size.rheight() += 40;
size.rheight() += 60;
return size;
}

View File

@ -21,6 +21,7 @@ namespace
Skinlet()
{
setOwnedBySkinnable( true );
setNodeRoles( { ShadowRole, PanelRole } );
}

View File

@ -163,7 +163,7 @@ QKeySequence QskShortcutQml::sequence() const
void QskShortcutQml::setSequenceVariant( const QVariant& sequence )
{
if ( sequence.userType() == QVariant::Int )
if ( sequence.userType() == QMetaType::Int )
setSequence( static_cast< QKeySequence::StandardKey >( sequence.toInt() ) );
else
setSequence( QKeySequence::fromString( sequence.toString() ) );

View File

@ -9,8 +9,6 @@
#include "QskBoxNode.h"
#include "QskGraphic.h"
#include "QskColorFilter.h"
#include "QskGraphicNode.h"
#include "QskTextNode.h"
#include "QskTextOptions.h"
#include "QskSGNode.h"
#include "QskFunctions.h"

View File

@ -179,7 +179,7 @@ QskAspect::Placement QskSegmentedBar::effectivePlacement() const
void QskSegmentedBar::mousePressEvent( QMouseEvent* event )
{
const int index = indexAtPosition( event->localPos() );
const int index = indexAtPosition( qskMousePosition( event ) );
if( index < 0 || index >= count() || !m_data->options[ index ].isEnabled )
return;
@ -203,7 +203,7 @@ void QskSegmentedBar::mouseReleaseEvent( QMouseEvent* event )
if( m_data->isPressed )
{
m_data->isPressed = false;
index = indexAtPosition( event->localPos() );
index = indexAtPosition( qskMousePosition( event ) );
}
if( index < 0 || !m_data->options[ index ].isEnabled )

View File

@ -6,10 +6,8 @@
#include "QskSegmentedBarSkinlet.h"
#include "QskSegmentedBar.h"
#include "QskGraphicNode.h"
#include "QskGraphic.h"
#include "QskColorFilter.h"
#include "QskTextNode.h"
#include "QskTextOptions.h"
#include "QskSGNode.h"
#include "QskFunctions.h"

View File

@ -62,6 +62,43 @@ static inline QRectF qskSubControlRect( const QskSkinlet* skinlet,
return QRectF();
}
static inline QSGNode* qskUpdateTextNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, Qt::Alignment alignment,
const QString& text, const QFont& font, const QskTextOptions& textOptions,
const QskTextColors& textColors, Qsk::TextStyle textStyle )
{
if ( text.isEmpty() || rect.isEmpty() )
return nullptr;
auto textNode = static_cast< QskTextNode* >( node );
if ( textNode == nullptr )
textNode = new QskTextNode();
auto effectiveFont = font;
switch ( textOptions.fontSizeMode() )
{
case QskTextOptions::FixedSize:
break;
case QskTextOptions::HorizontalFit:
Q_UNIMPLEMENTED();
break;
case QskTextOptions::VerticalFit:
effectiveFont.setPixelSize( static_cast< int >( rect.height() * 0.5 ) );
break;
case QskTextOptions::Fit:
Q_UNIMPLEMENTED();
break;
}
textNode->setTextData( skinnable->owningControl(),
text, rect, effectiveFont, textOptions, textColors, alignment, textStyle );
return textNode;
}
static inline QSGNode* qskUpdateGraphicNode(
const QskSkinnable* skinnable, QSGNode* node,
const QskGraphic& graphic, const QskColorFilter& colorFilter,
@ -521,6 +558,15 @@ QSGNode* QskSkinlet::updateBoxClipNode( const QskSkinnable* skinnable,
return clipNode;
}
QSGNode* QskSkinlet::updateTextNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, Qt::Alignment alignment,
const QString& text, const QFont& font, const QskTextOptions& textOptions,
const QskTextColors& textColors, Qsk::TextStyle textStyle )
{
return qskUpdateTextNode( skinnable, node, rect, alignment,
text, font, textOptions, textColors, textStyle );
}
QSGNode* QskSkinlet::updateTextNode(
const QskSkinnable* skinnable, QSGNode* node,
const QRectF& rect, Qt::Alignment alignment,
@ -530,43 +576,19 @@ QSGNode* QskSkinlet::updateTextNode(
if ( text.isEmpty() || rect.isEmpty() )
return nullptr;
auto textNode = static_cast< QskTextNode* >( node );
if ( textNode == nullptr )
textNode = new QskTextNode();
const auto colors = qskTextColors( skinnable, subControl );
const auto textColors = qskTextColors( skinnable, subControl );
auto textStyle = Qsk::Normal;
if ( colors.styleColor.alpha() == 0 )
if ( textColors.styleColor.alpha() == 0 )
{
textStyle = skinnable->flagHint< Qsk::TextStyle >(
subControl | QskAspect::Style, Qsk::Normal );
}
auto font = skinnable->effectiveFont( subControl );
const auto font = skinnable->effectiveFont( subControl );
switch ( textOptions.fontSizeMode() )
{
case QskTextOptions::FixedSize:
break;
case QskTextOptions::HorizontalFit:
Q_UNIMPLEMENTED();
break;
case QskTextOptions::VerticalFit:
font.setPixelSize( static_cast< int >( rect.height() * 0.5 ) );
break;
case QskTextOptions::Fit:
Q_UNIMPLEMENTED();
break;
}
textNode->setTextData( skinnable->owningControl(),
text, rect, font, textOptions, colors, alignment, textStyle );
return textNode;
return qskUpdateTextNode( skinnable, node, rect, alignment,
text, font, textOptions, textColors, textStyle );
}
QSGNode* QskSkinlet::updateTextNode(

View File

@ -7,6 +7,7 @@
#define QSK_SKINLET_H
#include "QskAspect.h"
#include "QskNamespace.h"
#include <qnamespace.h>
#include <qrect.h>
@ -21,6 +22,7 @@ class QskGradient;
class QskColorFilter;
class QskGraphic;
class QskTextOptions;
class QskTextColors;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
@ -108,6 +110,10 @@ class QSK_EXPORT QskSkinlet
const QRectF&, Qt::Alignment, const QString&, const QskTextOptions&,
QskAspect::Subcontrol );
static QSGNode* updateTextNode( const QskSkinnable*, QSGNode*,
const QRectF&, Qt::Alignment, const QString&, const QFont&,
const QskTextOptions&, const QskTextColors&, Qsk::TextStyle );
// keeping the aspect ratio
static QSGNode* updateGraphicNode( const QskSkinnable*, QSGNode*,
const QskGraphic&, const QskColorFilter&, const QRectF&,

View File

@ -204,12 +204,12 @@ bool QskSubWindowArea::mouseEventFilter( QskSubWindow* window, const QMouseEvent
window->setFocus( true );
#if 0
// how to handle not to be process visual
// changes for double click events ???
if ( window->titleBarRect().contains( event->localPos() ) )
if ( window->titleBarRect().contains( qskMousePosition( event ) ) )
{
// block button press until we know it is no double click
///QGuiApplication::styleHints()->mouseDoubleClickInterval()
/*
block button press until we know it is no double click.
QGuiApplication::styleHints()->mouseDoubleClickInterval()
*/
}
#endif
bool doDrag = !m_data->isDraggableByHeaderOnly;

View File

@ -8,8 +8,6 @@
#include "QskSkinlet.h"
#include "QskSGNode.h"
#include "QskTickmarksNode.h"
#include "QskTextNode.h"
#include "QskGraphicNode.h"
#include "QskTextOptions.h"
#include "QskTextColors.h"
#include "QskGraphic.h"
@ -283,18 +281,20 @@ QSGNode* QskScaleRenderer::updateLabelsNode(
labelRect = r;
}
if ( nextNode == nullptr )
nextNode = QskSkinlet::updateTextNode( skinnable, nextNode,
r, alignment, text, m_data->font, QskTextOptions(),
m_data->textColors, Qsk::Normal );
if ( nextNode )
{
nextNode = new QskTextNode;
QskSGNode::setNodeRole( nextNode, TextNode );
node->appendChildNode( nextNode );
if ( nextNode->parent() != node )
{
QskSGNode::setNodeRole( nextNode, TextNode );
node->appendChildNode( nextNode );
}
nextNode = nextNode->nextSibling();
}
auto textNode = static_cast< QskTextNode* >( nextNode );
textNode->setTextData( skinnable->owningControl(), text, r, m_data->font,
QskTextOptions(), m_data->textColors, alignment, Qsk::Normal );
nextNode = nextNode->nextSibling();
}
else if ( label.canConvert< QskGraphic >() )
{
@ -329,20 +329,19 @@ QSGNode* QskScaleRenderer::updateLabelsNode(
nextNode = qskRemoveTraillingNodes( node, nextNode );
}
if ( nextNode == nullptr )
nextNode = QskSkinlet::updateGraphicNode(
skinnable, nextNode, graphic, m_data->colorFilter, labelRect, alignment );
if ( nextNode )
{
nextNode = new QskGraphicNode;
QskSGNode::setNodeRole( nextNode, GraphicNode );
node->appendChildNode( nextNode );
if ( nextNode->parent() != node )
{
QskSGNode::setNodeRole( nextNode, GraphicNode );
node->appendChildNode( nextNode );
}
nextNode = nextNode->nextSibling();
}
auto graphicNode = static_cast< QskGraphicNode* >( nextNode );
QskSkinlet::updateGraphicNode(
skinnable->owningControl(), graphicNode,
graphic, m_data->colorFilter, labelRect, alignment );
nextNode = nextNode->nextSibling();
}
}