Initial commit for QML slideshow support.
This commit is contained in:
parent
46a5796e29
commit
14ddba70ef
@ -29,7 +29,7 @@ include( MacroLogFeature )
|
|||||||
|
|
||||||
set( QT_VERSION 5.3.0 )
|
set( QT_VERSION 5.3.0 )
|
||||||
|
|
||||||
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Core Gui Widgets LinguistTools Svg )
|
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Core Gui Widgets LinguistTools Svg Quick QuickWidgets )
|
||||||
find_package( YamlCpp 0.5.1 REQUIRED )
|
find_package( YamlCpp 0.5.1 REQUIRED )
|
||||||
find_package( PolkitQt5-1 REQUIRED )
|
find_package( PolkitQt5-1 REQUIRED )
|
||||||
|
|
||||||
|
@ -14,5 +14,4 @@ images:
|
|||||||
productLogo: "squid.png"
|
productLogo: "squid.png"
|
||||||
productIcon: "squid.png"
|
productIcon: "squid.png"
|
||||||
|
|
||||||
slideshow:
|
slideshow: "show.qml"
|
||||||
- "squid.png"
|
|
||||||
|
13
src/branding/default/show.qml
Normal file
13
src/branding/default/show.qml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import QtQuick 2.0;
|
||||||
|
import slideshow 1.0;
|
||||||
|
|
||||||
|
Presentation
|
||||||
|
{
|
||||||
|
id: presentation
|
||||||
|
width: 1280
|
||||||
|
height: 720
|
||||||
|
|
||||||
|
Slide {
|
||||||
|
centeredText: "Calamares is really nice"
|
||||||
|
}
|
||||||
|
}
|
@ -116,20 +116,37 @@ Branding::Branding( const QString& brandingFilePath,
|
|||||||
m_images.insert( it.key(), imageFi.absoluteFilePath() );
|
m_images.insert( it.key(), imageFi.absoluteFilePath() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !doc[ "slideshow" ].IsSequence() )
|
if ( doc[ "slideshow" ].IsSequence() )
|
||||||
bail( "Syntax error in slideshow sequence." );
|
|
||||||
|
|
||||||
doc[ "slideshow" ] >> m_slideshow;
|
|
||||||
for ( int i = 0; i < m_slideshow.count(); ++i )
|
|
||||||
{
|
{
|
||||||
QString pathString = m_slideshow[ i ];
|
QStringList slideShowPictures;
|
||||||
|
doc[ "slideshow" ] >> slideShowPictures;
|
||||||
|
for ( int i = 0; i < slideShowPictures.count(); ++i )
|
||||||
|
{
|
||||||
|
QString pathString = slideShowPictures[ i ];
|
||||||
QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
|
QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
|
||||||
if ( !imageFi.exists() )
|
if ( !imageFi.exists() )
|
||||||
bail( QString( "Slideshow file %1 does not exist." )
|
bail( QString( "Slideshow file %1 does not exist." )
|
||||||
.arg( imageFi.absoluteFilePath() ) );
|
.arg( imageFi.absoluteFilePath() ) );
|
||||||
|
|
||||||
m_slideshow[ i ] = imageFi.absoluteFilePath();
|
slideShowPictures[ i ] = imageFi.absoluteFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: implement a GenericSlideShow.qml that uses these slideShowPictures
|
||||||
|
}
|
||||||
|
else if ( doc[ "slideshow" ].IsScalar() )
|
||||||
|
{
|
||||||
|
QString slideshowPath = QString::fromStdString( doc[ "slideshow" ]
|
||||||
|
.as< std::string >() );
|
||||||
|
QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) );
|
||||||
|
if ( !slideshowFi.exists() ||
|
||||||
|
!slideshowFi.fileName().toLower().endsWith( ".qml" ) )
|
||||||
|
bail( QString( "Slideshow file %1 does not exist or is not a valid QML file." )
|
||||||
|
.arg( slideshowFi.absoluteFilePath() ) );
|
||||||
|
m_slideshowPath = slideshowFi.absoluteFilePath();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bail( "Syntax error in slideshow sequence." );
|
||||||
|
|
||||||
}
|
}
|
||||||
catch ( YAML::Exception& e )
|
catch ( YAML::Exception& e )
|
||||||
{
|
{
|
||||||
@ -197,10 +214,10 @@ Branding::image( Branding::ImageEntry imageEntry, const QSize& size ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QStringList
|
QString
|
||||||
Branding::slideshowPaths() const
|
Branding::slideshowPath() const
|
||||||
{
|
{
|
||||||
return m_slideshow;
|
return m_slideshowPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public:
|
|||||||
QString string( Branding::StringEntry stringEntry ) const;
|
QString string( Branding::StringEntry stringEntry ) const;
|
||||||
QString imagePath( Branding::ImageEntry imageEntry ) const;
|
QString imagePath( Branding::ImageEntry imageEntry ) const;
|
||||||
QPixmap image( Branding::ImageEntry imageEntry, const QSize& size ) const;
|
QPixmap image( Branding::ImageEntry imageEntry, const QSize& size ) const;
|
||||||
QStringList slideshowPaths() const;
|
QString slideshowPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a map called "branding" in the global storage, and inserts an
|
* Creates a map called "branding" in the global storage, and inserts an
|
||||||
@ -86,7 +86,7 @@ private:
|
|||||||
QString m_componentName;
|
QString m_componentName;
|
||||||
QMap< QString, QString > m_strings;
|
QMap< QString, QString > m_strings;
|
||||||
QMap< QString, QString > m_images;
|
QMap< QString, QString > m_images;
|
||||||
QStringList m_slideshow;
|
QString m_slideshowPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,10 @@ calamares_add_library( ${CALAMARESUI_LIBRARY_TARGET}
|
|||||||
LINK_LIBRARIES
|
LINK_LIBRARIES
|
||||||
yaml-cpp
|
yaml-cpp
|
||||||
Qt5::Svg
|
Qt5::Svg
|
||||||
|
Qt5::QuickWidgets
|
||||||
RESOURCES libcalamaresui.qrc
|
RESOURCES libcalamaresui.qrc
|
||||||
EXPORT CalamaresLibraryDepends
|
EXPORT CalamaresLibraryDepends
|
||||||
VERSION ${CALAMARES_VERSION_SHORT}
|
VERSION ${CALAMARES_VERSION_SHORT}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory( slideshow )
|
||||||
|
@ -18,11 +18,18 @@
|
|||||||
|
|
||||||
#include <InstallationViewStep.h>
|
#include <InstallationViewStep.h>
|
||||||
|
|
||||||
#include <JobQueue.h>
|
#include "JobQueue.h"
|
||||||
|
#include "Branding.h"
|
||||||
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QProgressBar>
|
#include <QProgressBar>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QtQuickWidgets/QQuickWidget>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
namespace Calamares
|
namespace Calamares
|
||||||
{
|
{
|
||||||
@ -35,10 +42,83 @@ InstallationViewStep::InstallationViewStep( QObject* parent )
|
|||||||
m_progressBar->setMaximum( 10000 );
|
m_progressBar->setMaximum( 10000 );
|
||||||
m_label = new QLabel;
|
m_label = new QLabel;
|
||||||
QVBoxLayout* layout = new QVBoxLayout( m_widget );
|
QVBoxLayout* layout = new QVBoxLayout( m_widget );
|
||||||
layout->addWidget(m_progressBar);
|
QVBoxLayout* innerLayout = new QVBoxLayout;
|
||||||
layout->addWidget(m_label);
|
|
||||||
|
m_slideShow = new QQuickWidget;
|
||||||
|
layout->addWidget( m_slideShow );
|
||||||
|
CalamaresUtils::unmarginLayout( layout );
|
||||||
|
|
||||||
|
layout->addLayout( innerLayout );
|
||||||
|
m_slideShow->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||||
|
m_slideShow->setResizeMode( QQuickWidget::SizeRootObjectToView );
|
||||||
|
|
||||||
|
QDir importPath;
|
||||||
|
{
|
||||||
|
QString subpath( "slideshow" );
|
||||||
|
|
||||||
|
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||||
|
{
|
||||||
|
importPath = QDir( CalamaresUtils::appDataDir()
|
||||||
|
.absoluteFilePath( subpath ) );
|
||||||
|
if ( !importPath.exists() || !importPath.isReadable() )
|
||||||
|
{
|
||||||
|
cLog() << "FATAL ERROR: explicitly configured application data directory"
|
||||||
|
<< CalamaresUtils::appDataDir().absolutePath()
|
||||||
|
<< "does not contain a valid slideshow directory at"
|
||||||
|
<< importPath.absolutePath()
|
||||||
|
<< "\nCowardly refusing to continue startup without slideshow.";
|
||||||
|
::exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QStringList slideshowDirCandidatesByPriority;
|
||||||
|
if ( Calamares::Settings::instance()->debugMode() )
|
||||||
|
{
|
||||||
|
slideshowDirCandidatesByPriority.append(
|
||||||
|
QDir::current().absoluteFilePath(
|
||||||
|
QString( "src/libcalamaresui/%1" )
|
||||||
|
.arg( subpath ) ) );
|
||||||
|
}
|
||||||
|
slideshowDirCandidatesByPriority.append( CalamaresUtils::appDataDir()
|
||||||
|
.absoluteFilePath( subpath ) );
|
||||||
|
|
||||||
|
foreach ( const QString& path, slideshowDirCandidatesByPriority )
|
||||||
|
{
|
||||||
|
QDir dir( path );
|
||||||
|
if ( dir.exists() && dir.isReadable() )
|
||||||
|
{
|
||||||
|
importPath = dir;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !importPath.exists() || !importPath.isReadable() )
|
||||||
|
{
|
||||||
|
cLog() << "FATAL ERROR: none of the expected slideshow paths ("
|
||||||
|
<< slideshowDirCandidatesByPriority.join( ", " )
|
||||||
|
<< ") exist."
|
||||||
|
<< "\nCowardly refusing to continue startup without slideshow.";
|
||||||
|
::exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cDebug() << "importPath:" << importPath;
|
||||||
|
importPath.cdUp();
|
||||||
|
|
||||||
|
m_slideShow->engine()->addImportPath( importPath.absolutePath() );
|
||||||
|
m_slideShow->setSource( QUrl::fromLocalFile( Calamares::Branding::instance()
|
||||||
|
->slideshowPath() ) );
|
||||||
|
|
||||||
|
innerLayout->addSpacing( CalamaresUtils::defaultFontHeight() / 2 );
|
||||||
|
innerLayout->addWidget( m_progressBar );
|
||||||
|
innerLayout->addWidget( m_label );
|
||||||
|
|
||||||
|
connect( JobQueue::instance(), &JobQueue::progress,
|
||||||
|
this, &InstallationViewStep::updateFromJobQueue );
|
||||||
|
|
||||||
|
cDebug() << "importPathList:" << m_slideShow->engine()->importPathList();
|
||||||
|
|
||||||
connect( JobQueue::instance(), &JobQueue::progress, this, &InstallationViewStep::updateFromJobQueue );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
|
class QQuickWidget;
|
||||||
|
|
||||||
namespace Calamares
|
namespace Calamares
|
||||||
{
|
{
|
||||||
@ -51,6 +52,7 @@ private:
|
|||||||
QWidget* m_widget;
|
QWidget* m_widget;
|
||||||
QProgressBar* m_progressBar;
|
QProgressBar* m_progressBar;
|
||||||
QLabel* m_label;
|
QLabel* m_label;
|
||||||
|
QQuickWidget* m_slideShow;
|
||||||
|
|
||||||
void updateFromJobQueue( qreal percent, const QString& message );
|
void updateFromJobQueue( qreal percent, const QString& message );
|
||||||
};
|
};
|
||||||
|
14
src/libcalamaresui/slideshow/CMakeLists.txt
Normal file
14
src/libcalamaresui/slideshow/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
set( QML_FILES
|
||||||
|
qmldir
|
||||||
|
Presentation.qml
|
||||||
|
Slide.qml
|
||||||
|
)
|
||||||
|
|
||||||
|
set( SLIDESHOW_DIR share/calamares/slideshow )
|
||||||
|
|
||||||
|
foreach( QML_FILE ${QML_FILES} )
|
||||||
|
configure_file( ${QML_FILE} ${QML_FILE} COPYONLY )
|
||||||
|
install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${QML_FILE}
|
||||||
|
DESTINATION ${SLIDESHOW_DIR} )
|
||||||
|
endforeach()
|
||||||
|
|
201
src/libcalamaresui/slideshow/Presentation.qml
Normal file
201
src/libcalamaresui/slideshow/Presentation.qml
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QML Presentation System.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Window 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property variant slides: []
|
||||||
|
property int currentSlide;
|
||||||
|
|
||||||
|
property bool showNotes: false;
|
||||||
|
property bool allowDelay: true;
|
||||||
|
|
||||||
|
property color titleColor: textColor;
|
||||||
|
property color textColor: "black"
|
||||||
|
property string fontFamily: "Helvetica"
|
||||||
|
property string codeFontFamily: "Courier New"
|
||||||
|
|
||||||
|
// Private API
|
||||||
|
property bool _faded: false
|
||||||
|
property int _userNum;
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var slideCount = 0;
|
||||||
|
var slides = [];
|
||||||
|
for (var i=0; i<root.children.length; ++i) {
|
||||||
|
var r = root.children[i];
|
||||||
|
if (r.isSlide) {
|
||||||
|
slides.push(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root.slides = slides;
|
||||||
|
root._userNum = 0;
|
||||||
|
|
||||||
|
// Make first slide visible...
|
||||||
|
if (root.slides.length > 0) {
|
||||||
|
root.currentSlide = 0;
|
||||||
|
root.slides[root.currentSlide].visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchSlides(from, to, forward) {
|
||||||
|
from.visible = false
|
||||||
|
to.visible = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToNextSlide() {
|
||||||
|
root._userNum = 0
|
||||||
|
if (_faded)
|
||||||
|
return
|
||||||
|
if (root.slides[currentSlide].delayPoints) {
|
||||||
|
if (root.slides[currentSlide]._advance())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (root.currentSlide + 1 < root.slides.length) {
|
||||||
|
var from = slides[currentSlide]
|
||||||
|
var to = slides[currentSlide + 1]
|
||||||
|
if (switchSlides(from, to, true)) {
|
||||||
|
currentSlide = currentSlide + 1;
|
||||||
|
root.focus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToPreviousSlide() {
|
||||||
|
root._userNum = 0
|
||||||
|
if (root._faded)
|
||||||
|
return
|
||||||
|
if (root.currentSlide - 1 >= 0) {
|
||||||
|
var from = slides[currentSlide]
|
||||||
|
var to = slides[currentSlide - 1]
|
||||||
|
if (switchSlides(from, to, false)) {
|
||||||
|
currentSlide = currentSlide - 1;
|
||||||
|
root.focus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToUserSlide() {
|
||||||
|
--_userNum;
|
||||||
|
if (root._faded || _userNum >= root.slides.length)
|
||||||
|
return
|
||||||
|
if (_userNum < 0)
|
||||||
|
goToNextSlide()
|
||||||
|
else if (root.currentSlide != _userNum) {
|
||||||
|
var from = slides[currentSlide]
|
||||||
|
var to = slides[_userNum]
|
||||||
|
if (switchSlides(from, to, _userNum > currentSlide)) {
|
||||||
|
currentSlide = _userNum;
|
||||||
|
root.focus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
Keys.onSpacePressed: goToNextSlide()
|
||||||
|
Keys.onRightPressed: goToNextSlide()
|
||||||
|
Keys.onDownPressed: goToNextSlide()
|
||||||
|
Keys.onLeftPressed: goToPreviousSlide()
|
||||||
|
Keys.onUpPressed: goToPreviousSlide()
|
||||||
|
Keys.onEscapePressed: Qt.quit()
|
||||||
|
Keys.onPressed: {
|
||||||
|
if (event.key >= Qt.Key_0 && event.key <= Qt.Key_9)
|
||||||
|
_userNum = 10 * _userNum + (event.key - Qt.Key_0)
|
||||||
|
else {
|
||||||
|
if (event.key == Qt.Key_Return || event.key == Qt.Key_Enter)
|
||||||
|
goToUserSlide();
|
||||||
|
else if (event.key == Qt.Key_Backspace)
|
||||||
|
goToPreviousSlide();
|
||||||
|
else if (event.key == Qt.Key_C)
|
||||||
|
root._faded = !root._faded;
|
||||||
|
_userNum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
z: 1000
|
||||||
|
color: "black"
|
||||||
|
anchors.fill: parent
|
||||||
|
opacity: root._faded ? 1 : 0
|
||||||
|
Behavior on opacity { NumberAnimation { duration: 250 } }
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button == Qt.RightButton)
|
||||||
|
goToPreviousSlide()
|
||||||
|
else
|
||||||
|
goToNextSlide()
|
||||||
|
}
|
||||||
|
onPressAndHold: goToPreviousSlide(); //A back mechanism for touch only devices
|
||||||
|
}
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: notesWindow;
|
||||||
|
width: 400
|
||||||
|
height: 300
|
||||||
|
|
||||||
|
title: "QML Presentation: Notes"
|
||||||
|
visible: root.showNotes
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: parent.height * 0.1;
|
||||||
|
|
||||||
|
font.pixelSize: 16
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
|
property string notes: root.slides[root.currentSlide].notes;
|
||||||
|
text: notes == "" ? "Slide has no notes..." : notes;
|
||||||
|
font.italic: notes == "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
201
src/libcalamaresui/slideshow/Slide.qml
Normal file
201
src/libcalamaresui/slideshow/Slide.qml
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QML Presentation System.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
/*
|
||||||
|
Slides can only be instantiated as a direct child of a Presentation {} as they rely on
|
||||||
|
several properties there.
|
||||||
|
*/
|
||||||
|
|
||||||
|
id: slide
|
||||||
|
|
||||||
|
property bool isSlide: true;
|
||||||
|
|
||||||
|
property bool delayPoints: false;
|
||||||
|
property int _pointCounter: 0;
|
||||||
|
function _advance() {
|
||||||
|
if (!parent.allowDelay)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_pointCounter = _pointCounter + 1;
|
||||||
|
if (_pointCounter < content.length)
|
||||||
|
return true;
|
||||||
|
_pointCounter = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
property string title;
|
||||||
|
property variant content: []
|
||||||
|
property string centeredText
|
||||||
|
property string writeInText;
|
||||||
|
property string notes;
|
||||||
|
|
||||||
|
property real fontSize: parent.height * 0.05
|
||||||
|
property real fontScale: 1
|
||||||
|
|
||||||
|
property real baseFontSize: fontSize * fontScale
|
||||||
|
property real titleFontSize: fontSize * 1.2 * fontScale
|
||||||
|
property real bulletSpacing: 1
|
||||||
|
|
||||||
|
property real contentWidth: width
|
||||||
|
|
||||||
|
// Define the slide to be the "content area"
|
||||||
|
x: parent.width * 0.05
|
||||||
|
y: parent.height * 0.2
|
||||||
|
width: parent.width * 0.9
|
||||||
|
height: parent.height * 0.7
|
||||||
|
|
||||||
|
property real masterWidth: parent.width
|
||||||
|
property real masterHeight: parent.height
|
||||||
|
|
||||||
|
property color titleColor: parent.titleColor;
|
||||||
|
property color textColor: parent.textColor;
|
||||||
|
property string fontFamily: parent.fontFamily;
|
||||||
|
property int textFormat: Text.PlainText
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: titleText
|
||||||
|
font.pixelSize: titleFontSize
|
||||||
|
text: title;
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.bottom: parent.top
|
||||||
|
anchors.bottomMargin: parent.fontSize * 1.5
|
||||||
|
font.bold: true;
|
||||||
|
font.family: slide.fontFamily
|
||||||
|
color: slide.titleColor
|
||||||
|
horizontalAlignment: Text.Center
|
||||||
|
z: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: centeredId
|
||||||
|
width: parent.width
|
||||||
|
anchors.centerIn: parent
|
||||||
|
anchors.verticalCenterOffset: - parent.y / 3
|
||||||
|
text: centeredText
|
||||||
|
horizontalAlignment: Text.Center
|
||||||
|
font.pixelSize: baseFontSize
|
||||||
|
font.family: slide.fontFamily
|
||||||
|
color: slide.textColor
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: writeInTextId
|
||||||
|
property int length;
|
||||||
|
font.family: slide.fontFamily
|
||||||
|
font.pixelSize: baseFontSize
|
||||||
|
color: slide.textColor
|
||||||
|
|
||||||
|
anchors.fill: parent;
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
text: slide.writeInText.substring(0, length);
|
||||||
|
|
||||||
|
NumberAnimation on length {
|
||||||
|
from: 0;
|
||||||
|
to: slide.writeInText.length;
|
||||||
|
duration: slide.writeInText.length * 30;
|
||||||
|
running: slide.visible && parent.visible && slide.writeInText.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: slide.writeInText != undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: contentId
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: content.length
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: row
|
||||||
|
|
||||||
|
function decideIndentLevel(s) { return s.charAt(0) == " " ? 1 + decideIndentLevel(s.substring(1)) : 0 }
|
||||||
|
property int indentLevel: decideIndentLevel(content[index])
|
||||||
|
property int nextIndentLevel: index < content.length - 1 ? decideIndentLevel(content[index+1]) : 0
|
||||||
|
property real indentFactor: (10 - row.indentLevel * 2) / 10;
|
||||||
|
|
||||||
|
height: text.height + (nextIndentLevel == 0 ? 1 : 0.3) * slide.baseFontSize * slide.bulletSpacing
|
||||||
|
x: slide.baseFontSize * indentLevel
|
||||||
|
visible: (!slide.parent.allowDelay || !delayPoints) || index <= _pointCounter
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: dot
|
||||||
|
y: baseFontSize * row.indentFactor / 2
|
||||||
|
width: baseFontSize / 4
|
||||||
|
height: baseFontSize / 4
|
||||||
|
color: slide.textColor
|
||||||
|
radius: width / 2
|
||||||
|
smooth: true
|
||||||
|
opacity: text.text.length == 0 ? 0 : 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: space
|
||||||
|
width: dot.width * 2
|
||||||
|
height: 1
|
||||||
|
color: "#00ffffff"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: text
|
||||||
|
width: slide.contentWidth - parent.x - dot.width - space.width
|
||||||
|
font.pixelSize: baseFontSize * row.indentFactor
|
||||||
|
text: content[index]
|
||||||
|
textFormat: slide.textFormat
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
color: slide.textColor
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
font.family: slide.fontFamily
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
4
src/libcalamaresui/slideshow/qmldir
Normal file
4
src/libcalamaresui/slideshow/qmldir
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
module slideshow
|
||||||
|
Presentation 1.0 Presentation.qml
|
||||||
|
Slide 1.0 Slide.qml
|
||||||
|
|
Loading…
Reference in New Issue
Block a user