[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt/qml: chapters UI redesign
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Fri Jul 22 09:47:31 UTC 2022
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
8ed9912b by Leon Vitanos at 2022-07-22T09:19:45+00:00
qt/qml: chapters UI redesign
- - - - -
ce53cd1e by Leon Vitanos at 2022-07-22T09:19:45+00:00
qml: fix activeFocus issue by using invalidateFilter instead of invalidate
- - - - -
4 changed files:
- modules/gui/qt/player/control_list_filter.cpp
- modules/gui/qt/player/input_models.cpp
- modules/gui/qt/player/input_models.hpp
- modules/gui/qt/player/qml/SliderBar.qml
Changes:
=====================================
modules/gui/qt/player/control_list_filter.cpp
=====================================
@@ -45,7 +45,7 @@ bool ControlListFilter::filterAcceptsRow(int source_row, const QModelIndex &) co
{
QAbstractItemModel * model = sourceModel();
- if (model == nullptr || m_player == nullptr)
+ if (model == nullptr || m_player == nullptr || m_ctx == nullptr)
return true;
QVariant variant = model->data(model->index(source_row, 0), ControlListModel::ID_ROLE);
@@ -63,11 +63,9 @@ bool ControlListFilter::filterAcceptsRow(int source_row, const QModelIndex &) co
}
else if (type == ControlListModel::BOOKMARK_BUTTON)
{
- assert(m_ctx);
return (m_ctx->hasMediaLibrary() || m_player->hasChapters() || m_player->hasTitles());
}
-
return true;
}
@@ -87,10 +85,10 @@ void ControlListFilter::setPlayer(PlayerController * player)
m_player = player;
- connect(player, &PlayerController::teletextAvailableChanged, this, &ControlListFilter::invalidate);
- connect(player, &PlayerController::hasMenuChanged, this, &ControlListFilter::invalidate);
- connect(player, &PlayerController::hasChaptersChanged, this, &ControlListFilter::invalidate);
- connect(player, &PlayerController::hasTitlesChanged, this, &ControlListFilter::invalidate);
+ connect(player, &PlayerController::teletextAvailableChanged, this, &ControlListFilter::invalidateFilter);
+ connect(player, &PlayerController::hasMenuChanged, this, &ControlListFilter::invalidateFilter);
+ connect(player, &PlayerController::hasChaptersChanged, this, &ControlListFilter::invalidateFilter);
+ connect(player, &PlayerController::hasTitlesChanged, this, &ControlListFilter::invalidateFilter);
invalidate();
=====================================
modules/gui/qt/player/input_models.cpp
=====================================
@@ -325,8 +325,13 @@ QVariant ChapterListModel::data(const QModelIndex &index, int role) const
return QVariant::fromValue<bool>(row == m_current);
else if (role == ChapterListRoles::TimeRole )
return QVariant::fromValue<vlc_tick_t>(chapter.time);
- else if (role == ChapterListRoles::PositionRole && (m_title->length != 0) )
- return QVariant::fromValue<float>(chapter.time /(float) m_title->length);
+ else if (role == ChapterListRoles::StartPositionRole && (m_title->length != 0))
+ return QVariant::fromValue<float>(chapter.time / (float) m_title->length);
+ else if (role == ChapterListRoles::EndPositionRole && (m_title->length != 0))
+ return (size_t)row + 1 == m_title->chapter_count
+ ? QVariant::fromValue<float> (1)
+ : QVariant::fromValue<float> (m_title->chapters[row+1].time / (float) m_title->length);
+
return QVariant{};
}
@@ -354,7 +359,8 @@ QHash<int, QByteArray> ChapterListModel::roleNames() const
{Qt::DisplayRole, "display"},
{Qt::CheckStateRole, "checked"},
{ChapterListRoles::TimeRole, "time"},
- {ChapterListRoles::PositionRole, "position"}
+ {ChapterListRoles::StartPositionRole, "startPosition"},
+ {ChapterListRoles::EndPositionRole, "endPosition"}
};
}
@@ -436,6 +442,8 @@ int ChapterListModel::getClosestChapterFromPos(float pos, float threshold) const
closestTime = currentChapterTime;
chapterIndex = i;
}
+ else
+ break;
}
if (closestTime == VLC_TICK_INVALID)
=====================================
modules/gui/qt/player/input_models.hpp
=====================================
@@ -165,7 +165,8 @@ public:
//user role
enum ChapterListRoles {
TimeRole = Qt::UserRole + 1 ,
- PositionRole
+ StartPositionRole,
+ EndPositionRole
};
public:
ChapterListModel(vlc_player_t* player, QObject* parent = nullptr);
=====================================
modules/gui/qt/player/qml/SliderBar.qml
=====================================
@@ -29,13 +29,20 @@ import "qrc:///util/Helpers.js" as Helpers
Slider {
id: control
+ readonly property real _hoveredScalingFactor: 2
property int barHeight: VLCStyle.dp(5, VLCStyle.scale)
+ readonly property real _scaledBarHeight: control.barHeight * _hoveredScalingFactor
+ readonly property real _scaledY: (-control.barHeight / 2) * (control._hoveredScalingFactor - 1)
+
property bool _isSeekPointsShown: true
+ readonly property int _seekPointsDistance: VLCStyle.dp(2, VLCStyle.scale)
+ readonly property int _seekPointsRadius: VLCStyle.dp(0.5, VLCStyle.scale)
+ readonly property real _scaledSeekPointsRadius: _seekPointsRadius * _hoveredScalingFactor
+
+ property bool _currentChapterHovered: false
property real _tooltipPosition: timeTooltip.pos.x / sliderRectMouseArea.width
property alias backgroundColor: sliderRect.color
- property alias progressBarColor: progressRect.color
-
property VLCColors colors: VLCStyle.colors
Keys.onRightPressed: Player.jumpFwd()
@@ -134,28 +141,37 @@ Slider {
onPositionChanged: fsm.playerUpdatePosition(Player.position)
}
+ Component.onCompleted: {
+ fsm.playerUpdatePosition(Player.position)
+ }
+
height: control.barHeight
implicitHeight: control.barHeight
- topPadding: 0
- leftPadding: 0
- bottomPadding: 0
- rightPadding: 0
+ padding: 0
stepSize: 0.01
- background: Rectangle {
- id: sliderRect
+ background: Item {
+ id: slider
width: control.availableWidth
implicitHeight: control.implicitHeight
height: implicitHeight
- color: control.colors.setColorAlpha( control.colors.playerFg, 0.2 )
- radius: implicitHeight
+
+ Rectangle {
+ id: sliderRect
+ visible: !Player.hasChapters
+ color: backgroundColor
+ anchors.fill: parent
+ radius: implicitHeight
+ }
MouseArea {
id: sliderRectMouseArea
- anchors.fill: parent
+ width: control.availableWidth
+ height: control._scaledBarHeight
+ y: control._scaledY
hoverEnabled: true
@@ -175,12 +191,101 @@ Slider {
}
}
+ Repeater {
+ id: seekpointsRptr
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: control.barHeight
+ visible: Player.hasChapters
+
+ model: Player.chapters
+ Item {
+ Rectangle {
+ id: seekpointsRect
+ readonly property real startPosition: model.startPosition === undefined ? 0.0 : model.startPosition
+ readonly property real endPosition: model.endPosition === undefined ? 1.0 : model.endPosition
+
+ readonly property int _currentChapter: {
+ if (control.visualPosition < seekpointsRect.startPosition)
+ return 1
+ else if (control.visualPosition > seekpointsRect.endPosition)
+ return -1
+ return 0
+ }
+ on_CurrentChapterChanged: {
+ if(_hovered)
+ control._currentChapterHovered = _currentChapter === 0
+ }
+
+ readonly property bool _hovered: control.hovered &&
+ (sliderRectMouseArea.mouseX > x && sliderRectMouseArea.mouseX < x+width)
+
+ color: _currentChapter < 0 ? control.colors.accent : control.backgroundColor
+ width: sliderRect.width * seekpointsRect.endPosition - x - control._seekPointsDistance
+ x: sliderRect.width * seekpointsRect.startPosition
+
+ Rectangle {
+ id: progressRepRect
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+
+ width: sliderRect.width * control.visualPosition - parent.x - control._seekPointsDistance
+ visible: parent._currentChapter === 0
+ color: control.colors.accent
+ }
+ }
+
+ transitions: [
+ Transition {
+ to: "*"
+ SequentialAnimation{
+ PropertyAction { targets: control; property: "_currentChapterHovered" }
+ NumberAnimation {
+ targets: [seekpointsRect, progressRepRect]; properties: "height, y, radius"
+ duration: VLCStyle.duration_short; easing.type: Easing.InSine
+ }
+ }
+ }
+ ]
+
+ states:[
+ State {
+ name: "visible"
+ PropertyChanges {
+ target: control;
+ _currentChapterHovered: seekpointsRect._currentChapter === 0 ? false : control._currentChapterHovered
+ }
+ PropertyChanges { target: seekpointsRect; height: control.barHeight }
+ PropertyChanges { target: seekpointsRect; y: 0 }
+ PropertyChanges { target: seekpointsRect; radius: control._seekPointsRadius }
+ },
+ State {
+ name: "visibleLarge"
+ PropertyChanges {
+ target: control;
+ _currentChapterHovered: seekpointsRect._currentChapter === 0 ? true : control._currentChapterHovered
+ }
+ PropertyChanges { target: seekpointsRect; height: control._scaledBarHeight }
+ PropertyChanges { target: seekpointsRect; y: control._scaledY }
+ PropertyChanges { target: seekpointsRect; radius: control._scaledSeekPointsRadius }
+ }
+ ]
+
+ state: (seekpointsRect._hovered || (seekpointsRect._currentChapter === 0 && fsm._state == fsmHeld))
+ ? "visibleLarge"
+ : "visible"
+ }
+ }
+
Rectangle {
id: progressRect
width: control.visualPosition * parent.width
- height: control.barHeight
+ visible: !Player.hasChapters
color: control.colors.accent
- radius: control.barHeight
+ height: control.barHeight
+ radius: control._seekPointsRadius
}
Rectangle {
@@ -266,47 +371,14 @@ Slider {
}
}
}
-
- Item {
- id: seekpointsRow
-
- width: parent.width
- height: control.barHeight
- visible: Player.hasChapters
-
- Repeater {
- id: seekpointsRptr
- model: Player.chapters
- Rectangle {
- id: seekpointsRect
- property real position: model.position === undefined ? 0.0 : model.position
-
- color: control.colors.seekpoint
- width: VLCStyle.dp(1, VLCStyle.scale)
- height: control.barHeight
- x: sliderRect.width * seekpointsRect.position
- }
- }
-
- OpacityAnimator on opacity {
- from: 1
- to: 0
- running: !control._isSeekPointsShown
- }
- OpacityAnimator on opacity{
- from: 0
- to: 1
- running: control._isSeekPointsShown
- }
- }
}
handle: Rectangle {
id: sliderHandle
- visible: control.activeFocus
x: (control.visualPosition * control.availableWidth) - width / 2
- y: (control.barHeight - width) / 2
+ y: (control.barHeight - height) / 2
+
implicitWidth: VLCStyle.margin_small
implicitHeight: VLCStyle.margin_small
radius: VLCStyle.margin_small
@@ -318,12 +390,9 @@ Slider {
SequentialAnimation {
NumberAnimation {
target: sliderHandle; properties: "implicitWidth,implicitHeight"
-
to: 0
-
duration: VLCStyle.duration_short; easing.type: Easing.OutSine
}
-
PropertyAction { target: sliderHandle; property: "visible"; value: false; }
}
},
@@ -331,18 +400,28 @@ Slider {
to: "visible"
SequentialAnimation {
PropertyAction { target: sliderHandle; property: "visible"; value: true; }
-
NumberAnimation {
target: sliderHandle; properties: "implicitWidth,implicitHeight"
-
to: VLCStyle.margin_small
-
+ duration: VLCStyle.duration_short; easing.type: Easing.InSine
+ }
+ }
+ },
+ Transition {
+ to: "visibleLarge"
+ SequentialAnimation {
+ PropertyAction { target: sliderHandle; property: "visible"; value: true; }
+ NumberAnimation {
+ target: sliderHandle; properties: "implicitWidth,implicitHeight"
+ to: VLCStyle.margin_small * (0.75 * control._hoveredScalingFactor)
duration: VLCStyle.duration_short; easing.type: Easing.InSine
}
}
}
]
- state: (control.hovered || control.activeFocus) ? "visible" : "hidden"
+ state: (control.hovered || control.activeFocus)
+ ? ((control._currentChapterHovered || (Player.hasChapters && fsm._state == fsmHeld)) ? "visibleLarge" : "visible")
+ : "hidden"
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2395eb294e21703cb82a3a926b00cca6367de97c...ce53cd1eb7b78d0189abce3a98565697a93e6069
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2395eb294e21703cb82a3a926b00cca6367de97c...ce53cd1eb7b78d0189abce3a98565697a93e6069
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list