Welcome: Start some performance improvements

This is essentially a widgets based re-implementation
of the current design. It is still using the QAIM based
interface layer between to the real data and display even
though this is not needed with this approach.
Removal of this layer would further reduce code size
and cycle counts.

For now:
               old          new
Load time    215ms        182ms
delete        22ms          2ms

Change-Id: I90d779a60a47a78399eaad0f1bc032d39f3ae3c0
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
hjk
2017-01-06 21:41:46 +01:00
parent 36d1a75118
commit 16944277d2
59 changed files with 1443 additions and 3184 deletions

View File

@@ -7,7 +7,6 @@ STATIC_OUTPUT_BASE = $$IDE_DATA_PATH
STATIC_INSTALL_BASE = $$INSTALL_DATA_PATH STATIC_INSTALL_BASE = $$INSTALL_DATA_PATH
DATA_DIRS = \ DATA_DIRS = \
welcomescreen \
examplebrowser \ examplebrowser \
snippets \ snippets \
templates \ templates \

View File

@@ -69,8 +69,7 @@ shared_sources = $$files($$IDE_SOURCE_TREE/src/shared/*)
shared_sources ~= s,^$$re_escape($$IDE_SOURCE_TREE/),,g$$i_flag shared_sources ~= s,^$$re_escape($$IDE_SOURCE_TREE/),,g$$i_flag
shared_sources -= \ shared_sources -= \
src/shared/qbs src/shared/qbs
sources = src/app src/libs $$plugin_sources $$shared_sources share/qtcreator/qmldesigner \ sources = src/app src/libs $$plugin_sources $$shared_sources share/qtcreator/qmldesigner
share/qtcreator/welcomescreen share/qtcreator/welcomescreen/widgets
for(path, INCLUDEPATH): include_options *= -I$$shell_quote($$path) for(path, INCLUDEPATH): include_options *= -I$$shell_quote($$path)

View File

@@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import widgets 1.0
import QtQuick.Controls 1.0 as Controls
Controls.ScrollView {
id: rectangle1
readonly property int buttonWidth: 190
readonly property int titleY: 50
Item {
id: canvas
implicitWidth: childrenRect.width
implicitHeight: childrenRect.height
Button {
y: screenDependHeightDistance
width: buttonWidth
text: qsTr("New Project")
anchors.left: sessionsTitle.left
onClicked: projectWelcomePage.newProject();
iconSource: "image://icons/new/"
+ ((checked || pressed)
? "Welcome_DividerColor"
: "Welcome_ForegroundSecondaryColor")
}
Button {
y: screenDependHeightDistance
width: buttonWidth
text: qsTr("Open Project")
anchors.left: recentProjectsTitle.left
onClicked: projectWelcomePage.openProject();
iconSource: "image://icons/open/" +
((checked || pressed)
? "Welcome_DividerColor"
: "Welcome_ForegroundSecondaryColor")
}
NativeText {
id: sessionsTitle
x: 32
y: screenDependHeightDistance + titleY
color: creatorTheme.Welcome_TextColor
text: qsTr("Sessions")
font.pixelSize: 16
font.family: "Helvetica"
}
NativeText {
id: recentProjectsTitle
x: 406
y: screenDependHeightDistance + titleY
color: creatorTheme.Welcome_TextColor
text: qsTr("Recent Projects")
anchors.left: sessionsTitle.right
anchors.leftMargin: 280
font.family: "Helvetica"
font.pixelSize: 16
}
Sessions {
anchors.left: sessionsTitle.left
anchors.right: recentProjectsTitle.left
anchors.top: sessionsTitle.bottom
anchors.topMargin: 20
model: sessionList
}
RecentProjects {
anchors.left: recentProjectsTitle.left
anchors.top: recentProjectsTitle.bottom
anchors.topMargin: 20
model: projectList
}
}
}

View File

@@ -1,98 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
name: "Main Windows"
descriptionData: "All the standard features of application main windows are provided by Qt. Main windows can have pull down menus, tool bars, and dock windows. These separate forms of user input are unified in an integrated action system that also supports keyboard shortcuts and accelerator keys in menu items."
imageSource: "images/mockup/mainwindow-examples.png"
}
ListElement {
name: "Layouts"
description: "t uses a layout-based approach to widget management. Widgets are arranged in the optimal positions in windows based on simple layout rules, leading to a consistent look and feel. Custom layouts can be used to provide more control over the positions and sizes of child widgets."
imageSource: "images/mockup/layout-examples.png"
}
ListElement {
name: "Item Views"
description: "tem views are widgets that typically display data sets. Qt 4's model/view framework lets you handle large data sets by separating the underlying data from the way it is represented to the user, and provides support for customized rendering through the use of delegates."
imageSource: "images/mockup/itemview-examples.png"
}
ListElement {
name: "Drag and Drop"
description: "Qt supports native drag and drop on all platforms via an extensible MIME-based system that enables applications to send data to each other in the most appropriate formats. Drag and drop can also be implemented for internal use by applications."
imageSource: "images/mockup/draganddrop-examples.png"
}
ListElement {
name: "Threading and Concurrent Programming"
description: "Qt 4 makes it easier than ever to write multithreaded applications. More classes have been made usable from non-GUI threads, and the signals and slots mechanism can now be used to communicate between threads. The QtConcurrent namespace includes a collection of classes and functions for straightforward concurrent programming."
imageSource: "images/mockup/thread-examples.png"
}
ListElement {
name: "OpenGL and OpenVG Examples"
description: "Qt provides support for integration with OpenGL implementations on all platforms, giving developers the opportunity to display hardware accelerated 3D graphics alongside a more conventional user interface. Qt provides support for integration with OpenVG implementations on platforms with suitable drivers."
imageSource: "images/mockup/opengl-examples.png"
}
ListElement {
name: "Network"
description: "Qt is provided with an extensive set of network classes to support both client-based and server side network programming."
imageSource: "images/mockup/network-examples.png"
}
ListElement {
name: "Qt Designer"
description: "Qt Designer is a capable graphical user interface designer that lets you create and configure forms without writing code. GUIs created with Qt Designer can be compiled into an application or created at run-time."
imageSource: "images/mockup/designer-examples.png"
}
ListElement {
name: "Qt Script"
description: "Qt is provided with a powerful embedded scripting environment through the QtScript classes."
imageSource: "images/mockup/qtscript-examples.png"
}
ListElement {
name: "Desktop"
description: "Qt provides features to enable applications to integrate with the user's preferred desktop environment. Features such as system tray icons, access to the desktop widget, and support for desktop services can be used to improve the appearance of applications and take advantage of underlying desktop facilities."
imageSource: "images/mockup/desktop-examples.png"
}
ListElement {
name: "Caption"
description: "Description"
imageSource: "image/mockup/penguin.png"
}
ListElement {
name: "Caption"
description: "Description"
imageSource: "images/mockup/penguin.png"
}
}

View File

@@ -1,41 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
title: "Projects"
pageLocation: "../develop.qml"
}
ListElement {
title: "Examples"
pageLocation: "../examples.qml"
}
ListElement {
title: "Tutorials"
pageLocation: "../tutorials.qml"
}
}

View File

@@ -1,61 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
prettyFilePath: "showing some path aka the link..."
displayName: "Project name 01"
}
ListElement {
prettyFilePath: "showing some path aka link..."
displayName: "Project name 02"
}
ListElement {
prettyFilePath: "showing some ... path aka link..."
displayName: "Project name 03"
}
ListElement {
prettyFilePath: "showing some ... path aka link..."
displayName: "Project name 04"
}
ListElement {
prettyFilePath: "showing some ... path aka link..."
displayName: "Project name 05"
}
ListElement {
prettyFilePath: "showing some ... path aka link test..."
displayName: "Project name 06"
}
ListElement {
prettyFilePath: "showing some ... path aka link... blup"
displayName: "Project name 07"
}
ListElement {
prettyFilePath: "showing some ... bla path aka link..."
displayName: "Project name 08"
}
}

View File

@@ -1,50 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
sessionName: "Session 01"
}
ListElement {
sessionName: "Session 02"
}
ListElement {
sessionName: "Session 03"
}
ListElement {
sessionName: "Session 04"
}
ListElement {
sessionName: "Session 05"
}
ListElement {
sessionName: "Session 07"
}
ListElement {
sessionName: "Session 08"
}
}

View File

@@ -1,114 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
name: "Main Windows"
description: "All the standard features of application main windows are provided by Qt. Main windows can have pull down menus, tool bars, and dock windows. These separate forms of user input are unified in an integrated action system that also supports keyboard shortcuts and accelerator keys in menu items."
imageSource: "images/mockup/mainwindow-examples.png"
isVideo: false
}
ListElement {
name: "Layouts"
description: "t uses a layout-based approach to widget management. Widgets are arranged in the optimal positions in windows based on simple layout rules, leading to a consistent look and feel. Custom layouts can be used to provide more control over the positions and sizes of child widgets."
imageSource: "images/mockup/layout-examples.png"
isVideo: false
}
ListElement {
name: "Some Video"
description: "tem views are widgets that typically display data sets. Qt 4's model/view framework lets you handle large data sets by separating the underlying data from the way it is represented to the user, and provides support for customized rendering through the use of delegates."
imageSource: "images/mockup/"
isVideo: true
videoLength: "2:20"
}
ListElement {
name: "Drag and Drop"
description: "Qt supports native drag and drop on all platforms via an extensible MIME-based system that enables applications to send data to each other in the most appropriate formats. Drag and drop can also be implemented for internal use by applications."
imageSource: "images/mockup/draganddrop-examples.png"
isVideo: false
}
ListElement {
name: "Some Video"
description: "Qt 4 makes it easier than ever to write multithreaded applications. More classes have been made usable from non-GUI threads, and the signals and slots mechanism can now be used to communicate between threads. The QtConcurrent namespace includes a collection of classes and functions for straightforward concurrent programming."
imageSource: "images/mockup/"
isVideo: true
videoLength: "6:40"
}
ListElement {
name: "Some Video"
description: "Qt provides support for integration with OpenGL implementations on all platforms, giving developers the opportunity to display hardware accelerated 3D graphics alongside a more conventional user interface. Qt provides support for integration with OpenVG implementations on platforms with suitable drivers."
imageSource: ""
isVideo: true
videoLength: "7:40"
}
ListElement {
name: "Some Video"
description: "Qt is provided with an extensive set of network classes to support both client-based and server side network programming."
imageSource: "images/mockup/"
isVideo: true
videoLength: "2:30"
}
ListElement {
name: "Qt Designer"
description: "Qt Designer is a capable graphical user interface designer that lets you create and configure forms without writing code. GUIs created with Qt Designer can be compiled into an application or created at run-time."
imageSource: "images/mockup/designer-examples.png"
isVideo: false
}
ListElement {
name: "Qt Script"
description: "Qt is provided with a powerful embedded scripting environment through the QtScript classes."
imageSource: "images/mockup/qtscript-examples.png"
isVideo: false
}
ListElement {
name: "Desktop"
description: "Qt provides features to enable applications to integrate with the user's preferred desktop environment. Features such as system tray icons, access to the desktop widget, and support for desktop services can be used to improve the appearance of applications and take advantage of underlying desktop facilities."
imageSource: "images/mockup/desktop-examples.png"
isVideo: false
}
ListElement {
name: "Caption"
description: "Description"
imageSource: "image/mockup/penguin.png"
isVideo: false
}
ListElement {
name: "Caption"
description: "Description"
imageSource: "images/mockup/penguin.png"
isVideo: false
}
}

View File

@@ -1,85 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import widgets 1.0
Item {
anchors.fill: parent
ComboBox {
id: comboBox
anchors.verticalCenter: searchBar.verticalCenter
width: 200
anchors.leftMargin: 30
anchors.left: parent.left
model: exampleSetModel
textRole: "text"
onCurrentIndexChanged: {
if (comboBox.model === undefined)
return;
examplesModel.filterForExampleSet(currentIndex)
}
property int theIndex: examplesModel.exampleSetIndex
onTheIndexChanged: {
if (comboBox.model === undefined)
return;
if (theIndex != currentIndex)
currentIndex = theIndex;
}
}
SearchBar {
id: searchBar
y: screenDependHeightDistance
anchors.left: comboBox.right
anchors.leftMargin: 18
anchors.rightMargin: 20
anchors.right: parent.right
text: examplesModel.searchString
placeholderText: qsTr("Search in Examples...")
onTextChanged: examplesModel.setSearchString(text)
}
CustomizedGridView {
id: grid
anchors.left: parent.left
anchors.right: parent.right
anchors.top: searchBar.bottom
anchors.bottom: parent.bottom
anchors.topMargin: screenDependHeightDistance
model: examplesModel
}
}

View File

@@ -1,58 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import widgets 1.0
Item {
anchors.fill: parent
SearchBar {
id: searchBar
y: screenDependHeightDistance
anchors.right: parent.right
anchors.rightMargin: 20
anchors.left: parent.left
anchors.leftMargin: 30
text: tutorialsModel.searchString
placeholderText: qsTr("Search in Tutorials...")
onTextChanged: tutorialsModel.setSearchString(text)
}
CustomizedGridView {
id: grid
anchors.left: parent.left
anchors.right: parent.right
anchors.top: searchBar.bottom
anchors.bottom: parent.bottom
anchors.topMargin: screenDependHeightDistance
model: tutorialsModel
}
}

View File

@@ -1,85 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
Button {
id: button
style: touchStyle
iconSource: ""
Component {
id: touchStyle
ButtonStyle {
padding.left: button.iconSource != "" ? 38 : 14
padding.right: 14
background: Item {
anchors.fill: parent
implicitWidth: 160
implicitHeight: 30
Image {
id: icon
x: 11
y: 8
z: 1
height: 16
width: 16
source: button.iconSource
visible: button.iconSource != ""
}
Rectangle {
id: rectangle
anchors.fill: parent
color: (button.checked || button.pressed)
? creatorTheme.Welcome_ForegroundPrimaryColor
: (button.hovered
? creatorTheme.Welcome_HoverColor
: creatorTheme.Welcome_ButtonBackgroundColor)
border.width: 1
border.color: (button.checked || button.pressed)
? creatorTheme.Welcome_ForegroundPrimaryColor
: creatorTheme.Welcome_ForegroundSecondaryColor
radius: creatorTheme.FlatToolBars ? 0 : 4
}
}
label: Text {
id: text
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
text: button.text
color: (button.checked || button.pressed)
? creatorTheme.Welcome_BackgroundColor
: creatorTheme.Welcome_TextColor
font.pixelSize: 15
font.bold: false
smooth: true
}
}
}
}

View File

@@ -1,30 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
ComboBox {
}

View File

@@ -1,105 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
QtObject {
property alias linkFont: linkText.font
property alias standardCaption: standardCaptionText.font
property alias standstandardDescription: standardDescriptionText.font
property alias italicDescription: italicDescriptionText.font
property alias boldDescription: boldText.font
property alias smallPath: smallPathText.font
property alias smallNumber: smallNumberText.font
property list<Item> texts: [
Text {
id: smallPathText
visible: false
font.pixelSize: 13
font.family: "Helvetica"
},
Text {
id: linkText
visible: false
font.pixelSize: 13
//font.bold: true
font.family: "Helvetica"
},
Text {
id: smallNumberText
visible: false
font.pixelSize: 10
font.family: "Helvetica"
},
Text {
id: boldText
visible: false
font.pixelSize: 13
font.bold: true
font.family: "Helvetica"
},
Text {
id: standardCaptionText
visible: false
font.family: "Helvetica"
font.pixelSize: 14
},
Text {
id: standardDescriptionText
visible: false
font.pixelSize: 13
font.bold: false
font.family: "Helvetica"
},
Text {
id: italicDescriptionText
visible: false
font.pixelSize: 13
font.bold: false
font.family: "Helvetica"
}
]
}

View File

@@ -1,65 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
ScrollView {
property alias model: gridView.model
GridView {
id: gridView
anchors.fill: parent
anchors.leftMargin: 20
anchors.rightMargin: 20
interactive: false
cellHeight: 240
cellWidth: 216
delegate: Delegate {
id: delegate
property bool isHelpImage: model.imageUrl.search(/qthelp/) != -1
property string sourcePrefix: isHelpImage ? "image://helpimage/" : ""
property string mockupSource: model.imageSource
property string helpSource: (model.imageUrl !== "" && model.imageUrl !== undefined) ? sourcePrefix + encodeURI(model.imageUrl) : ""
imageSource: isVideo ? "" : (model.imageSource === undefined ? delegate.helpSource : delegate.mockupSource)
videoSource: isVideo ? (model.imageSource === undefined ? model.imageUrl : mockupSource) : ""
caption: model.name;
description: model.description
isVideo: model.isVideo === true
videoLength: model.videoLength !== undefined ? model.videoLength : ""
tags: model.tags
}
}
}

View File

@@ -1,372 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Rectangle {
id: delegate
height: 240
width: 216
color: creatorTheme.Welcome_BackgroundColor
property alias caption: captionItem.text
property alias imageSource: imageItem.source
property alias videoSource: videoIcon.source
property alias description: descriptionItem.text
property bool isVideo: false
property alias videoLength: length.text
property alias tags: repeater.model
function appendTag(tag) {
var tagStr = "tag:" + '"' + tag + '"'
if (searchBar.text === "")
searchBar.text = tagStr
else
searchBar.text += " " + tagStr
}
BorderImage {
id: image1
x: 11
y: 8
width: 196
height: 153
anchors.horizontalCenter: parent.horizontalCenter
border.bottom: 4
border.right: 4
border.top: 4
border.left: 4
source: "images/dropshadow.png"
Image {
id: imageItem
visible: !delegate.isVideo
anchors.centerIn: parent
asynchronous: true
sourceSize.height: 145
sourceSize.width: 188
fillMode: Image.Center
}
Image {
id: videoIcon
visible: delegate.isVideo
anchors.centerIn: parent
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
asynchronous: true
}
NativeText {
id: length
visible: delegate.isVideo
x: 87
y: 130
color: "#555555"
text: delegate.videoLength
anchors.horizontalCenter: parent.horizontalCenter
font.bold: true
font.family: "Helvetica"
font.pixelSize: 14
}
}
Rectangle {
id: rectangle2
y: 161
width: 200
height: 69
color: creatorTheme.Welcome_BackgroundColor
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.left: parent.left
}
NativeText {
id: captionItem
x: 16
y: 170
color: creatorTheme.Welcome_TextColor
text: qsTr("2D PAINTING EXAMPLE long description")
elide: Text.ElideRight
anchors.right: parent.right
anchors.rightMargin: 16
anchors.left: parent.left
anchors.leftMargin: 16
wrapMode: Text.WordWrap
maximumLineCount: 1
font: fonts.standardCaption
}
NativeText {
id: descriptionItem
height: 43
color: creatorTheme.Welcome_ForegroundPrimaryColor
text: qsTr("The 2D Painting example shows how QPainter and QGLWidget work together.")
anchors.top: captionItem.bottom
anchors.topMargin: 10
opacity: 0
anchors.left: parent.left
anchors.leftMargin: 16
anchors.right: parent.right
anchors.rightMargin: 16
wrapMode: Text.WordWrap
font: fonts.standstandardDescription
horizontalAlignment: Text.AlignJustify
maximumLineCount: 8
}
Rectangle {
id: rectangle1
x: 16
y: 195
height: 1
color: "#dddcdc"
anchors.left: parent.left
anchors.leftMargin: 10
anchors.right: parent.right
anchors.rightMargin: 10
}
NativeText {
id: tags
x: 16
y: 198
text: qsTr("Tags:")
color: creatorTheme.Welcome_ForegroundSecondaryColor
smooth: true
font.italic: false
font.pixelSize: 11
wrapMode: Text.WordWrap
font.family: "Helvetica"
font.bold: false
}
Rectangle {
id: rectangle3
x: 10
height: 1
color: "#dddcdc"
visible: false
anchors.top: captionItem.bottom
anchors.topMargin: 4
anchors.rightMargin: 10
anchors.right: parent.right
anchors.leftMargin: 10
anchors.left: parent.left
}
Rectangle {
id: border
color: "#00000000"
radius: creatorTheme.FlatToolBars ? 0 : 6
anchors.rightMargin: 4
anchors.leftMargin: 4
anchors.bottomMargin: 4
anchors.topMargin: 1
visible: false
anchors.fill: parent
border.color: "#dddcdc"
}
MouseArea {
id: mousearea1
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
delegate.state="hover"
}
onExited: {
delegate.state=""
}
onClicked: {
var oldPauseAnimation = pauseAnimation.duration
pauseAnimation.duration = 10;
delegate.state = ""
pauseAnimation.duration = oldPauseAnimation;
if (model.isVideo)
gettingStarted.openUrl(model.videoUrl);
else if (model.hasSourceCode)
gettingStarted.openProject(model.projectPath,
model.filesToOpen,
model.mainFile,
model.docUrl,
model.dependencies,
model.platforms)
else
gettingStarted.openHelpInExtraWindow(model.docUrl);
}
}
states: [
State {
name: "hover"
PropertyChanges {
target: rectangle2
x: 0
y: 4
width: 216
height: 236
}
PropertyChanges {
target: captionItem
y: 14
maximumLineCount: 2
}
PropertyChanges {
target: descriptionItem
opacity: 1
}
PropertyChanges {
target: rectangle3
x: 10
y: 52
visible: true
anchors.rightMargin: 10
anchors.leftMargin: 10
}
PropertyChanges {
target: border
visible: true
}
}
]
transitions: [
Transition {
from: ""
to: "hover"
SequentialAnimation {
PauseAnimation { id: pauseAnimation; duration: 200 }
ParallelAnimation {
PropertyAnimation {
properties: "y, height"
duration: 100
}
SequentialAnimation {
PropertyAction {
property: "maximumLineCount"
}
PauseAnimation { duration: 60 }
PropertyAnimation {
properties: "opacity"
duration: 150
}
}
}
}
},
Transition {
from: "hover"
to: ""
SequentialAnimation {
PauseAnimation { duration: 100 }
ParallelAnimation {
PropertyAnimation {
properties: "opacity"
duration: 60
}
SequentialAnimation {
PauseAnimation { duration: 60 }
PropertyAction {
property: "maximumLineCount"
}
PropertyAnimation {
properties: "y, height"
duration: 100
}
}
}
}
}
]
Flow {
y: 198
width: 159
height: 32
anchors.left: tags.right
anchors.leftMargin: 6
spacing: 2
Repeater {
id: repeater
model: mockupTags
NativeText {
id: text4
text: modelData
smooth: true
font.pixelSize: 11
height: 12
font.family: "Helvetica" //setting the pixelSize will set the family back to the default
font.underline: tagMouseArea.containsMouse
color: creatorTheme.Welcome_LinkColor
wrapMode: Text.WordWrap
property bool hugeTag: (text.length > 12) && index > 1
property bool isExampleTag: text === "example"
visible: !hugeTag && !isExampleTag && index < 8 && y < 32
MouseArea {
id: tagMouseArea
anchors.fill: parent
onClicked: appendTag(modelData)
// hoverEnabled: true
cursorShape: Qt.PointingHandCursor
}
}
}
}
ListModel {
id: mockupTags
ListElement {
modelData: "painting"
}
ListElement {
modelData: "Qt Quick"
}
ListElement {
modelData: "OpenGl"
}
}
}

View File

@@ -1,69 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Rectangle {
property string iconSource
property string title: "title"
property string openUrl
property string openHelpUrl
height: 30
width: 231
color: mouseArea.containsMouse
? creatorTheme.Welcome_HoverColor
: creatorTheme.Welcome_BackgroundColor
Image {
id: image
width: 16
height: 16
x: 34
source: iconSource
anchors.verticalCenter: parent.verticalCenter
}
NativeText {
text: title
anchors.verticalCenter: parent.verticalCenter
anchors.left: image.right
anchors.leftMargin: 8
color: creatorTheme.Welcome_TextColor
font.pixelSize: 11
font.underline: mouseArea.containsMouse
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
if (openUrl)
gettingStarted.openUrl(openUrl);
if (openHelpUrl)
gettingStarted.openHelp(openHelpUrl);
}
}
}

View File

@@ -1,32 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Text {
renderType: useNativeText ? Text.NativeRendering : Text.QtRendering
Accessible.name: text
Accessible.role: Accessible.StaticText
}

View File

@@ -1,46 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Rectangle {
id: pageLoader
property alias model: repeater.model
property int currentIndex: 0
Repeater {
id: repeater
anchors.fill: parent
Loader {
id: loader
anchors.fill: parent
property bool isCurrentIndex: index === pageLoader.currentIndex
source: isCurrentIndex ? pageLocation : ""
}
}
}

View File

@@ -1,97 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Rectangle {
id: projectItem
width: Math.max(projectNameText.width, pathText.width) + projectNameText.x + 11
height: 48
color: mouseArea.containsMouse
? creatorTheme.Welcome_HoverColor
: creatorTheme.Welcome_BackgroundColor
property alias number: number.text
property alias projectName: projectNameText.text
property alias projectPath: pathText.text
property alias projectTooltip: projectItemTooltip.text
function requestProject() {
projectWelcomePage.requestProject(filePath);
}
Image {
id: icon
x: 11
height: 16
width: 16
anchors.verticalCenter: projectNameText.verticalCenter
source: "image://icons/project/Welcome_ForegroundSecondaryColor"
}
NativeText {
id: number
anchors.right: icon.left
anchors.rightMargin: 3
anchors.verticalCenter: projectNameText.verticalCenter
color: creatorTheme.Welcome_ForegroundSecondaryColor
font: fonts.smallNumber
}
NativeText {
id: projectNameText
x: 36
height: 30
anchors.top: parent.top
verticalAlignment: Text.AlignVCenter
font.pixelSize: fonts.linkFont.pixelSize
font.family: fonts.linkFont.family
font.underline: mouseArea.containsMouse
color: creatorTheme.Welcome_LinkColor
}
NativeText {
id: pathText
anchors.left: projectNameText.left
anchors.bottom: projectItem.bottom
anchors.bottomMargin: 6
color: creatorTheme.Welcome_ForegroundPrimaryColor
font: fonts.smallPath
}
ToolTip {
id: projectItemTooltip
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: projectItem.requestProject()
onEntered: projectItemTooltip.showAt(mouseX, mouseY)
onExited: projectItemTooltip.hide()
}
}

View File

@@ -1,72 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
Rectangle {
id: projectList
height: column.height + 200
width: column.width
color: creatorTheme.Welcome_BackgroundColor
property alias model: repeater.model
Column {
id: column
Repeater {
id: repeater
ProjectItem {
function maybeNumber() {
return index < 9 ? "%1".arg(index + 1) : "";
}
function tooltipText() {
var shortcutText = welcomeMode.recentProjectsShortcuts[index];
if (shortcutText)
return qsTr("Opens project \"%1\" (%2)").arg(displayName).arg(shortcutText);
else
return qsTr("Opens project \"%1\"").arg(displayName);
}
number: maybeNumber()
projectName: displayName
projectPath: prettyFilePath
projectTooltip: tooltipText()
}
}
}
Connections {
target: welcomeMode
onOpenRecentProjectTriggered: {
var item = repeater.itemAt(index);
if (item)
item.requestProject();
}
}
}

View File

@@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
Rectangle {
id: searchBar
width: 930
height: 30
color: creatorTheme.Welcome_BackgroundColor
border.color: creatorTheme.Welcome_ForegroundSecondaryColor
property alias placeholderText: lineEdit.placeholderText
property alias text: lineEdit.text
TextField {
id: lineEdit
anchors.topMargin: 1
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 12
anchors.leftMargin: 12
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
font.pixelSize: 14
placeholderText: qsTr("Search...")
style: TextFieldStyle {
placeholderTextColor: creatorTheme.Welcome_ForegroundSecondaryColor
textColor: creatorTheme.Welcome_TextColor
background: Item {
}
}
}
Accessible.name: text
Accessible.description: placeholderText
Accessible.role: Accessible.EditableText
}

View File

@@ -1,42 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
NativeText {
id: root
signal clicked()
text: qsTr("Clone")
font.pixelSize: 13
font.underline: area.containsMouse
color: creatorTheme.Welcome_LinkColor
MouseArea {
id: area
anchors.fill: parent
hoverEnabled: true
onClicked: root.clicked()
anchors.margins: -6
}
}

View File

@@ -1,238 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Item {
id: delegate
property bool expanded: false
height: columns.height
width: columns.width
property alias number: number.text
property alias name: titleText.text
property alias tooltip: titleAreaTooltip.text
function requestSession() {
root.model.switchToSession(sessionName);
}
Column {
id: columns
Rectangle {
id: rectangle
height: 30
width: 260
color: (titleArea.containsMouse || collapseArea.containsMouse || delegate.expanded)
? creatorTheme.Welcome_HoverColor
: creatorTheme.Welcome_BackgroundColor
Image {
id: sessionIcon
source: "image://icons/session/Welcome_ForegroundSecondaryColor"
x: 11
anchors.verticalCenter: titleText.verticalCenter
height: 16
width: 16
}
NativeText {
id: number
anchors.verticalCenter: titleText.verticalCenter
anchors.right: sessionIcon.left
anchors.rightMargin: 3
color: creatorTheme.Welcome_ForegroundSecondaryColor
font: fonts.smallNumber
}
NativeText {
id: titleText
x: 36
height: 30
width: parent.width - x
anchors.top: parent.top
elide: Text.ElideRight
color: creatorTheme.Welcome_LinkColor
verticalAlignment: Text.AlignVCenter
font.pixelSize: fonts.linkFont.pixelSize
font.family: fonts.linkFont.family
font.underline: titleArea.containsMouse
}
ToolTip {
id: titleAreaTooltip
}
MouseArea {
id: titleArea
hoverEnabled: true
anchors.fill: parent
onClicked: delegate.requestSession()
onEntered: titleAreaTooltip.showAt(mouseX, mouseY)
onExited: titleAreaTooltip.hide()
}
}
Rectangle {
z: -1
property int margin: 6
id: details
height: expanded ? innerColumn.height + margin + 16 : 0
width: titleArea.width + collapseArea.width
color: creatorTheme.Welcome_HoverColor
clip: true
visible: false
Behavior on height {
SequentialAnimation {
ScriptAction {
script: if (expanded) details.visible = true;
}
NumberAnimation {
duration: 180
easing.type: Easing.InOutQuad
}
ScriptAction {
script: if (!expanded) details.visible = false;
}
}
}
Column {
x: titleText.x
y: parent.margin
id: innerColumn
spacing: 12
Repeater {
model: details.visible ? projectsPath : 0
delegate: Column {
spacing: 4
NativeText {
text: projectsName[index]
font: fonts.smallPath
color: creatorTheme.Welcome_TextColor
width: titleText.width
}
NativeText {
text: modelData
font: fonts.smallPath
elide: Text.ElideRight
color: creatorTheme.Welcome_ForegroundPrimaryColor
width: titleText.width
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
toolTip.show();
}
onExited: {
toolTip.hide()
}
}
ToolTip {
x: 10
y: 20
id: toolTip
text: modelData
}
}
}
}
Flow {
width: parent.width - 2 * parent.margin
height: 18
spacing: 6
SessionActionLabel {
text: qsTr("Clone")
onClicked: root.model.cloneSession(sessionName)
}
Rectangle {
visible: !defaultSession
width: 1;
height: 13;
color: creatorTheme.Welcome_ForegroundSecondaryColor
}
SessionActionLabel {
visible: !defaultSession
text: qsTr("Rename")
onClicked: root.model.renameSession(sessionName)
}
Rectangle {
visible: y === 0 && !defaultSession
width: 1;
height: 13;
color: creatorTheme.Welcome_ForegroundSecondaryColor
}
SessionActionLabel {
visible: !defaultSession
text: qsTr("Delete")
onClicked: root.model.deleteSession(sessionName)
}
}
}
}
}
Item {
x: rectangle.width
width: 28
height: titleArea.height
Rectangle {
id: collapseButton
anchors.fill: parent
color: (collapseArea.containsMouse || delegate.expanded)
? creatorTheme.Welcome_HoverColor
: creatorTheme.Welcome_BackgroundColor
Image {
x: 6
y: 7
visible: (collapseArea.containsMouse || delegate.expanded || titleArea.containsMouse)
source: "image://icons/expandarrow/Welcome_ForegroundSecondaryColor"
rotation: delegate.expanded ? 180 : 0
height: 16
width: 16
}
}
MouseArea {
id: collapseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
delegate.expanded = !delegate.expanded;
delegate.ListView.view.positionViewAtIndex(index, ListView.Contain);
}
}
}
}

View File

@@ -1,84 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import widgets 1.0
Rectangle {
id: root
property var model
height: content.contentHeight + 200
color: creatorTheme.Welcome_BackgroundColor
ListView {
id: content
model: root.model
anchors.fill: parent
snapMode: ListView.SnapToItem
clip: true
interactive: false
delegate: SessionItem {
function fullSessionName()
{
var newSessionName = sessionName
if (model.lastSession && sessionList.isDefaultVirgin())
newSessionName = qsTr("%1 (last session)").arg(sessionName);
else if (model.activeSession && !sessionList.isDefaultVirgin())
newSessionName = qsTr("%1 (current session)").arg(sessionName);
return newSessionName;
}
function maybeNumber() {
return index < 9 ? "%1".arg(index + 1) : "";
}
function tooltipText() {
var shortcutText = welcomeMode.sessionsShortcuts[index];
if (shortcutText)
return qsTr("Opens session \"%1\" (%2)").arg(sessionName).arg(shortcutText);
else
return qsTr("Opens session \"%1\"").arg(sessionName);
}
number: maybeNumber()
name: fullSessionName()
tooltip: tooltipText()
}
}
Connections {
target: welcomeMode
// this is coming from session shortcuts
onOpenSessionTriggered: {
if (index < content.count) {
content.currentIndex = index;
// calling a javascript method on the SessionItem which knows its own current sessionName
content.currentItem.requestSession();
}
}
}
}

View File

@@ -1,144 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Window 2.1
import QtQuick.Layouts 1.0
ColumnLayout {
id: root
spacing: 0
property alias currentIndex: tabs.currentIndex
property alias model: tabs.model
readonly property int lrPadding: 34
Item {
id: modeArea
z: 1
Layout.fillWidth: true
Layout.preferredWidth: tabs.width + lrPadding * 2
Layout.preferredHeight: tabs.height + screenDependHeightDistance * 2
Rectangle {
color: creatorTheme.Welcome_BackgroundColor
anchors.fill: parent
}
Tabs {
anchors.verticalCenter: parent.verticalCenter
x: lrPadding
width: Math.max(modeArea.width - lrPadding * 2, implicitWidth)
id: tabs
spacing: Math.round((screenDependHeightDistance / count) + 10)
}
}
Rectangle {
color: creatorTheme.Welcome_BackgroundColor
Layout.fillWidth: true
Layout.preferredWidth: upperColumn.width + 20
Layout.fillHeight: true
ColumnLayout {
id: upperColumn
x: lrPadding
spacing: 8
property int spacerHeight: screenDependHeightDistance
Item {
Layout.preferredHeight: upperColumn.spacerHeight
}
NativeText {
text: qsTr("New to Qt?")
color: creatorTheme.Welcome_TextColor
font.pixelSize: 18
}
NativeText {
id: gettingStartedText
Layout.preferredWidth: upperColumn.width
text: qsTr("Learn how to develop your own applications and explore Qt Creator.")
color: creatorTheme.Welcome_ForegroundPrimaryColor
font.pixelSize: 12
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
Item {
Layout.preferredHeight: 4
}
Button {
id: gettingStartedButton
x: 4
text: qsTr("Get Started Now")
onClicked: gettingStarted.openHelp("qthelp://org.qt-project.qtcreator/doc/index.html")
}
Item {
Layout.preferredHeight: upperColumn.spacerHeight * 2
}
}
ColumnLayout {
anchors.top: upperColumn.bottom
anchors.topMargin: 8
IconAndLink {
iconSource: "image://icons/qtaccount"
title: qsTr("Qt Account")
openUrl: "https://account.qt.io"
}
IconAndLink {
iconSource: "image://icons/community"
title: qsTr("Online Community")
openUrl: "http://forum.qt.io"
}
IconAndLink {
iconSource: "image://icons/blogs"
title: qsTr("Blogs")
openUrl: "http://planet.qt.io"
}
IconAndLink {
iconSource: "image://icons/userguide"
title: qsTr("User Guide")
openHelpUrl: "qthelp://org.qt-project.qtcreator/doc/index.html"
}
}
}
}

View File

@@ -1,55 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.1 as QQControls
import QtQuick.Layouts 1.1
ColumnLayout {
id: customTab
property alias model: repeater.model
property int count: repeater.count
signal itemChanged
property int currentIndex: -1
onCurrentIndexChanged: welcomeMode.activePlugin = currentIndex
Component.onCompleted: currentIndex = welcomeMode.activePlugin
QQControls.ExclusiveGroup {
id: group
}
Repeater {
id: repeater
Button {
Layout.fillWidth: true
text: title
checkable: true
exclusiveGroup: group
checked: customTab.currentIndex === index
onCheckedChanged: if (checked) customTab.currentIndex = index
}
}
}

View File

@@ -1,98 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
Item {
id: toolTip
property alias text: text.text
property int margin: 4
width: text.width + margin * 2
height: text.height + margin * 2
opacity: 0
property Item originalParent: parent
property int oldX: x
property int oldY: y
Behavior on opacity {
SequentialAnimation {
PauseAnimation { duration: opacity === 0 ? 1000 : 0 }
PropertyAnimation { duration: 50 }
}
}
function show() {
toolTip.originalParent = toolTip.parent;
var p = toolTip.parent;
while (p.parent != undefined && p.parent.parent != undefined)
p = p.parent
toolTip.parent = p;
toolTip.oldX = toolTip.x
toolTip.oldY = toolTip.y
var globalPos = mapFromItem(toolTip.originalParent, toolTip.oldX, toolTip.oldY);
toolTip.x = Math.min(globalPos.x + toolTip.oldX, toolTip.parent.width - toolTip.width);
toolTip.y = Math.min(globalPos.y + toolTip.oldY, toolTip.parent.height - toolTip.height);
toolTip.opacity = 1;
}
function showAt(x, y) {
toolTip.x = x;
toolTip.y = y;
show();
}
function hide() {
toolTip.opacity = 0;
var oldClip = originalParent.clip
originalParent.clip = false
toolTip.parent = originalParent
originalParent.clip = true
originalParent.clip = oldClip
toolTip.x = toolTip.oldX
toolTip.y = toolTip.oldY
}
Rectangle {
anchors.fill: parent
color: creatorTheme.Welcome_BackgroundColor
border.width: 1
border.color: creatorTheme.Welcome_ForegroundSecondaryColor
}
NativeText {
x: toolTip.margin
y: toolTip.margin
id: text
color: creatorTheme.Welcome_TextColor
}
}

View File

@@ -1,35 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QmlDesigner 1.0
DummyContextObject {
property variant model: QtObject {
property string name: "Calculator"
property string description: "his demo shows how to write a simple calculator application in QML and JavaScript."
property string imageSource: "http://doc.qt.io/qt-4.8/images/qml-calculator-example-small.png"
}
}

View File

@@ -1,34 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
import QmlDesigner 1.0
DummyContextObject {
property Item scrollArea: Item {
width: 800
height: 300
}
}

View File

@@ -1,55 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
name: "Calculator with more info on something bla bla on Qt if you know"
description: "his demo shows how to write a simple calculator application in QML and JavaScript."
imageSource: "http://doc.qt.io/qt-4.8/images/qml-calculator-example-small.png"
}
ListElement {
name: "RSS News Reader"
description: "This demo shows how to write a RSS news reader in QML."
imageSource: "http://doc.qt.io/qt-4.8/images/qml-rssnews-demo-small.png"
}
ListElement {
name: "Twitter"
description: "This demo shows how to write a mobile Twitter search client in QML. Use it to see what people think about Qt Quick!"
imageSource: "http://doc.qt.io/qt-4.8/images/qml-twitter-demo-small.png"
}
ListElement {
name: "Basic Drawing Example"
description: "The Basic Drawing example shows how to display basic graphics primitives in a variety of styles using the QPainter class."
imageSource: "http://doc.qt.io/qt-4.8/images/basicdrawing-example.png"
}
ListElement {
name: "Border Layout Example"
description: "The Border Layout example shows how to create a custom layout that arranges child widgets according to a simple set of rules. The Border Layout example shows how to create a custom layout that arranges child widgets according to a simple set of rules. The Border Layout example shows how to create a custom layout that arranges child widgets according to a simple set of rules. The Border Layout example shows how to create a custom layout that arranges child widgets according to a simple set of rules."
imageSource: "http://doc.qt.io/qt-4.8/images/borderlayout-example.png"
}
}

View File

@@ -1,35 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
modelData: "bla1"
}
ListElement {
modelData: "bla2"
}
}

View File

@@ -1,44 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
title: "Getting started"
hasSearchBar: false
pageLocation: "gettingstarted"
}
ListElement {
title: "Develop"
hasSearchBar: false
pageLocation: "develop"
}
ListElement {
title: "Examples"
hasSearchBar: true
pageLocation: "examples"
}
}

View File

@@ -1,35 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
import QtQuick 2.1
ListModel {
ListElement {
title: "title1"
}
ListElement {
title: "title2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -1,23 +0,0 @@
CustomColors 1.0 CustomColors.qml
ProjectItem 1.0 ProjectItem.qml
CustomFonts 1.0 CustomFonts.qml
LinkedText 1.0 LinkedText.qml
RecentProjects 1.0 RecentProjects.qml
CustomizedGridView 1.0 CustomizedGridView.qml
LinksBar 1.0 LinksBar.qml
SearchBar 1.0 SearchBar.qml
CustomTab 1.0 CustomTab.qml
Logo 1.0 Logo.qml
SessionItem 1.0 SessionItem.qml
Delegate 1.0 Delegate.qml
PageCaption 1.0 PageCaption.qml
Sessions 1.0 Sessions.qml
Feedback 1.0 Feedback.qml
PageLoader 1.0 PageLoader.qml
ToolTip 1.0 ToolTip.qml
ComboBox 1.0 ComboBox.qml
NativeText 1.0 NativeText.qml
Button 1.0 Button.qml
Tabs 1.0 Tabs.qml
SideBar 1.0 SideBar.qml

View File

@@ -25,8 +25,19 @@
#include "iwelcomepage.h" #include "iwelcomepage.h"
#include "icore.h"
#include <utils/icon.h>
#include <utils/theme/theme.h>
#include <QHBoxLayout>
#include <QLabel>
#include <QMetaEnum>
#include <QPixmap>
#include <QUrl> #include <QUrl>
using namespace Utils;
namespace Core { namespace Core {
IWelcomePage::IWelcomePage() IWelcomePage::IWelcomePage()
@@ -37,4 +48,159 @@ IWelcomePage::~IWelcomePage()
{ {
} }
} // namespace Utils int IWelcomePage::screenDependHeightDistance()
{
return std::min(50, std::max(16, ICore::mainWindow()->height() / 30));
}
static QPalette buttonPalette(bool isActive, bool isCursorInside, bool forText)
{
QPalette pal;
Theme *theme = Utils::creatorTheme();
if (isActive) {
if (forText) {
pal.setColor(QPalette::Background, theme->color(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_BackgroundColor));
} else {
pal.setColor(QPalette::Background, theme->color(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundPrimaryColor));
}
} else {
if (isCursorInside) {
if (forText) {
pal.setColor(QPalette::Background, theme->color(Theme::Welcome_HoverColor));
pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_HoverColor));
pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_TextColor));
} else {
pal.setColor(QPalette::Background, theme->color(Theme::Welcome_HoverColor));
pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundSecondaryColor));
}
} else {
if (forText) {
pal.setColor(QPalette::Background, theme->color(Theme::Welcome_ForegroundPrimaryColor));
pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_BackgroundColor));
pal.setColor(QPalette::WindowText, theme->color(Theme::Welcome_TextColor));
} else {
pal.setColor(QPalette::Background, theme->color(Theme::Welcome_BackgroundColor));
pal.setColor(QPalette::Foreground, theme->color(Theme::Welcome_ForegroundSecondaryColor));
}
}
}
return pal;
}
class WelcomePageButtonPrivate
{
public:
WelcomePageButtonPrivate(WelcomePageButton *parent) : q(parent) {}
bool isActive() const;
void doUpdate(bool cursorInside);
WelcomePageButton *q;
QHBoxLayout *m_layout;
QLabel *m_label;
QLabel *m_icon = nullptr;
std::function<void()> onClicked;
std::function<bool()> activeChecker;
};
WelcomePageButton::WelcomePageButton(QWidget *parent)
: QFrame(parent), d(new WelcomePageButtonPrivate(this))
{
setAutoFillBackground(true);
setFrameShape(QFrame::Box);
setFrameShadow(QFrame::Plain);
setPalette(buttonPalette(false, false, false));
QFont f = font();
f.setPixelSize(15);
d->m_label = new QLabel(this);
d->m_label->setFont(f);
d->m_label->setPalette(buttonPalette(false, false, true));
d->m_layout = new QHBoxLayout;
d->m_layout->setContentsMargins(13, 5, 20, 5);
d->m_layout->setSpacing(0);
d->m_layout->addWidget(d->m_label);
setLayout(d->m_layout);
}
WelcomePageButton::~WelcomePageButton()
{
delete d;
}
void WelcomePageButton::mousePressEvent(QMouseEvent *)
{
if (d->onClicked)
d->onClicked();
}
void WelcomePageButton::enterEvent(QEvent *)
{
d->doUpdate(true);
}
void WelcomePageButton::leaveEvent(QEvent *)
{
d->doUpdate(false);
}
bool WelcomePageButtonPrivate::isActive() const
{
return activeChecker && activeChecker();
}
void WelcomePageButtonPrivate::doUpdate(bool cursorInside)
{
const bool active = isActive();
q->setPalette(buttonPalette(active, cursorInside, false));
const QPalette lpal = buttonPalette(active, cursorInside, true);
m_label->setPalette(lpal);
if (m_icon)
m_icon->setPalette(lpal);
q->update();
}
void WelcomePageButton::setText(const QString &text)
{
d->m_label->setText(text);
}
void WelcomePageButton::setIcon(const QPixmap &pixmap)
{
if (!d->m_icon) {
d->m_icon = new QLabel(this);
d->m_layout->insertWidget(0, d->m_icon);
d->m_layout->insertSpacing(1, 10);
}
d->m_icon->setPixmap(pixmap);
}
void WelcomePageButton::setActiveChecker(const std::function<bool ()> &value)
{
d->activeChecker = value;
}
void WelcomePageButton::recheckActive()
{
bool isActive = d->isActive();
d->doUpdate(isActive);
}
void WelcomePageButton::click()
{
if (d->onClicked)
d->onClicked();
}
void WelcomePageButton::setOnClicked(const std::function<void ()> &value)
{
d->onClicked = value;
if (d->isActive())
click();
}
} // namespace Core

View File

@@ -29,10 +29,14 @@
#include "id.h" #include "id.h"
#include <QFrame>
#include <QObject> #include <QObject>
#include <QUrl>
QT_FORWARD_DECLARE_CLASS(QQmlEngine) #include <functional>
QT_BEGIN_NAMESPACE
class QPixmap;
QT_END_NAMESPACE
namespace Core { namespace Core {
@@ -41,20 +45,41 @@ class CORE_EXPORT IWelcomePage : public QObject
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString title READ title CONSTANT) Q_PROPERTY(QString title READ title CONSTANT)
Q_PROPERTY(QUrl pageLocation READ pageLocation CONSTANT)
Q_PROPERTY(int priority READ priority CONSTANT) Q_PROPERTY(int priority READ priority CONSTANT)
Q_PROPERTY(bool hasSearchBar READ hasSearchBar CONSTANT)
public: public:
IWelcomePage(); IWelcomePage();
virtual ~IWelcomePage(); virtual ~IWelcomePage();
virtual QUrl pageLocation() const = 0;
virtual QString title() const = 0; virtual QString title() const = 0;
virtual int priority() const { return 0; } virtual int priority() const { return 0; }
virtual void facilitateQml(QQmlEngine *) {}
virtual bool hasSearchBar() const { return false; }
virtual Core::Id id() const = 0; virtual Core::Id id() const = 0;
virtual QWidget *createWidget() const = 0;
static int screenDependHeightDistance();
};
class WelcomePageButtonPrivate;
class CORE_EXPORT WelcomePageButton : public QFrame
{
public:
WelcomePageButton(QWidget *parent);
~WelcomePageButton();
void mousePressEvent(QMouseEvent *) override;
void enterEvent(QEvent *) override;
void leaveEvent(QEvent *) override;
void setText(const QString &text);
void setIcon(const QPixmap &pixmap);
void setOnClicked(const std::function<void ()> &value);
void setActiveChecker(const std::function<bool ()> &value);
void recheckActive();
void click();
private:
WelcomePageButtonPrivate *d;
}; };
} // Core } // Core

View File

@@ -24,18 +24,36 @@
****************************************************************************/ ****************************************************************************/
#include "projectwelcomepage.h" #include "projectwelcomepage.h"
#include "session.h"
#include "sessionmodel.h" #include "sessionmodel.h"
#include "projectexplorer.h" #include "projectexplorer.h"
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/iwizardfactory.h> #include <coreplugin/iwizardfactory.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <utils/algorithm.h> #include <utils/theme/theme.h>
#include <QQmlContext> #include <QAbstractItemDelegate>
#include <QQmlEngine> #include <QAction>
#include <QBoxLayout>
#include <QDir>
#include <QFileInfo>
#include <QHeaderView>
#include <QHelpEvent>
#include <QLabel>
#include <QPainter>
#include <QToolTip>
#include <QTreeView>
using namespace Core;
using namespace Utils;
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
@@ -88,30 +106,12 @@ void ProjectModel::resetProjects()
/////////////////// ///////////////////
void ProjectWelcomePage::facilitateQml(QQmlEngine *engine)
{
m_sessionModel = new SessionModel(this);
m_projectModel = new ProjectModel(this);
QQmlContext *ctx = engine->rootContext();
ctx->setContextProperty(QLatin1String("sessionList"), m_sessionModel);
ctx->setContextProperty(QLatin1String("projectList"), m_projectModel);
ctx->setContextProperty(QLatin1String("projectWelcomePage"), this);
}
QUrl ProjectWelcomePage::pageLocation() const
{
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows
const QString resourcePath = Utils::FileUtils::normalizePathName(Core::ICore::resourcePath());
return QUrl::fromLocalFile(resourcePath + QLatin1String("/welcomescreen/develop.qml"));
}
Core::Id ProjectWelcomePage::id() const Core::Id ProjectWelcomePage::id() const
{ {
return "Develop"; return "Develop";
} }
void ProjectWelcomePage::reloadWelcomeScreenData() void ProjectWelcomePage::reloadWelcomeScreenData() const
{ {
if (m_sessionModel) if (m_sessionModel)
m_sessionModel->resetSessions(); m_sessionModel->resetSessions();
@@ -129,5 +129,427 @@ void ProjectWelcomePage::openProject()
ProjectExplorerPlugin::openOpenProjectDialog(); ProjectExplorerPlugin::openOpenProjectDialog();
} }
///////////////////
static QColor themeColor(Theme::Color role)
{
return Utils::creatorTheme()->color(role);
}
static QFont sizedFont(int size, const QWidget *widget, bool underline = false)
{
QFont f = widget->font();
f.setPixelSize(size);
f.setUnderline(underline);
return f;
}
static QPixmap pixmap(const QString &id, const Theme::Color &color)
{
const QString fileName = QString(":/welcome/images/%1.png").arg(id);
return Icon({{fileName, color}}, Icon::Tint).pixmap();
}
class SessionDelegate : public QAbstractItemDelegate
{
public:
SessionDelegate() {
const int actionsCount = 9;
Context welcomeContext(Core::Constants::C_WELCOME_MODE);
const Id sessionBase = "Welcome.OpenSession";
for (int i = 1; i <= actionsCount; ++i) {
auto act = new QAction(tr("Open Session #%1").arg(i), this);
Command *cmd = ActionManager::registerAction(act, sessionBase.withSuffix(i), welcomeContext);
cmd->setDefaultKeySequence(QKeySequence((UseMacShortcuts ? tr("Ctrl+Meta+%1") : tr("Ctrl+Alt+%1")).arg(i)));
m_sessionShortcuts.append(cmd->keySequence().toString(QKeySequence::NativeText));
// connect(act, &QAction::triggered, this, [this, i] { openSessionTriggered(i-1); });
connect(cmd, &Command::keySequenceChanged, this, [this, i, cmd] {
m_sessionShortcuts[i-1] = cmd->keySequence().toString(QKeySequence::NativeText);
// emit sessionsShortcutsChanged(m_sessionShortcuts);
});
}
}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final
{
static const QPixmap arrowUp = pixmap("expandarrow",Theme::Welcome_ForegroundSecondaryColor);
static const QPixmap arrowDown = QPixmap::fromImage(arrowUp.toImage().mirrored(false, true));
static const QPixmap sessionIcon = pixmap("session", Theme::Welcome_ForegroundSecondaryColor);
const QRect rc = option.rect;
const QString sessionName = idx.data(Qt::DisplayRole).toString();
const QPoint mousePos = option.widget->mapFromGlobal(QCursor::pos());
//const bool hovered = option.state & QStyle::State_MouseOver;
const bool hovered = option.rect.contains(mousePos);
const bool expanded = m_expandedSessions.contains(sessionName);
painter->fillRect(rc, hovered || expanded ? hoverColor : backgroundColor);
const int x = rc.x();
const int x1 = x + 36;
const int y = rc.y();
const int firstBase = y + 18;
painter->drawPixmap(x + 11, y + 5, sessionIcon);
if (hovered || expanded)
painter->drawPixmap(rc.right() - 16, y + 5, expanded ? arrowDown : arrowUp);
if (idx.row() < 9) {
painter->setPen(foregroundColor2);
painter->setFont(sizedFont(10, option.widget));
painter->drawText(x + 3, firstBase, QString::number(idx.row() + 1));
}
const bool isLastSession = idx.data(SessionModel::LastSessionRole).toBool();
const bool isActiveSession = idx.data(SessionModel::ActiveSessionRole).toBool();
const bool isDefaultVirgin = SessionManager::isDefaultVirgin();
QString fullSessionName = sessionName;
if (isLastSession && isDefaultVirgin)
fullSessionName = ProjectWelcomePage::tr("%1 (last session)").arg(fullSessionName);
if (isActiveSession && !isDefaultVirgin)
fullSessionName = ProjectWelcomePage::tr("%1 (current session)").arg(fullSessionName);
const QRect switchRect = QRect(x, y, rc.width() - 20, firstBase + 3 - y);
const bool switchActive = switchRect.contains(mousePos);
painter->setPen(linkColor);
painter->setFont(sizedFont(12, option.widget, switchActive));
painter->drawText(x1, firstBase, fullSessionName);
if (switchActive)
m_activeSwitchToRect = switchRect;
if (expanded) {
painter->setPen(textColor);
painter->setFont(sizedFont(12, option.widget));
const QStringList projects = SessionManager::projectsForSessionName(sessionName);
int yy = firstBase + 25;
QFontMetrics fm(option.widget->font());
for (const QString &project : projects) {
// Project name.
QFileInfo fi(project);
QString completeBase = fi.completeBaseName();
painter->setPen(textColor);
painter->drawText(x1, yy, completeBase);
yy += 18;
// Project path.
QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(project));
painter->setPen(foregroundColor1);
painter->drawText(x1, yy, fm.elidedText(pathWithTilde, Qt::ElideMiddle, rc.width() - 40));
yy += 22;
}
yy += 5;
int xx = x1;
const QStringList actions = {
ProjectWelcomePage::tr("Clone"),
ProjectWelcomePage::tr("Rename"),
ProjectWelcomePage::tr("Delete")
};
for (int i = 0; i < 3; ++i) {
const QString &action = actions.at(i);
const int ww = fm.width(action);
const QRect actionRect(xx, yy - 10, ww, 15);
const bool isActive = actionRect.contains(mousePos);
painter->setPen(linkColor);
painter->setFont(sizedFont(12, option.widget, isActive));
painter->drawText(xx, yy, action);
if (i < 2) {
xx += ww + 14;
int pp = xx - 7;
painter->setPen(textColor);
painter->drawLine(pp, yy - 10, pp, yy);
}
if (isActive)
m_activeActionRects[i] = actionRect;
}
}
}
QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &idx) const final
{
int h = 30;
QString sessionName = idx.data(Qt::DisplayRole).toString();
if (m_expandedSessions.contains(sessionName)) {
QStringList projects = SessionManager::projectsForSessionName(sessionName);
h += projects.size() * 40 + 35;
}
return QSize(380, h);
}
bool helpEvent(QHelpEvent *ev, QAbstractItemView *view,
const QStyleOptionViewItem &option, const QModelIndex &idx) final
{
const int y = ev->pos().y();
if (y > option.rect.bottom() - 20)
return false;
QString sessionShortcut;
if (idx.row() < m_sessionShortcuts.size())
sessionShortcut = m_sessionShortcuts.at(idx.row());
QString sessionName = idx.data(Qt::DisplayRole).toString();
QString tooltipText;
if (sessionShortcut.isEmpty())
tooltipText = ProjectWelcomePage::tr("Opens session \"%1\"").arg(sessionName);
else
tooltipText = ProjectWelcomePage::tr("Opens session \"%1\" (%2)").arg(sessionName).arg(sessionShortcut);
if (tooltipText.isEmpty())
return false;
QToolTip::showText(ev->globalPos(), tooltipText, view);
return true;
}
bool editorEvent(QEvent *ev, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &idx) final
{
if (ev->type() == QEvent::MouseButtonRelease) {
const QPoint pos = static_cast<QMouseEvent *>(ev)->pos();
const QRect rc(option.rect.right() - 20, option.rect.top(), 20, 30);
const QString sessionName = idx.data(Qt::DisplayRole).toString();
if (rc.contains(pos)) {
// The expand/collapse "button".
if (m_expandedSessions.contains(sessionName))
m_expandedSessions.removeOne(sessionName);
else
m_expandedSessions.append(sessionName);
model->layoutChanged({ QPersistentModelIndex(idx) });
return false;
}
// One of the action links?
const auto sessionModel = qobject_cast<SessionModel *>(model);
QTC_ASSERT(sessionModel, return false);
if (m_activeSwitchToRect.contains(pos))
sessionModel->switchToSession(sessionName);
else if (m_activeActionRects[0].contains(pos))
sessionModel->cloneSession(sessionName);
else if (m_activeActionRects[1].contains(pos))
sessionModel->renameSession(sessionName);
else if (m_activeActionRects[2].contains(pos))
sessionModel->deleteSession(sessionName);
return true;
}
if (ev->type() == QEvent::MouseMove) {
model->layoutChanged({ QPersistentModelIndex(idx) }); // Somewhat brutish.
//update(option.rect);
return true;
}
return false;
}
private:
const QColor hoverColor = themeColor(Theme::Welcome_HoverColor);
const QColor textColor = themeColor(Theme::Welcome_TextColor);
const QColor linkColor = themeColor(Theme::Welcome_LinkColor);
const QColor backgroundColor = themeColor(Theme::Welcome_BackgroundColor);
const QColor foregroundColor1 = themeColor(Theme::Welcome_ForegroundPrimaryColor); // light-ish.
const QColor foregroundColor2 = themeColor(Theme::Welcome_ForegroundSecondaryColor); // blacker.
QStringList m_sessionShortcuts;
QStringList m_expandedSessions;
mutable QRect m_activeSwitchToRect;
mutable QRect m_activeActionRects[3];
};
class ProjectDelegate : public QAbstractItemDelegate
{
public:
ProjectDelegate()
{
const int actionsCount = 9;
Context welcomeContext(Core::Constants::C_WELCOME_MODE);
const Id projectBase = "Welcome.OpenRecentProject";
for (int i = 1; i <= actionsCount; ++i) {
auto act = new QAction(tr("Open Recent Project #%1").arg(i), this);
Command *cmd = ActionManager::registerAction(act, projectBase.withSuffix(i), welcomeContext);
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+%1").arg(i)));
m_recentProjectsShortcuts.append(cmd->keySequence().toString(QKeySequence::NativeText));
// connect(act, &QAction::triggered, this, [this, i] { openRecentProjectTriggered(i-1); });
connect(cmd, &Command::keySequenceChanged, this, [this, i, cmd] {
m_recentProjectsShortcuts[i - 1] = cmd->keySequence().toString(QKeySequence::NativeText);
});
}
}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final
{
QRect rc = option.rect;
const bool hovered = option.widget->isActiveWindow() && option.state & QStyle::State_MouseOver;
QColor color = themeColor(hovered ? Theme::Welcome_HoverColor : Theme::Welcome_BackgroundColor);
painter->fillRect(rc, color);
const int x = rc.x();
const int y = rc.y();
const int firstBase = y + 15;
const int secondBase = firstBase + 15;
painter->drawPixmap(x + 11, y + 3, pixmap("project", Theme::Welcome_ForegroundSecondaryColor));
QString projectName = idx.data(Qt::DisplayRole).toString();
QString projectPath = idx.data(Qt::UserRole + 1).toString();
painter->setPen(themeColor(Theme::Welcome_ForegroundSecondaryColor));
painter->setFont(sizedFont(10, option.widget));
if (idx.row() < 9)
painter->drawText(x + 3, firstBase, QString::number(idx.row() + 1));
painter->setPen(themeColor(Theme::Welcome_LinkColor));
painter->setFont(sizedFont(12, option.widget, hovered));
painter->drawText(x + 36, firstBase, projectName);
painter->setPen(themeColor(Theme::Welcome_ForegroundPrimaryColor));
painter->setFont(sizedFont(12, option.widget));
QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(projectPath));
painter->drawText(x + 36, secondBase, pathWithTilde);
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &idx) const final
{
QString projectName = idx.data(Qt::DisplayRole).toString();
QString projectPath = idx.data(Qt::UserRole + 1).toString();
QFontMetrics fm(sizedFont(13, option.widget));
int width = std::max(fm.width(projectName), fm.width(projectPath)) + 36;
return QSize(width, 48);
}
bool editorEvent(QEvent *ev, QAbstractItemModel *,
const QStyleOptionViewItem &, const QModelIndex &idx) final
{
if (ev->type() == QEvent::MouseButtonRelease) {
QString projectFile = idx.data(Qt::UserRole + 1).toString();
ProjectExplorerPlugin::openProjectWelcomePage(projectFile);
return true;
}
return false;
}
QStringList m_recentProjectsShortcuts;
};
class TreeView : public QTreeView
{
public:
TreeView(QWidget *parent)
: QTreeView(parent)
{
header()->hide();
setMouseTracking(true); // To enable hover.
setIndentation(0);
setSelectionMode(QAbstractItemView::NoSelection);
setFrameShape(QFrame::NoFrame);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
setFocusPolicy(Qt::NoFocus);
QPalette pal; // Needed for classic theme (only).
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
viewport()->setPalette(pal);
}
void leaveEvent(QEvent *) final
{
QHoverEvent hev(QEvent::HoverLeave, QPointF(), QPointF());
viewportEvent(&hev); // Seemingly needed to kill the hover paint.
}
};
class SessionsPage : public QWidget
{
public:
SessionsPage(ProjectWelcomePage *projectWelcomePage)
{
// FIXME: Remove once facilitateQml() is gone.
if (!projectWelcomePage->m_sessionModel)
projectWelcomePage->m_sessionModel = new SessionModel(this);
if (!projectWelcomePage->m_projectModel)
projectWelcomePage->m_projectModel = new ProjectModel(this);
auto newButton = new WelcomePageButton(this);
newButton->setText(ProjectWelcomePage::tr("New Project"));
newButton->setIcon(pixmap("new", Theme::Welcome_ForegroundSecondaryColor));
newButton->setOnClicked([] { ProjectExplorerPlugin::openNewProjectDialog(); });
auto openButton = new WelcomePageButton(this);
openButton->setText(ProjectWelcomePage::tr("Open Project"));
openButton->setIcon(pixmap("open", Theme::Welcome_ForegroundSecondaryColor));
openButton->setOnClicked([] { ProjectExplorerPlugin::openOpenProjectDialog(); });
auto sessionsLabel = new QLabel(this);
sessionsLabel->setFont(sizedFont(15, this));
sessionsLabel->setText(ProjectWelcomePage::tr("Sessions"));
auto recentProjectsLabel = new QLabel(this);
recentProjectsLabel->setFont(sizedFont(15, this));
recentProjectsLabel->setText(ProjectWelcomePage::tr("Recent Projects"));
auto sessionsList = new TreeView(this);
sessionsList->setModel(projectWelcomePage->m_sessionModel);
sessionsList->header()->setSectionHidden(1, true); // The "last modified" column.
sessionsList->setItemDelegate(&m_sessionDelegate);
sessionsList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
auto projectsList = new TreeView(this);
projectsList->setUniformRowHeights(true);
projectsList->setModel(projectWelcomePage->m_projectModel);
projectsList->setItemDelegate(&m_projectDelegate);
projectsList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
const int d = IWelcomePage::screenDependHeightDistance();
auto hbox11 = new QHBoxLayout;
hbox11->setContentsMargins(0, 0, 0, 0);
hbox11->addWidget(newButton);
hbox11->addStretch(1);
auto hbox21 = new QHBoxLayout;
hbox21->setContentsMargins(0, 0, 0, 0);
hbox21->addWidget(openButton);
hbox21->addStretch(1);
auto vbox1 = new QVBoxLayout;
vbox1->setContentsMargins(0, 0, 0, 0);
vbox1->addStrut(200);
vbox1->addItem(hbox11);
vbox1->addSpacing(d);
vbox1->addWidget(sessionsLabel);
vbox1->addSpacing(d + 5);
vbox1->addWidget(sessionsList);
auto vbox2 = new QVBoxLayout;
vbox2->setContentsMargins(0, 0, 0, 0);
vbox2->addItem(hbox21);
vbox2->addSpacing(d);
vbox2->addWidget(recentProjectsLabel);
vbox2->addSpacing(d + 5);
vbox2->addWidget(projectsList);
auto hbox = new QHBoxLayout(this);
hbox->setContentsMargins(30, 27, 27, 27);
hbox->addItem(vbox1);
hbox->addSpacing(d);
hbox->addItem(vbox2);
hbox->setStretchFactor(vbox2, 2);
}
SessionDelegate m_sessionDelegate;
ProjectDelegate m_projectDelegate;
};
QWidget *ProjectWelcomePage::createWidget() const
{
return new SessionsPage(const_cast<ProjectWelcomePage *>(this));
}
} // namespace Internal } // namespace Internal
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -25,18 +25,15 @@
#pragma once #pragma once
#include <QAbstractListModel>
#include <coreplugin/iwelcomepage.h> #include <coreplugin/iwelcomepage.h>
QT_BEGIN_NAMESPACE #include <QAbstractListModel>
class QQmlEngine;
QT_END_NAMESPACE
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
class SessionModel; class SessionModel;
class SessionsPage;
class ProjectModel : public QAbstractListModel class ProjectModel : public QAbstractListModel
{ {
@@ -60,14 +57,12 @@ class ProjectWelcomePage : public Core::IWelcomePage
public: public:
ProjectWelcomePage() = default; ProjectWelcomePage() = default;
void facilitateQml(QQmlEngine *engine) override;
QUrl pageLocation() const override;
QWidget *page() { return nullptr; }
QString title() const override { return tr("Projects"); } QString title() const override { return tr("Projects"); }
int priority() const override { return 20; } int priority() const override { return 20; }
Core::Id id() const override; Core::Id id() const override;
QWidget *createWidget() const override;
void reloadWelcomeScreenData(); void reloadWelcomeScreenData() const;
public slots: public slots:
void newProject(); void newProject();
@@ -78,6 +73,7 @@ signals:
void manageSessions(); void manageSessions();
private: private:
friend class SessionsPage;
SessionModel *m_sessionModel = nullptr; SessionModel *m_sessionModel = nullptr;
ProjectModel *m_projectModel = nullptr; ProjectModel *m_projectModel = nullptr;
}; };

View File

@@ -629,10 +629,8 @@ QString prefixForItem(const ExampleItem &item)
QVariant ExamplesListModel::data(const QModelIndex &index, int role) const QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid() || index.row()+1 > m_exampleItems.count()) { if (!index.isValid() || index.row()+1 > m_exampleItems.count())
qDebug() << Q_FUNC_INFO << "invalid index requested";
return QVariant(); return QVariant();
}
ExampleItem item = m_exampleItems.at(index.row()); ExampleItem item = m_exampleItems.at(index.row());
switch (role) switch (role)
@@ -674,7 +672,6 @@ QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
case IsHighlighted: case IsHighlighted:
return item.isHighlighted; return item.isHighlighted;
default: default:
qDebug() << Q_FUNC_INFO << "role type not supported";
return QVariant(); return QVariant();
} }
} }

View File

@@ -39,26 +39,30 @@
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <QMutex> #include <QApplication>
#include <QThread>
#include <QMutexLocker>
#include <QPointer>
#include <QWaitCondition>
#include <QDir>
#include <QBuffer> #include <QBuffer>
#include <QCloseEvent>
#include <QComboBox>
#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QDir>
#include <QGridLayout>
#include <QHeaderView>
#include <QIdentityProxyModel>
#include <QImage> #include <QImage>
#include <QImageReader> #include <QImageReader>
#include <QGridLayout>
#include <QLabel> #include <QLabel>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QMessageBox> #include <QMessageBox>
#include <QApplication> #include <QPainter>
#include <QQuickImageProvider> #include <QPixmapCache>
#include <QQmlEngine> #include <QPointer>
#include <QQmlContext> #include <QPushButton>
#include <QDesktopServices> #include <QStyledItemDelegate>
#include <QTableView>
#include <QTime>
#include <QTimer>
using namespace Core;
using namespace Utils; using namespace Utils;
namespace QtSupport { namespace QtSupport {
@@ -66,223 +70,40 @@ namespace Internal {
const char C_FALLBACK_ROOT[] = "ProjectsFallbackRoot"; const char C_FALLBACK_ROOT[] = "ProjectsFallbackRoot";
QPointer<ExamplesListModel> &examplesModelStatic() const int itemWidth = 240;
const int itemHeight = 240;
const int itemGap = 10;
const int tagsSeparatorY = itemHeight - 60;
ExamplesWelcomePage::ExamplesWelcomePage(bool showExamples)
: m_showExamples(showExamples)
{ {
static QPointer<ExamplesListModel> s_examplesModel;
return s_examplesModel;
}
class Fetcher : public QObject
{
Q_OBJECT
public:
Fetcher() : QObject(), m_shutdown(false)
{
connect(Core::ICore::instance(), &Core::ICore::coreAboutToClose, this, &Fetcher::shutdown);
}
void wait()
{
if (QThread::currentThread() == QApplication::instance()->thread())
return;
if (m_shutdown)
return;
m_waitcondition.wait(&m_mutex, 4000);
}
QByteArray data()
{
QMutexLocker lock(&m_dataMutex);
return m_fetchedData;
}
void clearData()
{
QMutexLocker lock(&m_dataMutex);
m_fetchedData.clear();
}
bool asynchronousFetchData(const QUrl &url)
{
QMutexLocker lock(&m_mutex);
if (!QMetaObject::invokeMethod(this,
"fetchData",
Qt::AutoConnection,
Q_ARG(QUrl, url))) {
return false;
}
wait();
return true;
}
public slots:
void fetchData(const QUrl &url)
{
if (m_shutdown)
return;
QMutexLocker lock(&m_mutex);
if (Core::HelpManager::instance()) {
QMutexLocker dataLock(&m_dataMutex);
m_fetchedData = Core::HelpManager::fileData(url);
}
m_waitcondition.wakeAll();
}
private:
void shutdown()
{
m_shutdown = true;
}
public:
QByteArray m_fetchedData;
QWaitCondition m_waitcondition;
QMutex m_mutex; //This mutex synchronises the wait() and wakeAll() on the wait condition.
//We have to ensure that wakeAll() is called always after wait().
QMutex m_dataMutex; //This mutex synchronises the access of m_fectedData.
//If the wait condition timeouts we otherwise get a race condition.
bool m_shutdown;
};
class HelpImageProvider : public QQuickImageProvider
{
public:
HelpImageProvider()
: QQuickImageProvider(QQuickImageProvider::Image)
{
}
// gets called by declarative in separate thread
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
QMutexLocker lock(&m_mutex);
QUrl url = QUrl::fromEncoded(id.toLatin1());
if (!m_fetcher.asynchronousFetchData(url) || m_fetcher.data().isEmpty()) {
if (size) {
size->setWidth(0);
size->setHeight(0);
}
return QImage();
}
QByteArray data = m_fetcher.data();
QBuffer imgBuffer(&data);
imgBuffer.open(QIODevice::ReadOnly);
QImageReader reader(&imgBuffer);
QImage img = reader.read();
m_fetcher.clearData();
img = ScreenshotCropper::croppedImage(img, id, requestedSize);
if (size)
*size = img.size();
return img;
}
private:
Fetcher m_fetcher;
QMutex m_mutex;
};
ExamplesWelcomePage::ExamplesWelcomePage()
: m_engine(0), m_showExamples(false)
{
}
void ExamplesWelcomePage::setShowExamples(bool showExamples)
{
m_showExamples = showExamples;
} }
QString ExamplesWelcomePage::title() const QString ExamplesWelcomePage::title() const
{ {
if (m_showExamples) return m_showExamples ? tr("Examples") : tr("Tutorials");
return tr("Examples");
else
return tr("Tutorials");
} }
int ExamplesWelcomePage::priority() const int ExamplesWelcomePage::priority() const
{
if (m_showExamples)
return 30;
else
return 40;
}
bool ExamplesWelcomePage::hasSearchBar() const
{
if (m_showExamples)
return true;
else
return false;
}
QUrl ExamplesWelcomePage::pageLocation() const
{ {
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows return m_showExamples ? 30 : 40;
const QString resourcePath = Utils::FileUtils::normalizePathName(Core::ICore::resourcePath());
if (m_showExamples)
return QUrl::fromLocalFile(resourcePath + QLatin1String("/welcomescreen/examples.qml"));
else
return QUrl::fromLocalFile(resourcePath + QLatin1String("/welcomescreen/tutorials.qml"));
} }
void ExamplesWelcomePage::facilitateQml(QQmlEngine *engine) Id ExamplesWelcomePage::id() const
{
m_engine = engine;
m_engine->addImageProvider(QLatin1String("helpimage"), new HelpImageProvider);
ExamplesListModelFilter *proxy = new ExamplesListModelFilter(examplesModel(), this);
proxy->setDynamicSortFilter(true);
proxy->sort(0);
proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
QQmlContext *rootContenxt = m_engine->rootContext();
if (m_showExamples) {
proxy->setShowTutorialsOnly(false);
rootContenxt->setContextProperty(QLatin1String("examplesModel"), proxy);
rootContenxt->setContextProperty(QLatin1String("exampleSetModel"), proxy->exampleSetModel());
} else {
rootContenxt->setContextProperty(QLatin1String("tutorialsModel"), proxy);
}
rootContenxt->setContextProperty(QLatin1String("gettingStarted"), this);
}
Core::Id ExamplesWelcomePage::id() const
{ {
return m_showExamples ? "Examples" : "Tutorials"; return m_showExamples ? "Examples" : "Tutorials";
} }
void ExamplesWelcomePage::openHelpInExtraWindow(const QUrl &help) void ExamplesWelcomePage::openHelpInExtraWindow(const QUrl &help)
{ {
Core::HelpManager::handleHelpRequest(help, Core::HelpManager::ExternalHelpAlways); HelpManager::handleHelpRequest(help, HelpManager::ExternalHelpAlways);
}
void ExamplesWelcomePage::openHelp(const QUrl &help)
{
Core::HelpManager::handleHelpRequest(help, Core::HelpManager::HelpModeAlways);
}
void ExamplesWelcomePage::openUrl(const QUrl &url)
{
QDesktopServices::openUrl(url);
} }
QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen, const QStringList& dependencies) QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen, const QStringList& dependencies)
{ {
const QString projectDir = proFileInfo.canonicalPath(); const QString projectDir = proFileInfo.canonicalPath();
QDialog d(Core::ICore::mainWindow()); QDialog d(ICore::mainWindow());
QGridLayout *lay = new QGridLayout(&d); QGridLayout *lay = new QGridLayout(&d);
QLabel *descrLbl = new QLabel; QLabel *descrLbl = new QLabel;
d.setWindowTitle(tr("Copy Project to writable Location?")); d.setWindowTitle(tr("Copy Project to writable Location?"));
@@ -305,9 +126,9 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
txt->setBuddy(chooser); txt->setBuddy(chooser);
chooser->setExpectedKind(PathChooser::ExistingDirectory); chooser->setExpectedKind(PathChooser::ExistingDirectory);
chooser->setHistoryCompleter(QLatin1String("Qt.WritableExamplesDir.History")); chooser->setHistoryCompleter(QLatin1String("Qt.WritableExamplesDir.History"));
QSettings *settings = Core::ICore::settings(); QSettings *settings = ICore::settings();
chooser->setPath(settings->value(QString::fromLatin1(C_FALLBACK_ROOT), chooser->setPath(settings->value(QString::fromLatin1(C_FALLBACK_ROOT),
Core::DocumentManager::projectsDirectory()).toString()); DocumentManager::projectsDirectory()).toString());
lay->addWidget(txt, 1, 0); lay->addWidget(txt, 1, 0);
lay->addWidget(chooser, 1, 1); lay->addWidget(chooser, 1, 1);
enum { Copy = QDialog::Accepted + 1, Keep = QDialog::Accepted + 2 }; enum { Copy = QDialog::Accepted + 1, Keep = QDialog::Accepted + 2 };
@@ -327,7 +148,7 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
QDir toDirWithExamplesDir(destBaseDir); QDir toDirWithExamplesDir(destBaseDir);
if (toDirWithExamplesDir.cd(exampleDirName)) { if (toDirWithExamplesDir.cd(exampleDirName)) {
toDirWithExamplesDir.cdUp(); // step out, just to not be in the way toDirWithExamplesDir.cdUp(); // step out, just to not be in the way
QMessageBox::warning(Core::ICore::mainWindow(), tr("Cannot Use Location"), QMessageBox::warning(ICore::mainWindow(), tr("Cannot Use Location"),
tr("The specified location already exists. " tr("The specified location already exists. "
"Please specify a valid location."), "Please specify a valid location."),
QMessageBox::Ok, QMessageBox::NoButton); QMessageBox::Ok, QMessageBox::NoButton);
@@ -347,7 +168,7 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
targetFile.appendPath(QDir(dependency).dirName()); targetFile.appendPath(QDir(dependency).dirName());
if (!FileUtils::copyRecursively(FileName::fromString(dependency), targetFile, if (!FileUtils::copyRecursively(FileName::fromString(dependency), targetFile,
&error)) { &error)) {
QMessageBox::warning(Core::ICore::mainWindow(), tr("Cannot Copy Project"), error); QMessageBox::warning(ICore::mainWindow(), tr("Cannot Copy Project"), error);
// do not fail, just warn; // do not fail, just warn;
} }
} }
@@ -355,7 +176,7 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
return targetDir + QLatin1Char('/') + proFileInfo.fileName(); return targetDir + QLatin1Char('/') + proFileInfo.fileName();
} else { } else {
QMessageBox::warning(Core::ICore::mainWindow(), tr("Cannot Copy Project"), error); QMessageBox::warning(ICore::mainWindow(), tr("Cannot Copy Project"), error);
} }
} }
@@ -363,7 +184,6 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
if (code == Keep) if (code == Keep)
return proFileInfo.absoluteFilePath(); return proFileInfo.absoluteFilePath();
return QString(); return QString();
} }
void ExamplesWelcomePage::openProject(const QString &projectFile, void ExamplesWelcomePage::openProject(const QString &projectFile,
@@ -402,23 +222,485 @@ void ExamplesWelcomePage::openProject(const QString &projectFile,
ProjectExplorer::ProjectExplorerPlugin::OpenProjectResult result = ProjectExplorer::ProjectExplorerPlugin::OpenProjectResult result =
ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFile); ProjectExplorer::ProjectExplorerPlugin::instance()->openProject(proFile);
if (result) { if (result) {
Core::ICore::openFiles(filesToOpen); ICore::openFiles(filesToOpen);
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); ModeManager::activateMode(Core::Constants::MODE_EDIT);
if (help.isValid()) if (help.isValid())
openHelpInExtraWindow(help.toString()); openHelpInExtraWindow(help.toString());
Core::ModeManager::activateMode(ProjectExplorer::Constants::MODE_SESSION); ModeManager::activateMode(ProjectExplorer::Constants::MODE_SESSION);
} else { } else {
ProjectExplorer::ProjectExplorerPlugin::showOpenProjectError(result); ProjectExplorer::ProjectExplorerPlugin::showOpenProjectError(result);
} }
} }
ExamplesListModel *ExamplesWelcomePage::examplesModel() const //////////////////////////////
{
if (examplesModelStatic())
return examplesModelStatic().data();
examplesModelStatic() = new ExamplesListModel(const_cast<ExamplesWelcomePage*>(this)); static QColor themeColor(Theme::Color role)
return examplesModelStatic().data(); {
return Utils::creatorTheme()->color(role);
}
static QFont sizedFont(int size, const QWidget *widget, bool underline = false)
{
QFont f = widget->font();
f.setPixelSize(size);
f.setUnderline(underline);
return f;
}
static QString resourcePath()
{
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows
return FileUtils::normalizePathName(ICore::resourcePath());
}
class SearchBox : public QFrame
{
public:
SearchBox(const QString &placeHolderText, QWidget *parent)
: QFrame(parent)
{
setFrameShape(QFrame::Box);
setFrameShadow(QFrame::Plain);
QPalette pal;
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
m_lineEdit = new QLineEdit;
m_lineEdit->setPlaceholderText(placeHolderText);
m_lineEdit->setFrame(false);
m_lineEdit->setFont(sizedFont(14, this));
m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
m_lineEdit->setPalette(pal);
auto box = new QHBoxLayout(this);
box->setContentsMargins(15, 3, 15, 3);
box->addWidget(m_lineEdit);
}
QLineEdit *m_lineEdit;
};
class GridView : public QTableView
{
public:
GridView(QWidget *parent)
: QTableView(parent)
{
horizontalHeader()->hide();
horizontalHeader()->setDefaultSectionSize(itemWidth);
verticalHeader()->hide();
verticalHeader()->setDefaultSectionSize(itemHeight);
setMouseTracking(true); // To enable hover.
setSelectionMode(QAbstractItemView::NoSelection);
setFrameShape(QFrame::NoFrame);
setGridStyle(Qt::NoPen);
QPalette pal;
pal.setColor(QPalette::Base, themeColor(Theme::Welcome_BackgroundColor));
setPalette(pal); // Makes a difference on Mac.
}
void leaveEvent(QEvent *) final
{
QHoverEvent hev(QEvent::HoverLeave, QPointF(), QPointF());
viewportEvent(&hev); // Seemingly needed to kill the hover paint.
}
};
class GridProxyModel : public QIdentityProxyModel
{
public:
GridProxyModel()
{}
void setColumnCount(int columnCount)
{
if (columnCount == m_columnCount)
return;
QTC_ASSERT(columnCount >= 1, columnCount = 1);
m_columnCount = columnCount;
layoutChanged();
}
int rowCount(const QModelIndex &parent) const final
{
if (parent.isValid())
return 0;
int rows = sourceModel()->rowCount(QModelIndex());
return (rows + m_columnCount - 1) / m_columnCount;
}
int columnCount(const QModelIndex &parent) const final
{
if (parent.isValid())
return 0;
return m_columnCount;
}
QModelIndex index(int row, int column, const QModelIndex &) const final
{
return createIndex(row, column, nullptr);
}
QModelIndex parent(const QModelIndex &) const final
{
return QModelIndex();
}
QModelIndex mapToSource(const QModelIndex &proxyIndex) const final
{
if (!proxyIndex.isValid())
return QModelIndex();
int sourceRow = proxyIndex.row() * m_columnCount + proxyIndex.column();
return sourceModel()->index(sourceRow, 0);
}
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const final
{
if (!sourceIndex.isValid())
return QModelIndex();
QTC_CHECK(sourceIndex.column() == 0);
int proxyRow = sourceIndex.row() / m_columnCount;
int proxyColumn = sourceIndex.row() % m_columnCount;
return index(proxyRow, proxyColumn, QModelIndex());
}
private:
int m_columnCount = 1;
};
class ExampleDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const final
{
const QRect rc = option.rect;
const QString name = index.data(Name).toString();
// Quick hack for empty items in the last row.
if (name.isEmpty())
return;
const int d = 10;
const int x = rc.x() + d;
const int y = rc.y() + d;
const int w = rc.width() - 2 * d - itemGap;
const int h = rc.height() - 2 * d;
const bool hovered = option.state & QStyle::State_MouseOver;
const int tagsBase = tagsSeparatorY + 10;
const int shiftY = tagsSeparatorY - 20;
const int nameY = tagsSeparatorY - 20;
const QRect textRect = QRect(x, y + nameY, w, h);
QTextOption wrapped;
wrapped.setWrapMode(QTextOption::WordWrap);
int offset = 0;
if (hovered) {
if (index != m_previousIndex) {
m_previousIndex = index;
m_startTime.start();
m_currentArea = rc;
m_currentWidget = qobject_cast<QAbstractItemView *>(
const_cast<QWidget *>(option.widget));
}
offset = m_startTime.elapsed() * itemHeight / 200; // Duration 200 ms.
if (offset < shiftY)
QTimer::singleShot(5, this, &ExampleDelegate::goon);
else if (offset > shiftY)
offset = shiftY;
} else {
m_previousIndex = QModelIndex();
}
const QFontMetrics fm(option.widget->font());
const QRect shiftedTextRect = textRect.adjusted(0, -offset, 0, -offset);
// The pixmap.
if (offset == 0) {
const QString imageUrl = index.data(ImageUrl).toString();
const bool isVideo = index.data(IsVideo).toBool();
const QSize requestSize(188, 145);
QPixmap pm;
if (QPixmap *foundPixmap = m_pixmapCache.find(imageUrl)) {
pm = *foundPixmap;
} else {
pm.load(imageUrl);
if (pm.isNull())
pm.load(resourcePath() + "/welcomescreen/widgets/" + imageUrl);
if (pm.isNull()) {
// FIXME: Make async
QByteArray fetchedData = HelpManager::fileData(imageUrl);
QBuffer imgBuffer(&fetchedData);
imgBuffer.open(QIODevice::ReadOnly);
QImageReader reader(&imgBuffer);
QImage img = reader.read();
img = ScreenshotCropper::croppedImage(img, imageUrl, requestSize);
pm = QPixmap::fromImage(img);
}
m_pixmapCache.insert(imageUrl, pm);
}
QRect inner(x + 11, y - offset, requestSize.width(), requestSize.height());
QRect pixmapRect = inner;
if (!pm.isNull()) {
painter->setPen(foregroundColor2);
if (isVideo)
pixmapRect = inner.adjusted(6, 10, -6, -25);
QPoint pixmapPos = pixmapRect.center();
pixmapPos.rx() -= pm.width() / 2;
pixmapPos.ry() -= pm.height() / 2;
painter->drawPixmap(pixmapPos, pm);
if (isVideo) {
painter->setFont(sizedFont(13, option.widget));
QRect lenRect(x, y + 120, w, 20);
QString videoLen = index.data(VideoLength).toString();
lenRect = fm.boundingRect(lenRect, Qt::AlignHCenter, videoLen);
painter->drawText(lenRect.adjusted(0, 0, 5, 0), videoLen);
}
} else {
// The description text as fallback.
QRect descRect = pixmapRect.adjusted(6, 10, -6, -10);
QString desc = index.data(Description).toString();
painter->setPen(foregroundColor2);
painter->setFont(sizedFont(11, option.widget));
painter->drawText(descRect, desc, wrapped);
}
painter->setPen(foregroundColor1);
painter->drawRect(pixmapRect.adjusted(-1, -1, -1, -1));
}
// The title of the example.
painter->setPen(foregroundColor1);
painter->setFont(sizedFont(13, option.widget));
QRectF nameRect;
if (offset) {
nameRect = painter->boundingRect(shiftedTextRect, name, wrapped);
painter->drawText(nameRect, name, wrapped);
} else {
nameRect = QRect(x, y + nameY, x + w, y + nameY + 20);
QString elidedName = fm.elidedText(name, Qt::ElideRight, w - 20);
painter->drawText(nameRect, elidedName);
}
// The separator line below the example title.
if (offset) {
int ll = nameRect.bottom() + 5;
painter->setPen(lightColor);
painter->drawLine(x, ll, x + w, ll);
}
// The description text.
if (offset) {
int dd = nameRect.height() + 10;
QRect descRect = shiftedTextRect.adjusted(0, dd, 0, dd);
QString desc = index.data(Description).toString();
painter->setPen(foregroundColor2);
painter->setFont(sizedFont(11, option.widget));
painter->drawText(descRect, desc, wrapped);
}
// Separator line between text and 'Tags:' section
painter->setPen(lightColor);
painter->drawLine(x, y + tagsSeparatorY, x + w, y + tagsSeparatorY);
// The 'Tags:' section
const int tagsHeight = h - tagsBase;
const QFont tagsFont = sizedFont(10, option.widget);
const QFontMetrics tagsFontMetrics(tagsFont);
QRect tagsLabelRect = QRect(x, y + tagsBase, 30, tagsHeight - 2);
painter->setPen(foregroundColor2);
painter->setFont(tagsFont);
painter->drawText(tagsLabelRect, ExamplesWelcomePage::tr("Tags:"));
painter->setPen(themeColor(Theme::Welcome_LinkColor));
const QStringList tags = index.data(Tags).toStringList();
m_currentTagRects.clear();
int xx = 0;
int yy = y + tagsBase;
for (const QString tag : tags) {
const int ww = tagsFontMetrics.width(tag) + 5;
if (xx + ww > w - 30) {
yy += 15;
xx = 0;
}
const QRect tagRect(xx + x + 30, yy, ww, 15);
painter->drawText(tagRect, tag);
m_currentTagRects.append({ tag, tagRect });
xx += ww;
}
// Box it when hovered.
if (hovered) {
painter->setPen(lightColor);
painter->drawRect(rc.adjusted(0, 0, -1, -1));
}
}
void goon()
{
if (m_currentWidget)
m_currentWidget->viewport()->update(m_currentArea);
}
bool editorEvent(QEvent *ev, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &idx) final
{
if (ev->type() == QEvent::MouseButtonRelease) {
auto mev = static_cast<QMouseEvent *>(ev);
if (idx.isValid()) {
const QPoint pos = mev->pos();
if (pos.y() > option.rect.y() + tagsSeparatorY) {
//const QStringList tags = idx.data(Tags).toStringList();
for (auto it : m_currentTagRects) {
if (it.second.contains(pos))
emit tagClicked(it.first);
}
} else {
if (idx.data(IsVideo).toBool())
QDesktopServices::openUrl(idx.data(VideoUrl).toUrl());
else if (idx.data(HasSourceCode).toBool())
ExamplesWelcomePage::openProject(idx.data(ProjectPath).toString(),
idx.data(FilesToOpen).toStringList(),
idx.data(MainFile).toString(),
idx.data(DocUrl).toUrl(),
idx.data(Dependencies).toStringList(),
idx.data(Platforms).toStringList());
else
ExamplesWelcomePage::openHelpInExtraWindow(idx.data(DocUrl).toUrl());
}
}
}
return QAbstractItemDelegate::editorEvent(ev, model, option, idx);
}
signals:
void tagClicked(const QString &tag);
private:
const QColor lightColor = QColor(221, 220, 220); // color: "#dddcdc"
const QColor backgroundColor = themeColor(Theme::Welcome_BackgroundColor);
const QColor foregroundColor1 = themeColor(Theme::Welcome_ForegroundPrimaryColor); // light-ish.
const QColor foregroundColor2 = themeColor(Theme::Welcome_ForegroundSecondaryColor); // blacker.
mutable QPersistentModelIndex m_previousIndex;
mutable QTime m_startTime;
mutable QRect m_currentArea;
mutable QPointer<QAbstractItemView> m_currentWidget;
mutable QVector<QPair<QString, QRect>> m_currentTagRects;
mutable QPixmapCache m_pixmapCache;
};
class ExamplesPageWidget : public QWidget
{
public:
ExamplesPageWidget(bool isExamples)
: m_isExamples(isExamples)
{
static ExamplesListModel *s_examplesModel = new ExamplesListModel(this);
m_examplesModel = s_examplesModel;
m_filteredModel = new ExamplesListModelFilter(m_examplesModel, this);
m_filteredModel->setDynamicSortFilter(true);
m_filteredModel->sort(0);
m_filteredModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
auto vbox = new QVBoxLayout(this);
vbox->setContentsMargins(30, 27, 20, 20);
if (m_isExamples) {
m_filteredModel->setShowTutorialsOnly(false);
m_qtVersionSelector = new QComboBox(this);
m_qtVersionSelector->setMinimumWidth(itemWidth);
m_qtVersionSelector->setMaximumWidth(itemWidth);
m_searchBox = new SearchBox(tr("Search in Examples..."), this);
auto hbox = new QHBoxLayout;
hbox->setSpacing(17);
hbox->addWidget(m_qtVersionSelector);
hbox->addWidget(m_searchBox);
vbox->addItem(hbox);
connect(m_qtVersionSelector, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
this, &ExamplesPageWidget::updateComboBox);
} else {
m_filteredModel->setShowTutorialsOnly(true);
m_searchBox = new SearchBox(tr("Search in Tutorials..."), this);
vbox->addWidget(m_searchBox);
}
m_gridModel.setSourceModel(m_filteredModel);
m_gridView = new GridView(this);
m_gridView->setModel(&m_gridModel);
m_gridView->setItemDelegate(&m_exampleDelegate);
vbox->addWidget(m_gridView);
connect(&m_exampleDelegate, &ExampleDelegate::tagClicked,
this, &ExamplesPageWidget::onTagClicked);
connect(m_filteredModel, &ExamplesListModelFilter::filterTagsChanged,
this, &ExamplesPageWidget::updateStuff);
connect(m_filteredModel, &ExamplesListModelFilter::searchStringChanged,
this, &ExamplesPageWidget::updateStuff);
connect(m_filteredModel, &ExamplesListModelFilter::exampleSetIndexChanged,
this, &ExamplesPageWidget::updateStuff);
connect(m_searchBox->m_lineEdit, &QLineEdit::textChanged,
m_filteredModel, &ExamplesListModelFilter::setSearchString);
}
int bestColumnCount() const
{
return qMax(1, (width() - 30) / (itemWidth + itemGap));
}
void resizeEvent(QResizeEvent *ev) final
{
QWidget::resizeEvent(ev);
m_gridModel.setColumnCount(bestColumnCount());
}
void onTagClicked(const QString &tag)
{
QString text = m_searchBox->m_lineEdit->text();
m_searchBox->m_lineEdit->setText(text + QString("tag:\"%1\" ").arg(tag));
}
void updateStuff()
{
if (m_isExamples) {
QTC_ASSERT(m_examplesModel, return);
const QList<BaseQtVersion *> qtVersions = m_examplesModel->qtVersions();
const QList<ExamplesListModel::ExtraExampleSet> extraExampleSets = m_examplesModel->extraExampleSets();
QStringList list;
for (BaseQtVersion *qtVersion : qtVersions)
list.append(qtVersion->displayName());
m_qtVersionSelector->clear();
m_qtVersionSelector->addItems(list);
}
}
void updateComboBox(int index)
{
QTC_ASSERT(m_isExamples, return);
QTC_ASSERT(m_examplesModel, return);
m_examplesModel->selectExampleSet(index);
}
const bool m_isExamples;
ExampleDelegate m_exampleDelegate;
QPointer<ExamplesListModel> m_examplesModel;
ExamplesListModelFilter *m_filteredModel;
SearchBox *m_searchBox;
QComboBox *m_qtVersionSelector = nullptr;
GridView *m_gridView;
GridProxyModel m_gridModel;
};
QWidget *ExamplesWelcomePage::createWidget() const
{
return new ExamplesPageWidget(m_showExamples);
} }
} // namespace Internal } // namespace Internal

View File

@@ -30,7 +30,6 @@
#include <QStringList> #include <QStringList>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QQmlEngine;
class QFileInfo; class QFileInfo;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -44,29 +43,21 @@ class ExamplesWelcomePage : public Core::IWelcomePage
Q_OBJECT Q_OBJECT
public: public:
ExamplesWelcomePage(); explicit ExamplesWelcomePage(bool showExamples);
void setShowExamples(bool showExamples); QString title() const final;
QUrl pageLocation() const; int priority() const final;
QString title() const; Core::Id id() const final;
int priority() const; QWidget *createWidget() const final;
bool hasSearchBar() const;
void facilitateQml(QQmlEngine *);
Core::Id id() const;
Q_INVOKABLE void openUrl(const QUrl &url);
public slots: static void openHelpInExtraWindow(const QUrl &help);
void openHelpInExtraWindow(const QUrl &help); static void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen,
void openHelp(const QUrl &help); const QString &mainFile, const QUrl &help,
void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen, const QStringList &dependencies, const QStringList &platforms);
const QString &mainFile, const QUrl& help, const QStringList &dependencies,
const QStringList &platforms);
private: private:
ExamplesListModel *examplesModel() const; static QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen, const QStringList &dependencies);
QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen, const QStringList &dependencies); const bool m_showExamples;
QQmlEngine *m_engine;
bool m_showExamples;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -76,13 +76,8 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes
addAutoReleasedObject(new CodeGenSettingsPage); addAutoReleasedObject(new CodeGenSettingsPage);
addAutoReleasedObject(new QtOptionsPage); addAutoReleasedObject(new QtOptionsPage);
ExamplesWelcomePage *welcomePage; addAutoReleasedObject(new ExamplesWelcomePage(true)); // Examples
welcomePage = new ExamplesWelcomePage; addAutoReleasedObject(new ExamplesWelcomePage(false)); // Tutorials
addAutoReleasedObject(welcomePage);
welcomePage->setShowExamples(true);
welcomePage = new ExamplesWelcomePage;
addAutoReleasedObject(welcomePage);
ProjectExplorer::KitManager::registerKitInformation(new QtKitInformation); ProjectExplorer::KitManager::registerKitInformation(new QtKitInformation);

View File

@@ -13,7 +13,7 @@
\"Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.\" \"Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.\"
], ],
\"Category\" : \"Qt Creator\", \"Category\" : \"Qt Creator\",
\"Description\" : \"Default Welcome Screen Plugin.\", \"Description\" : \"Secondary Welcome Screen Plugin.\",
\"Url\" : \"http://www.qt.io\", \"Url\" : \"http://www.qt.io\",
$$dependencyList $$dependencyList
} }

View File

@@ -1,15 +1,8 @@
QT += quick quickwidgets
QML_IMPORT_PATH=../../../share/qtcreator/welcomescreen
include(../../qtcreatorplugin.pri) include(../../qtcreatorplugin.pri)
HEADERS += welcomeplugin.h
SOURCES += welcomeplugin.cpp SOURCES += welcomeplugin.cpp
DEFINES += WELCOME_LIBRARY DEFINES += WELCOME_LIBRARY
RESOURCES += \ RESOURCES += welcome.qrc
welcome.qrc

View File

@@ -3,14 +3,13 @@ import qbs 1.0
QtcPlugin { QtcPlugin {
name: "Welcome" name: "Welcome"
Depends { name: "Qt"; submodules: ["widgets", "network", "quick", "quickwidgets"] } Depends { name: "Qt"; submodules: ["widgets", "network" ] }
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "Core" } Depends { name: "Core" }
files: [ files: [
"welcomeplugin.cpp", "welcome2plugin.cpp",
"welcomeplugin.h", "welcome2plugin.h",
"welcome.qrc",
] ]
} }

View File

@@ -4,3 +4,4 @@ QTC_LIB_DEPENDS += \
utils utils
QTC_PLUGIN_DEPENDS += \ QTC_PLUGIN_DEPENDS += \
coreplugin coreplugin

View File

@@ -23,13 +23,11 @@
** **
****************************************************************************/ ****************************************************************************/
#include "welcomeplugin.h" #include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/imode.h> #include <coreplugin/imode.h>
@@ -43,278 +41,318 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/styledbar.h> #include <utils/styledbar.h>
#include <utils/treemodel.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <QVBoxLayout> #include <QDesktopServices>
#include <QMessageBox> #include <QHeaderView>
#include <QLabel>
#include <QDir> #include <QMouseEvent>
#include <QQmlPropertyMap> #include <QPainter>
#include <QQuickImageProvider> #include <QStackedWidget>
#include <QTimer> #include <QTimer>
#include <QVBoxLayout>
#include <QtQuickWidgets/QQuickWidget>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
enum { debug = 0 };
using namespace Core; using namespace Core;
using namespace ExtensionSystem; using namespace ExtensionSystem;
using namespace Utils; using namespace Utils;
static const char currentPageSettingsKeyC[] = "WelcomeTab";
namespace Welcome { namespace Welcome {
namespace Internal { namespace Internal {
static QString applicationDirPath() class SideBar;
const int lrPadding = 34;
const char currentPageSettingsKeyC[] = "Welcome2Tab";
static QColor themeColor(Theme::Color role)
{ {
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows return Utils::creatorTheme()->color(role);
return FileUtils::normalizePathName(QCoreApplication::applicationDirPath());
} }
static QString resourcePath() static QFont sizedFont(int size, const QWidget *widget, bool underline = false)
{ {
// normalize paths so QML doesn't freak out if it's wrongly capitalized on Windows QFont f = widget->font();
return FileUtils::normalizePathName(ICore::resourcePath()); f.setPixelSize(size);
f.setUnderline(underline);
return f;
} }
class WelcomeImageIconProvider : public QQuickImageProvider static QPalette lightText()
{ {
public: QPalette pal;
WelcomeImageIconProvider() pal.setColor(QPalette::Foreground, themeColor(Theme::Welcome_ForegroundPrimaryColor));
: QQuickImageProvider(Pixmap) pal.setColor(QPalette::WindowText, themeColor(Theme::Welcome_ForegroundPrimaryColor));
{ return pal;
} }
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override
{
Q_UNUSED(requestedSize)
QString maskFile;
Theme::Color themeColor = Theme::Welcome_ForegroundPrimaryColor;
const QStringList elements = id.split(QLatin1Char('/'));
if (!elements.empty())
maskFile = elements.first();
if (elements.count() >= 2) {
const static QMetaObject &m = Theme::staticMetaObject;
const static QMetaEnum e = m.enumerator(m.indexOfEnumerator("Color"));
bool success = false;
int value = e.keyToValue(elements.at(1).toLatin1(), &success);
if (success)
themeColor = Theme::Color(value);
}
const QString fileName = QString::fromLatin1(":/welcome/images/%1.png").arg(maskFile);
const Icon icon({{fileName, themeColor}}, Icon::Tint);
const QPixmap result = icon.pixmap();
if (size)
*size = result.size();
return result;
}
};
class WelcomeMode : public IMode class WelcomeMode : public IMode
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int activePlugin READ activePlugin WRITE setActivePlugin NOTIFY activePluginChanged)
Q_PROPERTY(QStringList recentProjectsShortcuts READ recentProjectsShortcuts NOTIFY recentProjectsShortcutsChanged)
Q_PROPERTY(QStringList sessionsShortcuts READ sessionsShortcuts NOTIFY sessionsShortcutsChanged)
public: public:
WelcomeMode(); WelcomeMode();
~WelcomeMode(); ~WelcomeMode();
void activated();
void initPlugins(); void initPlugins();
int activePlugin() const { return m_activePlugin; }
QStringList recentProjectsShortcuts() const { return m_recentProjectsShortcuts; }
QStringList sessionsShortcuts() const { return m_sessionsShortcuts; }
Q_INVOKABLE bool openDroppedFiles(const QList<QUrl> &urls); Q_INVOKABLE bool openDroppedFiles(const QList<QUrl> &urls);
public slots:
void setActivePlugin(int pos)
{
if (m_activePlugin != pos) {
m_activePlugin = pos;
emit activePluginChanged(pos);
}
}
signals:
void activePluginChanged(int pos);
void openSessionTriggered(int index);
void openRecentProjectTriggered(int index);
void recentProjectsShortcutsChanged(QStringList recentProjectsShortcuts);
void sessionsShortcutsChanged(QStringList sessionsShortcuts);
private: private:
void welcomePluginAdded(QObject*); void addPage(IWelcomePage *page);
void sceneGraphError(QQuickWindow::SceneGraphError, const QString &message);
void facilitateQml(QQmlEngine *engine);
void addPages(QQmlEngine *engine, const QList<IWelcomePage *> &pages);
void addKeyboardShortcuts();
QWidget *m_modeWidget; QWidget *m_modeWidget;
QQuickWidget *m_welcomePage; QStackedWidget *m_pageStack;
QMap<Id, IWelcomePage *> m_idPageMap; SideBar *m_sideBar;
QList<IWelcomePage *> m_pluginList; QList<IWelcomePage *> m_pluginList;
int m_activePlugin; QList<WelcomePageButton *> m_pageButtons;
QStringList m_recentProjectsShortcuts; Id m_activePage;
QStringList m_sessionsShortcuts; };
class WelcomePlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Welcome.json")
public:
WelcomePlugin() {}
bool initialize(const QStringList &, QString *) final
{
m_welcomeMode = new WelcomeMode;
addAutoReleasedObject(m_welcomeMode);
return true;
}
void extensionsInitialized() final
{
m_welcomeMode->initPlugins();
ModeManager::activateMode(m_welcomeMode->id());
}
WelcomeMode *m_welcomeMode = nullptr;
};
class IconAndLink : public QWidget
{
public:
IconAndLink(const QString &iconSource,
const QString &title,
const QString &openUrl,
QWidget *parent)
: QWidget(parent), m_iconSource(iconSource), m_title(title), m_openUrl(openUrl)
{
setAutoFillBackground(true);
const QString fileName = QString(":/welcome/images/%1.png").arg(iconSource);
const Icon icon({{ fileName, Theme::Welcome_ForegroundPrimaryColor }}, Icon::Tint);
m_icon = new QLabel;
m_icon->setPixmap(icon.pixmap());
m_label = new QLabel(title);
m_label->setFont(sizedFont(11, m_label, false));
auto layout = new QHBoxLayout;
layout->setContentsMargins(lrPadding, 0, lrPadding, 0);
layout->addWidget(m_icon);
layout->addSpacing(2);
layout->addWidget(m_label);
layout->addStretch(1);
setLayout(layout);
}
void enterEvent(QEvent *) override
{
QPalette pal;
pal.setColor(QPalette::Background, themeColor(Theme::Welcome_HoverColor));
setPalette(pal);
m_label->setFont(sizedFont(11, m_label, true));
update();
}
void leaveEvent(QEvent *) override
{
QPalette pal;
pal.setColor(QPalette::Background, themeColor(Theme::Welcome_BackgroundColor));
setPalette(pal);
m_label->setFont(sizedFont(11, m_label, false));
update();
}
void mousePressEvent(QMouseEvent *) override
{
QDesktopServices::openUrl(m_openUrl);
}
QString m_iconSource;
QString m_title;
QString m_openUrl;
QLabel *m_icon;
QLabel *m_label;
};
class SideBar : public QWidget
{
Q_OBJECT
public:
SideBar(QWidget *parent)
: QWidget(parent)
{
setAutoFillBackground(true);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setPalette(themeColor(Theme::Welcome_BackgroundColor));
auto vbox = new QVBoxLayout(this);
vbox->setSpacing(0);
vbox->setContentsMargins(0, 27, 0, 0);
int sd = IWelcomePage::screenDependHeightDistance();
{
auto l = m_pluginButtons = new QVBoxLayout;
l->setContentsMargins(lrPadding, 0, lrPadding, 0);
l->setSpacing(sd + 3);
vbox->addItem(l);
vbox->addSpacing(62);
}
{
auto l = new QVBoxLayout;
l->setContentsMargins(lrPadding, 0, lrPadding, 0);
l->setSpacing(sd - 8);
auto newLabel = new QLabel(tr("New to Qt?"), this);
newLabel->setFont(sizedFont(18, this));
l->addWidget(newLabel);
auto learnLabel = new QLabel(tr("Learn how to develop your own applications "
"and explore Qt Creator."), this);
learnLabel->setMaximumWidth(200);
learnLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
learnLabel->setWordWrap(true);
learnLabel->setFont(sizedFont(12, this));
learnLabel->setPalette(lightText());
l->addWidget(learnLabel);
l->addSpacing(12);
auto getStartedButton = new WelcomePageButton(this);
getStartedButton->setText(tr("Get Started Now"));
getStartedButton->setOnClicked([] {
QDesktopServices::openUrl(QString("qthelp://org.qt-project.qtcreator/doc/index.html"));
});
l->addWidget(getStartedButton);
vbox->addItem(l);
vbox->addSpacing(77);
}
{
auto l = new QVBoxLayout;
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(sd + 3);
l->addWidget(new IconAndLink("qtaccount", tr("Qt Account"), "https://account.qt.io", this));
l->addWidget(new IconAndLink("community", tr("Online Community"), "http://forum.qt.io", this));
l->addWidget(new IconAndLink("blogs", tr("Blogs"), "http://planet.qt.io", this));
l->addWidget(new IconAndLink("userguide", tr("User Guide"),
"qthelp://org.qt-project.qtcreator/doc/index.html", this));
vbox->addItem(l);
}
vbox->addStretch(1);
}
QVBoxLayout *m_pluginButtons = nullptr;
}; };
WelcomeMode::WelcomeMode() WelcomeMode::WelcomeMode()
: m_activePlugin(0)
{ {
setDisplayName(tr("Welcome")); setDisplayName(tr("Welcome"));
const Utils::Icon MODE_WELCOME_CLASSIC( const Icon CLASSIC(":/welcome/images/mode_welcome.png");
QLatin1String(":/welcome/images/mode_welcome.png")); const Icon FLAT({{":/welcome/images/mode_welcome_mask.png",
const Utils::Icon MODE_WELCOME_FLAT({ Theme::IconsBaseColor}});
{QLatin1String(":/welcome/images/mode_welcome_mask.png"), Utils::Theme::IconsBaseColor}}); const Icon FLAT_ACTIVE({{":/welcome/images/mode_welcome_mask.png",
const Utils::Icon MODE_WELCOME_FLAT_ACTIVE({ Theme::IconsModeWelcomeActiveColor}});
{QLatin1String(":/welcome/images/mode_welcome_mask.png"), Utils::Theme::IconsModeWelcomeActiveColor}}); setIcon(Icon::modeIcon(CLASSIC, FLAT, FLAT_ACTIVE));
setIcon(Utils::Icon::modeIcon(MODE_WELCOME_CLASSIC,
MODE_WELCOME_FLAT, MODE_WELCOME_FLAT_ACTIVE));
setPriority(Constants::P_MODE_WELCOME); setPriority(Constants::P_MODE_WELCOME);
setId(Constants::MODE_WELCOME); setId(Constants::MODE_WELCOME);
setContextHelpId(QLatin1String("Qt Creator Manual")); setContextHelpId("Qt Creator Manual");
setContext(Context(Constants::C_WELCOME_MODE)); setContext(Context(Constants::C_WELCOME_MODE));
QPalette palette = creatorTheme()->palette();
palette.setColor(QPalette::Background, themeColor(Theme::Welcome_BackgroundColor));
m_modeWidget = new QWidget; m_modeWidget = new QWidget;
m_modeWidget->setObjectName(QLatin1String("WelcomePageModeWidget")); m_modeWidget->setPalette(palette);
QVBoxLayout *layout = new QVBoxLayout(m_modeWidget);
m_sideBar = new SideBar(m_modeWidget);
auto divider = new QWidget(m_modeWidget);
divider->setMaximumWidth(1);
divider->setMinimumWidth(1);
divider->setAutoFillBackground(true);
divider->setPalette(themeColor(Theme::Welcome_DividerColor));
m_pageStack = new QStackedWidget(m_modeWidget);
m_pageStack->setAutoFillBackground(true);
auto hbox = new QHBoxLayout;
hbox->addWidget(m_sideBar);
hbox->addWidget(divider);
hbox->addWidget(m_pageStack);
hbox->setStretchFactor(m_pageStack, 10);
auto layout = new QVBoxLayout(m_modeWidget);
layout->setMargin(0); layout->setMargin(0);
layout->setSpacing(0); layout->setSpacing(0);
layout->addWidget(new StyledBar(m_modeWidget));
m_welcomePage = new QQuickWidget; layout->addItem(hbox);
m_welcomePage->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_welcomePage->setObjectName(QLatin1String("WelcomePage"));
connect(m_welcomePage, &QQuickWidget::sceneGraphError,
this, &WelcomeMode::sceneGraphError);
StyledBar *styledBar = new StyledBar(m_modeWidget);
styledBar->setObjectName(QLatin1String("WelcomePageStyledBar"));
layout->addWidget(styledBar);
m_welcomePage->setParent(m_modeWidget);
layout->addWidget(m_welcomePage);
addKeyboardShortcuts();
setWidget(m_modeWidget); setWidget(m_modeWidget);
} }
void WelcomeMode::addKeyboardShortcuts()
{
const int actionsCount = 9;
Context welcomeContext(Core::Constants::C_WELCOME_MODE);
const Id sessionBase = "Welcome.OpenSession";
for (int i = 1; i <= actionsCount; ++i) {
auto act = new QAction(tr("Open Session #%1").arg(i), this);
Command *cmd = ActionManager::registerAction(act, sessionBase.withSuffix(i), welcomeContext);
cmd->setDefaultKeySequence(QKeySequence((UseMacShortcuts ? tr("Ctrl+Meta+%1") : tr("Ctrl+Alt+%1")).arg(i)));
m_sessionsShortcuts.append(cmd->keySequence().toString(QKeySequence::NativeText));
connect(act, &QAction::triggered, this, [this, i] { openSessionTriggered(i-1); });
connect(cmd, &Command::keySequenceChanged, this, [this, i, cmd] {
m_sessionsShortcuts[i-1] = cmd->keySequence().toString(QKeySequence::NativeText);
emit sessionsShortcutsChanged(m_sessionsShortcuts);
});
}
const Id projectBase = "Welcome.OpenRecentProject";
for (int i = 1; i <= actionsCount; ++i) {
auto act = new QAction(tr("Open Recent Project #%1").arg(i), this);
Command *cmd = ActionManager::registerAction(act, projectBase.withSuffix(i), welcomeContext);
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+%1").arg(i)));
m_recentProjectsShortcuts.append(cmd->keySequence().toString(QKeySequence::NativeText));
connect(act, &QAction::triggered, this, [this, i] { openRecentProjectTriggered(i-1); });
connect(cmd, &Command::keySequenceChanged, this, [this, i, cmd] {
m_recentProjectsShortcuts[i-1] = cmd->keySequence().toString(QKeySequence::NativeText);
emit recentProjectsShortcutsChanged(m_recentProjectsShortcuts);
});
}
}
WelcomeMode::~WelcomeMode() WelcomeMode::~WelcomeMode()
{ {
QSettings *settings = ICore::settings(); QSettings *settings = ICore::settings();
settings->setValue(QLatin1String(currentPageSettingsKeyC), activePlugin()); settings->setValue(currentPageSettingsKeyC, m_activePage.toSetting());
delete m_modeWidget; delete m_modeWidget;
} }
void WelcomeMode::sceneGraphError(QQuickWindow::SceneGraphError, const QString &message)
{
QMessageBox *messageBox =
new QMessageBox(QMessageBox::Warning,
tr("Welcome Mode Load Error"), message,
QMessageBox::Close, m_modeWidget);
messageBox->setModal(false);
messageBox->setAttribute(Qt::WA_DeleteOnClose);
messageBox->show();
}
void WelcomeMode::facilitateQml(QQmlEngine *engine)
{
QStringList importPathList = engine->importPathList();
importPathList.append(resourcePath() + QLatin1String("/welcomescreen"));
engine->addImageProvider(QLatin1String("icons"), new WelcomeImageIconProvider);
if (!debug)
engine->setOutputWarningsToStandardError(false);
QString pluginPath = applicationDirPath();
if (HostOsInfo::isMacHost())
pluginPath += QLatin1String("/../PlugIns");
else
pluginPath += QLatin1String("/../" IDE_LIBRARY_BASENAME "/qtcreator");
importPathList.append(QDir::cleanPath(pluginPath));
engine->setImportPathList(importPathList);
QQmlContext *ctx = engine->rootContext();
ctx->setContextProperty(QLatin1String("welcomeMode"), this);
ctx->setContextProperty(QLatin1String("creatorTheme"), Utils::creatorTheme()->values());
ctx->setContextProperty(QLatin1String("useNativeText"), true);
}
void WelcomeMode::initPlugins() void WelcomeMode::initPlugins()
{ {
QSettings *settings = ICore::settings(); QSettings *settings = ICore::settings();
setActivePlugin(settings->value(QLatin1String(currentPageSettingsKeyC)).toInt()); m_activePage = Id::fromSetting(settings->value(currentPageSettingsKeyC));
QQmlEngine *engine = m_welcomePage->engine(); const QList<IWelcomePage *> availablePages = PluginManager::getObjects<IWelcomePage>();
facilitateQml(engine); for (IWelcomePage *page : availablePages)
addPage(page);
QList<IWelcomePage *> availablePages = PluginManager::getObjects<IWelcomePage>();
addPages(engine, availablePages);
// make sure later added pages are made available too: // make sure later added pages are made available too:
connect(PluginManager::instance(), &PluginManager::objectAdded, engine, [this, engine](QObject *obj) { connect(PluginManager::instance(), &PluginManager::objectAdded, this, [this](QObject *obj) {
if (IWelcomePage *page = qobject_cast<IWelcomePage*>(obj)) if (IWelcomePage *page = qobject_cast<IWelcomePage*>(obj))
addPages(engine, QList<IWelcomePage *>() << page); addPage(page);
}); });
QString path = resourcePath() + QLatin1String("/welcomescreen/welcomescreen.qml"); if (!m_activePage.isValid() && !m_pageButtons.isEmpty()) {
m_activePage = m_pluginList.at(0)->id();
// finally, load the root page m_pageButtons.at(0)->click();
m_welcomePage->setSource(QUrl::fromLocalFile(path)); }
} }
bool WelcomeMode::openDroppedFiles(const QList<QUrl> &urls) bool WelcomeMode::openDroppedFiles(const QList<QUrl> &urls)
{ {
// DropArea {
// anchors.fill: parent
// keys: ["text/uri-list"]
// onDropped: {
// if ((drop.supportedActions & Qt.CopyAction != 0)
// && welcomeMode.openDroppedFiles(drop.urls))
// drop.accept(Qt.CopyAction);
// }
// }
const QList<QUrl> localUrls = Utils::filtered(urls, &QUrl::isLocalFile); const QList<QUrl> localUrls = Utils::filtered(urls, &QUrl::isLocalFile);
if (!localUrls.isEmpty()) { if (!localUrls.isEmpty()) {
QTimer::singleShot(0, [localUrls]() { QTimer::singleShot(0, [localUrls]() {
@@ -325,54 +363,38 @@ bool WelcomeMode::openDroppedFiles(const QList<QUrl> &urls)
return false; return false;
} }
void WelcomeMode::addPages(QQmlEngine *engine, const QList<IWelcomePage *> &pages) void WelcomeMode::addPage(IWelcomePage *page)
{ {
QList<IWelcomePage *> addedPages = pages; int idx;
Utils::sort(addedPages, &IWelcomePage::priority); int pagePriority = page->priority();
// insert into m_pluginList, keeping m_pluginList sorted by priority for (idx = 0; idx != m_pluginList.size(); ++idx) {
auto addIt = addedPages.cbegin(); if (m_pluginList.at(idx)->priority() >= pagePriority)
auto currentIt = m_pluginList.begin(); break;
while (addIt != addedPages.cend()) {
IWelcomePage *page = *addIt;
QTC_ASSERT(!m_idPageMap.contains(page->id()), ++addIt; continue);
while (currentIt != m_pluginList.end() && (*currentIt)->priority() <= page->priority())
++currentIt;
// currentIt is now either end() or a page with higher value
currentIt = m_pluginList.insert(currentIt, page);
m_idPageMap.insert(page->id(), page);
page->facilitateQml(engine);
++currentIt;
++addIt;
} }
// update model through reset auto pageButton = new WelcomePageButton(m_sideBar);
QQmlContext *ctx = engine->rootContext(); auto pageId = page->id();
ctx->setContextProperty(QLatin1String("pagesModel"), QVariant::fromValue( pageButton->setText(page->title());
Utils::transform(m_pluginList, // transform into QList<QObject *> pageButton->setActiveChecker([this, pageId] { return m_activePage == pageId; });
[](IWelcomePage *page) -> QObject * {
return page;
})));
}
WelcomePlugin::WelcomePlugin() m_pluginList.append(page);
: m_welcomeMode(0) m_pageButtons.append(pageButton);
{
}
bool WelcomePlugin::initialize(const QStringList & /* arguments */, QString *errorMessage) m_sideBar->m_pluginButtons->insertWidget(idx, pageButton);
{
if (!Utils::HostOsInfo::canCreateOpenGLContext(errorMessage))
return false;
m_welcomeMode = new WelcomeMode; QWidget *stackPage = page->createWidget();
addAutoReleasedObject(m_welcomeMode); stackPage->setAutoFillBackground(true);
m_pageStack->insertWidget(idx, stackPage);
return true; auto onClicked = [this, page, pageId, stackPage] {
} m_activePage = pageId;
m_pageStack->setCurrentWidget(stackPage);
for (WelcomePageButton *pageButton : m_pageButtons)
pageButton->recheckActive();
};
void WelcomePlugin::extensionsInitialized() pageButton->setOnClicked(onClicked);
{ if (pageId == m_activePage)
m_welcomeMode->initPlugins(); onClicked();
ModeManager::activateMode(m_welcomeMode->id());
} }
} // namespace Internal } // namespace Internal

View File

@@ -1,55 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <extensionsystem/iplugin.h>
QT_BEGIN_NAMESPACE
class QQmlEngine;
QT_END_NAMESPACE
namespace Welcome {
namespace Internal {
class WelcomeMode;
class WelcomePlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Welcome.json")
public:
WelcomePlugin();
virtual bool initialize(const QStringList &arguments, QString *errorMessage);
virtual void extensionsInitialized();
private:
WelcomeMode *m_welcomeMode;
};
} // namespace Welcome
} // namespace Internal