mirror of https://code.videolan.org/videolan/vlc
qml: make FrostedGlassEffect a layer effect
... so that we can set background on it. Also, - Make MiniPlayer a control. - Refactor ScanProgressBar and make it a control.
This commit is contained in:
parent
d28f235b93
commit
e3b28612d3
|
@ -213,16 +213,36 @@ FocusScope {
|
|||
onContentModelChanged: modelSortSettingHandler.set(sourcesBanner.contentModel, History.viewPath)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: VLCStyle.colors.bg
|
||||
FocusScope {
|
||||
focus: true
|
||||
id: medialibId
|
||||
anchors.fill: parent
|
||||
|
||||
FocusScope {
|
||||
focus: true
|
||||
id: medialibId
|
||||
Navigation.parentItem: root
|
||||
|
||||
Rectangle {
|
||||
id: parentRectangle
|
||||
anchors.fill: parent
|
||||
|
||||
Navigation.parentItem: root
|
||||
color: VLCStyle.colors.bg
|
||||
|
||||
layer.enabled: (((GraphicsInfo.shaderType === GraphicsInfo.GLSL)) &&
|
||||
((GraphicsInfo.shaderSourceType & GraphicsInfo.ShaderSourceString))) &&
|
||||
(miniPlayer.visible || (loaderProgress.active && loaderProgress.item.visible))
|
||||
|
||||
layer.effect: Widgets.FrostedGlassEffect {
|
||||
tint: VLCStyle.colors.lowerBanner
|
||||
|
||||
effectRect: {
|
||||
var _height = 0
|
||||
if (loaderProgress.active && loaderProgress.item.visible)
|
||||
_height += loaderProgress.item.height
|
||||
if (miniPlayer.visible)
|
||||
_height += miniPlayer.height
|
||||
|
||||
return Qt.rect(0, height - _height, width, _height)
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: mainColumn
|
||||
|
@ -281,27 +301,6 @@ FocusScope {
|
|||
: VLCStyle.applicationHorizontalMargin
|
||||
leftMargin: VLCStyle.applicationHorizontalMargin
|
||||
}
|
||||
|
||||
// This item is the root of a large hierarchy
|
||||
// which requires many batches to be rendered.
|
||||
// When the miniPlayer effect is active, this
|
||||
// item (source item) gets rendered in an offscreen
|
||||
// surface. If we don't enable layer here,
|
||||
// it (along with children) gets rendered again
|
||||
// in the assigned window.
|
||||
// If layer is enabled, instead of rendering one
|
||||
// more time with many batches, a dynamic texture
|
||||
// from the offscreen surface is used. This behavior
|
||||
// reduces the amount of batches from 2x to x+1.
|
||||
// A side effect is having to draw a large texture
|
||||
// with blending on, but this must be cheaper redrawing
|
||||
// all the batches.
|
||||
// TODO: Reconsider this behavior when batching is optimized.
|
||||
layer.enabled: miniPlayer.visible && miniPlayer.effectAvailable
|
||||
|
||||
// Enable clipping so that the effect does not sit
|
||||
// on top of the source.
|
||||
clip: miniPlayer.visible && miniPlayer.effectAvailable
|
||||
}
|
||||
|
||||
FocusScope {
|
||||
|
@ -430,114 +429,110 @@ FocusScope {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loaderProgress
|
||||
Loader {
|
||||
id: loaderProgress
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: miniPlayer.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: miniPlayer.top
|
||||
|
||||
active: (MainCtx.mediaLibraryAvailable && MainCtx.mediaLibrary.idle === false)
|
||||
active: (MainCtx.mediaLibraryAvailable && MainCtx.mediaLibrary.idle === false)
|
||||
|
||||
source: "qrc:///widgets/ScanProgressBar.qml"
|
||||
source: "qrc:///widgets/ScanProgressBar.qml"
|
||||
|
||||
onItemChanged: {
|
||||
if (item === null) return
|
||||
onLoaded: {
|
||||
item.background.visible = Qt.binding(function() { return !parentRectangle.layer.enabled })
|
||||
|
||||
// NOTE: These are required for the FrostedGlassEffect.
|
||||
item.leftPadding = Qt.binding(function() { return VLCStyle.margin_large + VLCStyle.applicationHorizontalMargin })
|
||||
item.rightPadding = Qt.binding(function() { return VLCStyle.margin_large + VLCStyle.applicationHorizontalMargin })
|
||||
item.bottomPadding = Qt.binding(function() { return VLCStyle.margin_small + (miniPlayer.visible ? 0 : VLCStyle.applicationVerticalMargin) })
|
||||
}
|
||||
}
|
||||
|
||||
item.source = Qt.binding(function() { return stackView })
|
||||
|
||||
item.sourceRect = Qt.binding(function() {
|
||||
return stackView.mapFromItem(parent, x, y, width, height)
|
||||
})
|
||||
}
|
||||
P.PIPPlayer {
|
||||
id: playerPip
|
||||
anchors {
|
||||
bottom: miniPlayer.top
|
||||
left: parent.left
|
||||
bottomMargin: VLCStyle.margin_normal
|
||||
leftMargin: VLCStyle.margin_normal + VLCStyle.applicationHorizontalMargin
|
||||
}
|
||||
|
||||
P.PIPPlayer {
|
||||
id: playerPip
|
||||
anchors {
|
||||
bottom: miniPlayer.top
|
||||
left: parent.left
|
||||
bottomMargin: VLCStyle.margin_normal
|
||||
leftMargin: VLCStyle.margin_normal + VLCStyle.applicationHorizontalMargin
|
||||
}
|
||||
width: VLCStyle.dp(320, VLCStyle.scale)
|
||||
height: VLCStyle.dp(180, VLCStyle.scale)
|
||||
z: 2
|
||||
visible: !root._inhibitMiniPlayer && root._showMiniPlayer && MainCtx.hasEmbededVideo
|
||||
enabled: !root._inhibitMiniPlayer && root._showMiniPlayer && MainCtx.hasEmbededVideo
|
||||
|
||||
width: VLCStyle.dp(320, VLCStyle.scale)
|
||||
height: VLCStyle.dp(180, VLCStyle.scale)
|
||||
z: 2
|
||||
visible: !root._inhibitMiniPlayer && root._showMiniPlayer && MainCtx.hasEmbededVideo
|
||||
enabled: !root._inhibitMiniPlayer && root._showMiniPlayer && MainCtx.hasEmbededVideo
|
||||
|
||||
dragXMin: 0
|
||||
dragXMax: root.width - playerPip.width
|
||||
dragYMin: sourcesBanner.y + sourcesBanner.height
|
||||
dragYMax: miniPlayer.y - playerPip.height
|
||||
|
||||
//keep the player visible on resize
|
||||
Connections {
|
||||
target: root
|
||||
onWidthChanged: {
|
||||
if (playerPip.x > playerPip.dragXMax)
|
||||
playerPip.x = playerPip.dragXMax
|
||||
}
|
||||
onHeightChanged: {
|
||||
if (playerPip.y > playerPip.dragYMax)
|
||||
playerPip.y = playerPip.dragYMax
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DG.Dialogs {
|
||||
z: 10
|
||||
bgContent: root
|
||||
|
||||
anchors {
|
||||
bottom: miniPlayer.visible ? miniPlayer.top : parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
P.MiniPlayer {
|
||||
id: miniPlayer
|
||||
|
||||
BindingCompat on state {
|
||||
when: root._inhibitMiniPlayer && !miniPlayer.visible
|
||||
value: ""
|
||||
}
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
z: 3
|
||||
Navigation.parentItem: medialibId
|
||||
Navigation.upItem: stackView
|
||||
Navigation.cancelItem:sourcesBanner
|
||||
onVisibleChanged: {
|
||||
if (!visible && miniPlayer.activeFocus)
|
||||
stackView.forceActiveFocus()
|
||||
}
|
||||
|
||||
effectSource: stackView
|
||||
effectSourceRect: effectSource.mapFromItem(parent,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height)
|
||||
}
|
||||
dragXMin: 0
|
||||
dragXMax: root.width - playerPip.width
|
||||
dragYMin: sourcesBanner.y + sourcesBanner.height
|
||||
dragYMax: miniPlayer.y - playerPip.height
|
||||
|
||||
//keep the player visible on resize
|
||||
Connections {
|
||||
target: Player
|
||||
onHasVideoOutputChanged: {
|
||||
if (Player.hasVideoOutput && MainCtx.hasEmbededVideo) {
|
||||
if (History.current.view !== "player")
|
||||
g_mainDisplay.showPlayer()
|
||||
} else {
|
||||
_showMiniPlayer = false;
|
||||
}
|
||||
target: root
|
||||
onWidthChanged: {
|
||||
if (playerPip.x > playerPip.dragXMax)
|
||||
playerPip.x = playerPip.dragXMax
|
||||
}
|
||||
onHeightChanged: {
|
||||
if (playerPip.y > playerPip.dragYMax)
|
||||
playerPip.y = playerPip.dragYMax
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DG.Dialogs {
|
||||
z: 10
|
||||
bgContent: root
|
||||
|
||||
anchors {
|
||||
bottom: miniPlayer.visible ? miniPlayer.top : parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
P.MiniPlayer {
|
||||
id: miniPlayer
|
||||
|
||||
BindingCompat on state {
|
||||
when: root._inhibitMiniPlayer && !miniPlayer.visible
|
||||
value: ""
|
||||
}
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
z: 3
|
||||
|
||||
rightPadding: VLCStyle.applicationHorizontalMargin
|
||||
leftPadding: VLCStyle.applicationHorizontalMargin
|
||||
bottomPadding: VLCStyle.applicationVerticalMargin
|
||||
|
||||
background.visible: !parentRectangle.layer.enabled
|
||||
|
||||
Navigation.parentItem: medialibId
|
||||
Navigation.upItem: stackView
|
||||
Navigation.cancelItem:sourcesBanner
|
||||
onVisibleChanged: {
|
||||
if (!visible && miniPlayer.activeFocus)
|
||||
stackView.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Player
|
||||
onHasVideoOutputChanged: {
|
||||
if (Player.hasVideoOutput && MainCtx.hasEmbededVideo) {
|
||||
if (History.current.view !== "player")
|
||||
g_mainDisplay.showPlayer()
|
||||
} else {
|
||||
_showMiniPlayer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
*****************************************************************************/
|
||||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.4
|
||||
import QtQuick.Templates 2.4 as T
|
||||
import QtQuick.Layouts 1.11
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
|
@ -25,17 +26,15 @@ import org.videolan.vlc 0.1
|
|||
import "qrc:///widgets/" as Widgets
|
||||
import "qrc:///style/"
|
||||
|
||||
FocusScope {
|
||||
T.Pane {
|
||||
id: root
|
||||
|
||||
implicitHeight: controlBar.implicitHeight
|
||||
height: 0
|
||||
|
||||
visible: false
|
||||
implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentItem.implicitHeight + topPadding + bottomPadding)
|
||||
|
||||
property alias effectSource: effect.source
|
||||
property alias effectSourceRect: effect.sourceRect
|
||||
property alias effectAvailable: effect.effectAvailable
|
||||
visible: false
|
||||
|
||||
state: (Player.playingState === Player.PLAYING_STATE_STOPPED) ? ""
|
||||
: "expanded"
|
||||
|
@ -68,22 +67,11 @@ FocusScope {
|
|||
acceptedButtons: Qt.AllButtons
|
||||
}
|
||||
|
||||
Widgets.FrostedGlassEffect {
|
||||
id: effect
|
||||
anchors.fill: parent
|
||||
|
||||
tint: VLCStyle.colors.lowerBanner
|
||||
background: Rectangle {
|
||||
color: VLCStyle.colors.bg
|
||||
}
|
||||
|
||||
ControlBar {
|
||||
id: controlBar
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
rightPadding: VLCStyle.applicationHorizontalMargin
|
||||
leftPadding: rightPadding
|
||||
bottomPadding: VLCStyle.applicationVerticalMargin
|
||||
|
||||
contentItem: ControlBar {
|
||||
focus: true
|
||||
colors: VLCStyle.colors
|
||||
textPosition: ControlBar.TimeTextPosition.Hide
|
||||
|
@ -94,7 +82,7 @@ FocusScope {
|
|||
Navigation.parentItem: root
|
||||
|
||||
Keys.onPressed: {
|
||||
controlBar.Navigation.defaultKeyAction(event)
|
||||
Navigation.defaultKeyAction(event)
|
||||
|
||||
if (!event.accepted) {
|
||||
MainCtx.sendHotkey(event.key, event.modifiers)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (C) 2020 VLC authors and VideoLAN
|
||||
* Copyright (C) 2022 VLC authors and VideoLAN
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,101 +21,114 @@ import QtGraphicalEffects 1.0
|
|||
|
||||
import "qrc:///style/"
|
||||
|
||||
// This item can be used as a layer effect.
|
||||
// Right now, it has the following limitations:
|
||||
// * The blur effect is processed for the whole source,
|
||||
// even though it is only shown for the area denoted
|
||||
// by effectRect. This is caused by FastBlur not
|
||||
// accepting a source rectangle.
|
||||
// * The source is sampled and displayed as a whole,
|
||||
// however it is stacked below of the blur effect
|
||||
// so it is only partly seen as intended.
|
||||
// * As a corollary of the previous limitation, you should
|
||||
// always have a solid background for the source item.
|
||||
// otherwise, the effect can not work properly.
|
||||
Item {
|
||||
id: effect
|
||||
|
||||
property Item source
|
||||
property rect sourceRect: mapToItem(source, x, y, width, height)
|
||||
property var source
|
||||
|
||||
property bool recursive: false
|
||||
property real blurRadius: 64
|
||||
property color tint
|
||||
// Rectangular area where the effect should be applied:
|
||||
property alias effectRect: blurProxy.sourceRect
|
||||
|
||||
property real tintStrength: 0.7
|
||||
property alias blurRadius: blurEffect.radius
|
||||
|
||||
property color tint: "transparent"
|
||||
property real tintStrength: Qt.colorEqual(tint, "transparent") ? 0.0 : 0.7
|
||||
property real noiseStrength: 0.02
|
||||
property real exclusionStrength: 0.09
|
||||
|
||||
readonly property bool effectAvailable: (GraphicsInfo.shaderType === GraphicsInfo.GLSL) &&
|
||||
(GraphicsInfo.shaderSourceType & GraphicsInfo.ShaderSourceString)
|
||||
ShaderEffect {
|
||||
anchors.fill: parent
|
||||
|
||||
opacity: source.opacity
|
||||
property alias source: effect.source
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
cullMode: ShaderEffect.BackFaceCulling
|
||||
}
|
||||
|
||||
FastBlur {
|
||||
id: blurEffect
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
sourceComponent: effect.effectAvailable ? effectComponent : rectComponent
|
||||
source: effect.source
|
||||
|
||||
Component {
|
||||
id: rectComponent
|
||||
radius: 64
|
||||
|
||||
Rectangle {
|
||||
color: effect.tint
|
||||
}
|
||||
}
|
||||
visible: false
|
||||
}
|
||||
|
||||
Component {
|
||||
id: effectComponent
|
||||
ShaderEffectSource {
|
||||
id: blurProxy
|
||||
|
||||
FastBlur {
|
||||
id: blurEffect
|
||||
x: Math.floor(sourceRect.x)
|
||||
y: Math.floor(sourceRect.y)
|
||||
width: sourceRect.width > 0 ? Math.ceil(sourceRect.width)
|
||||
: implicitWidth
|
||||
height: sourceRect.height > 0 ? Math.ceil(sourceRect.height)
|
||||
: implicitHeight
|
||||
|
||||
source: ShaderEffectSource {
|
||||
id: effectSource
|
||||
smooth: false
|
||||
sourceItem: effect.source
|
||||
sourceRect: effect.sourceRect
|
||||
visible: false
|
||||
samples: 0
|
||||
implicitWidth: Math.ceil(parent.width)
|
||||
implicitHeight: Math.ceil(parent.height)
|
||||
|
||||
sourceItem: blurEffect
|
||||
recursive: false
|
||||
samples: 0
|
||||
smooth: false
|
||||
|
||||
mipmap: false
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: ShaderEffect {
|
||||
readonly property color tint: effect.tint
|
||||
readonly property real tintStrength: effect.tintStrength
|
||||
readonly property real noiseStrength: effect.noiseStrength
|
||||
readonly property real exclusionStrength: effect.exclusionStrength
|
||||
|
||||
cullMode: ShaderEffect.BackFaceCulling
|
||||
|
||||
fragmentShader: "
|
||||
uniform lowp sampler2D source; // this item
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform lowp float qt_Opacity;
|
||||
|
||||
uniform lowp vec4 tint;
|
||||
|
||||
uniform lowp float exclusionStrength;
|
||||
uniform lowp float noiseStrength;
|
||||
uniform lowp float tintStrength;
|
||||
|
||||
mediump float rand(highp vec2 co){
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
radius: effect.blurRadius
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: ShaderEffect {
|
||||
readonly property color tint: effect.tint
|
||||
readonly property real tintStrength: effect.tintStrength
|
||||
readonly property real noiseStrength: effect.noiseStrength
|
||||
readonly property real exclusionStrength: effect.exclusionStrength
|
||||
|
||||
cullMode: ShaderEffect.BackFaceCulling
|
||||
|
||||
fragmentShader: "
|
||||
uniform lowp sampler2D source; // this item
|
||||
varying highp vec2 qt_TexCoord0;
|
||||
|
||||
uniform lowp float qt_Opacity;
|
||||
|
||||
uniform lowp vec4 tint;
|
||||
|
||||
uniform lowp float exclusionStrength;
|
||||
uniform lowp float noiseStrength;
|
||||
uniform lowp float tintStrength;
|
||||
|
||||
mediump float rand(highp vec2 co){
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
mediump vec4 exclude(mediump vec4 src, mediump vec4 dst)
|
||||
{
|
||||
return src + dst - 2.0 * src * dst;
|
||||
}
|
||||
|
||||
void main() {
|
||||
mediump float r = rand(qt_TexCoord0) - 0.5;
|
||||
mediump vec4 noise = vec4(r,r,r,1.0) * noiseStrength;
|
||||
mediump vec4 blurred = texture2D(source, qt_TexCoord0);
|
||||
|
||||
mediump vec4 exclColor = vec4(exclusionStrength, exclusionStrength, exclusionStrength, 0.0);
|
||||
|
||||
blurred = exclude(blurred, exclColor);
|
||||
|
||||
gl_FragColor = (mix(blurred, tint, tintStrength) + noise) * qt_Opacity;
|
||||
}"
|
||||
mediump vec4 exclude(mediump vec4 src, mediump vec4 dst)
|
||||
{
|
||||
return src + dst - 2.0 * src * dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
mediump float r = rand(qt_TexCoord0) - 0.5;
|
||||
mediump vec4 noise = vec4(r,r,r,1.0) * noiseStrength;
|
||||
mediump vec4 blurred = texture2D(source, qt_TexCoord0);
|
||||
|
||||
mediump vec4 exclColor = vec4(exclusionStrength, exclusionStrength, exclusionStrength, 0.0);
|
||||
|
||||
blurred = exclude(blurred, exclColor);
|
||||
|
||||
gl_FragColor = (mix(blurred, tint, tintStrength) + noise) * qt_Opacity;
|
||||
}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,138 +19,115 @@
|
|||
import QtQuick 2.11
|
||||
import QtQuick.Controls 2.4
|
||||
import QtQuick.Templates 2.4 as T
|
||||
import QtQuick.Layouts 1.11
|
||||
|
||||
import org.videolan.vlc 0.1
|
||||
import org.videolan.medialib 0.1
|
||||
|
||||
import "qrc:///style/"
|
||||
|
||||
FrostedGlassEffect {
|
||||
// Settings
|
||||
T.ProgressBar {
|
||||
id: control
|
||||
|
||||
height: _getHeight()
|
||||
implicitWidth: Math.max(background ? background.implicitWidth : 0,
|
||||
contentItem.implicitWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(background ? background.implicitHeight : 0,
|
||||
contentItem.implicitHeight + topPadding + bottomPadding)
|
||||
|
||||
tint: VLCStyle.colors.lowerBanner
|
||||
rightPadding: VLCStyle.margin_large
|
||||
leftPadding: VLCStyle.margin_large
|
||||
bottomPadding: VLCStyle.margin_small
|
||||
topPadding: VLCStyle.margin_small
|
||||
|
||||
// Functions
|
||||
from: 0
|
||||
to: 100
|
||||
|
||||
// Private
|
||||
value: MediaLib.parsingProgress
|
||||
|
||||
function _getHeight() {
|
||||
var height = column.implicitHeight + VLCStyle.margin_small * 2
|
||||
indeterminate: MediaLib.discoveryPending
|
||||
|
||||
// NOTE: We don't need to take the vertical safe area into consideration when the
|
||||
// miniPlayer is visible.
|
||||
if (g_mainDisplay.hasMiniPlayer)
|
||||
return height
|
||||
else
|
||||
return height + VLCStyle.applicationVerticalMargin
|
||||
background: Rectangle {
|
||||
color: VLCStyle.colors.bg
|
||||
}
|
||||
|
||||
// Children
|
||||
|
||||
ColumnLayout {
|
||||
id: column
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.leftMargin: VLCStyle.margin_large + VLCStyle.applicationHorizontalMargin
|
||||
anchors.rightMargin: anchors.leftMargin
|
||||
|
||||
anchors.topMargin: VLCStyle.margin_small
|
||||
|
||||
anchors.bottomMargin: (g_mainDisplay.hasMiniPlayer) ? VLCStyle.margin_small
|
||||
: VLCStyle.margin_small
|
||||
+ VLCStyle.applicationVerticalMargin
|
||||
|
||||
contentItem: Column {
|
||||
spacing: VLCStyle.margin_small
|
||||
|
||||
T.ProgressBar {
|
||||
id: control
|
||||
Item {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: VLCStyle.heightBar_xxsmall
|
||||
implicitWidth: 200
|
||||
|
||||
height: VLCStyle.heightBar_xxsmall
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
from: 0
|
||||
to: 100
|
||||
implicitHeight: VLCStyle.heightBar_xxxsmall
|
||||
|
||||
value: MediaLib.parsingProgress
|
||||
color: VLCStyle.colors.sliderBarMiniplayerBgColor
|
||||
}
|
||||
|
||||
indeterminate: MediaLib.discoveryPending
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
contentItem: Item {
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitWidth: parent.width * control.visualPosition
|
||||
implicitHeight: VLCStyle.heightBar_xxsmall
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
// NOTE: We want round corners.
|
||||
radius: height
|
||||
|
||||
height: VLCStyle.heightBar_xxxsmall
|
||||
visible: !control.indeterminate
|
||||
|
||||
color: VLCStyle.colors.sliderBarMiniplayerBgColor
|
||||
}
|
||||
color: VLCStyle.colors.accent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Rectangle {
|
||||
property real position: 0
|
||||
|
||||
width: parent.width * control.visualPosition
|
||||
height: VLCStyle.heightBar_xxsmall
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
// NOTE: We want round corners.
|
||||
radius: height
|
||||
// NOTE: Why 0.24 though ?
|
||||
implicitWidth: parent.width * 0.24
|
||||
implicitHeight: VLCStyle.heightBar_xxsmall
|
||||
|
||||
visible: (control.indeterminate === false)
|
||||
x: Math.round((parent.width - width) * position)
|
||||
|
||||
color: VLCStyle.colors.accent
|
||||
}
|
||||
// NOTE: We want round corners.
|
||||
radius: height
|
||||
|
||||
Rectangle {
|
||||
property real position: 0
|
||||
visible: control.indeterminate
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: VLCStyle.colors.accent
|
||||
|
||||
// NOTE: Why 0.24 though ?
|
||||
width: parent.width * 0.24
|
||||
height: VLCStyle.heightBar_xxsmall
|
||||
SequentialAnimation on position {
|
||||
loops: Animation.Infinite
|
||||
|
||||
x: Math.round((parent.width - width) * position)
|
||||
running: visible
|
||||
|
||||
// NOTE: We want round corners.
|
||||
radius: height
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
to: 1.0
|
||||
|
||||
visible: control.indeterminate
|
||||
duration: VLCStyle.durationSliderBouncing
|
||||
easing.type: Easing.OutBounce
|
||||
}
|
||||
|
||||
color: VLCStyle.colors.accent
|
||||
NumberAnimation {
|
||||
from: 1.0
|
||||
to: 0
|
||||
|
||||
SequentialAnimation on position {
|
||||
loops: Animation.Infinite
|
||||
|
||||
running: visible
|
||||
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
to: 1.0
|
||||
|
||||
duration: VLCStyle.durationSliderBouncing
|
||||
easing.type: Easing.OutBounce
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
from: 1.0
|
||||
to: 0
|
||||
|
||||
duration: VLCStyle.durationSliderBouncing
|
||||
easing.type: Easing.OutBounce
|
||||
}
|
||||
duration: VLCStyle.durationSliderBouncing
|
||||
easing.type: Easing.OutBounce
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SubtitleLabel {
|
||||
Layout.fillWidth: true
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
text: (MediaLib.discoveryPending) ? I18n.qtr("Scanning %1")
|
||||
.arg(MediaLib.discoveryEntryPoint)
|
||||
|
|
Loading…
Reference in New Issue