RibbonUI/lib_source/qml/Qt6/RibbonPageIndicator.qml

160 lines
6.6 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import RibbonUI
PageIndicator {
id: control
property real paginationHeight: 12
property real paginationWidth: 12
property int headCount: 4
property int tailCount: 4
property int previewWindow: 2
property bool showPagination: true
property bool startWithZero: false
property bool modernStyle: RibbonTheme.modernStyle
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
padding: 6
spacing: 6
delegate: Rectangle {
id: item
implicitWidth: showPagination ? Math.max(pagination_text.contentWidth + padding * 2, paginationWidth,
pagination_text.contentHeight + padding * 3 / 4, paginationHeight) : paginationWidth
implicitHeight: showPagination ? previous_btn.height : paginationHeight
radius: showPagination ? modernStyle ? Math.min(width, height) * 0.22 : Math.min(width, height) * 0.15 : Math.min(width, height) / 2
color: {
if(!mouse.containsMouse)
return RibbonTheme.isDarkMode ? "#2F2F2F" : "white"
let alpha = (mouse.containsPress ? 0.55 : mouse.containsMouse ? 0.75 : (modelData ? modelData : index) === control.currentIndex ? 0.95 : 0.45) - (showPagination ? 0.65 : 0)
return RibbonTheme.isDarkMode ? Qt.rgba(255,255,255,alpha) : Qt.rgba(0,0,0,alpha)
}
border.width: (modelData ? modelData : index) === control.currentIndex ? 2 : 1
border.color: RibbonTheme.isDarkMode ? "#5C5D5D" : "#B5B4B5"
scale: {
if(showPagination)
return 1
let minimumScale = 0.5
let ave = 0
if(mouse.containsMouse)
return 1.1
else if((modelData ? modelData : index) === control.currentIndex)
return 1
else{
if(index < control.currentIndex){
ave = (1 - minimumScale) / control.currentIndex
}
else if(index > control.currentIndex){
ave = (1 - minimumScale) / (control.count - control.currentIndex - 1)
}
return 1 - ave * Math.abs(index - control.currentIndex)
}
}
required property int index
required property int modelData
RibbonText{
id: pagination_text
viewOnly: true
visible: showPagination
anchors.centerIn: parent
text: startWithZero ? modelData ? modelData : index : (modelData ? modelData : index) + 1
font.bold: (modelData ? modelData : index) === control.currentIndex
}
Behavior on opacity { OpacityAnimator { duration: 100 } }
MouseArea{
id: mouse
anchors.fill: parent
hoverEnabled: true
onClicked: control.currentIndex = modelData ? modelData : index
}
}
contentItem: RowLayout {
id: row
spacing: control.spacing
property int head: headCount
property int middle: Math.max(head,tail)
property int tail: tailCount
RibbonButton{
id: previous_btn
text: qsTr("Previous")
iconSource: RibbonIcons.Previous
onClicked: control.currentIndex--
enabled: control.currentIndex !== 0
visible: showPagination
}
Repeater {
id: head_repeater
model: showPagination ? ((control.currentIndex + 1 > row.head - control.previewWindow) && (control.count > row.head + row.tail) ? control.previewWindow : control.count > row.head ? row.head : control.count ) : control.count
delegate: control.delegate
}
RibbonText{
viewOnly: true
visible: showPagination && control.currentIndex > row.head - control.previewWindow && (control.count > row.head + row.tail)
text: "...."
font.bold: true
}
Repeater {
id: mid_repeater
property int begin: (control.currentIndex - Math.floor((row.middle - control.previewWindow)/2)) + row.middle > control.count - 1 ? end - row.middle + 1: (control.currentIndex - Math.floor((row.middle - control.previewWindow)/2)) < row.head ? control.currentIndex : (control.currentIndex - Math.floor((row.middle - control.previewWindow)/2))
property int end: control.count - 1 - control.currentIndex < row.middle ? control.count - 1 : control.currentIndex + row.middle - Math.ceil((row.middle - control.previewWindow)/2)
model: {
let list = []
if(showPagination && (control.currentIndex + 1 > row.head - control.previewWindow) && (control.count > (control.previewWindow * 2 + row.middle)) && row.head + row.tail < control.count){
for(let i = begin; i <= end; i++){
list.push(i)
}
}
return list
}
delegate: control.delegate
}
RibbonText{
viewOnly: true
visible: showPagination && (control.currentIndex + 1 < control.count - 1 - row.tail) && (control.count > (control.previewWindow * 2 + row.middle)) && head_repeater.model + tail_repeater.model.length < control.count
text: "...."
font.bold: true
}
Repeater {
id: tail_repeater
model: {
let list = [], begin = mid_repeater.model.length ? control.count - 1 - mid_repeater.end < control.previewWindow ? mid_repeater.end + 1 : control.count - control.previewWindow : control.count < row.head + row.tail ? row.head : control.count - row.tail
if(showPagination && ((control.count >= row.head + row.tail) && (control.currentIndex < control.count - row.tail) || !mid_repeater.model.length)){
for(let i = begin; i < control.count; i++){
list.push(i)
}
}
return list
}
delegate: control.delegate
}
RibbonButton{
id: next_btn
text: qsTr("Next")
iconSource: RibbonIcons.Next
onClicked: control.currentIndex++
enabled: control.currentIndex !== control.count - 1
visible: showPagination
}
}
}