Files
2019-09-15 10:34:34 +08:00

290 lines
7.0 KiB
QML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import QtQuick 2.6
import Toou2D 1.0
/* 滚动条-竖向
滚动条可配合 Qt ListView ,Qt Flickable ,等等使用。
TScrllbarV{
target:listView;
}
*/
/*! TODO */
Item {
id:toou2d_scrollbarv;
width: 22;
property Flickable target: parent;
//0 - 1
property double yPosition: 0;
//小方块
property alias thumb: mgadgetthumb;
//轨道
property alias track: mgadgettrack;
//可变小 ,true 启动状态为 narrowed false 启动状态为 full
property bool narrowed: true;
property bool autoHide: false;
//Too small a height affects drag accuracy
property int thumbMinHieght: 30;
property int stateDuration: 1000;
property Component thumbComponent;
property Component trackComponent;
state: narrowed ? "narrowed" : "full";
TGadgetBackground{
id:mgadgettrack;
onWidthChanged: console.error("Width Invalid setting...");
onHeightChanged: console.error("Height Invalid setting...");
}
Loader{
id:track;
anchors.right: parent.right;
sourceComponent: trackComponent;
height: parent.height;
visible: mgadgettrack.visible;
}
Loader{
id:thumb
anchors.horizontalCenter: track.horizontalCenter;
sourceComponent: thumbComponent;
visible: mgadgetthumb.visible;
height: thumbMinHieght;
}
//这些可以不用要了
TGadgetBackground{
id:mgadgetthumb;
onWidthChanged: console.error("Width Invalid setting...");
onHeightChanged: console.error("Height Invalid setting...");
}
MouseArea{
id:mouseArea
property bool ishold: false;
property bool isdrag: false;
property double offset: 0;
//anchors.fill: parent;
width: parent.width;
height: parent.height;
hoverEnabled: true;
onWheel: {
}
onPressed: {
ishold = true;
if(mouseY > thumb.y && mouseY < thumb.height + thumb.y){
offset = mouseY - thumb.y;
isdrag = true;
}else{
mprivate.setValue(mouseY - thumb.height / 2)
}
}
onReleased: {
ishold = false;
isdrag = false;
if(!containsMouse){
stateTimer.rStart();
}
}
onEntered: {
toou2d_scrollbarv.state = "full";
stateTimer.stop();
}
onExited: {
if(!ishold)stateTimer.rStart();
}
onMouseYChanged: {
if(ishold && isdrag){
mprivate.setValue(mouseY - offset)
}
}
Component.onCompleted: {
mprivate.checkVisible();
}
onIsholdChanged: target.interactive = !ishold;
}
onYPositionChanged: {
if(mouseArea.ishold){//drag interior setting
target.contentY = (target.contentHeight - target.height) * yPosition;
}
}
Connections{
target: toou2d_scrollbarv.target;
onContentYChanged:{
if(!mouseArea.ishold){
var t = toou2d_scrollbarv.target;
var p = t.contentY / (t.contentHeight - t.height);
mprivate.setValue(p * (height - thumb.height))
}
mprivate.restoreVisibleState();
}
onContentHeightChanged:{
var t = toou2d_scrollbarv.target;
var nh = t.height / t.contentHeight * toou2d_scrollbarv.height;
if(nh > thumbMinHieght){
thumb.height = nh;
}
mprivate.checkVisible();
}
onHeightChanged:mprivate.checkVisible();
}
TObject{
id:mprivate;
function setValue(v){
if(v < 0){
thumb.y = 0;
}else if(v + thumb.height > height){
thumb.y = height - thumb.height;
}else{
thumb.y = v;
}
yPosition = thumb.y / (height - thumb.height);
}
function checkVisible(){
var t = toou2d_scrollbarv.target;
if(t){
toou2d_scrollbarv.visible = t.contentHeight > t.height;
toou2d_scrollbarv.enabled = toou2d_scrollbarv.visible;
}
}
function restoreVisibleState(){
if(!mouseArea.containsMouse && !mouseArea.ishold && !stateTimer.running){
if(toou2d_scrollbarv.narrowed){
toou2d_scrollbarv.state = "narrowed";
}else{
toou2d_scrollbarv.state = "full";
}
stateTimer.rStart();
}
}
}
trackComponent: TRectangle{
id:mt
theme.enabled: false;
state: toou2d_scrollbarv.state;
color: "#E5E5E5"
opacity: 0.1
states: [
State {
name: "full"
PropertyChanges {
target: mt
color:"#5d5d5d"
width: 15;
}
},
State {
name: "narrowed"
PropertyChanges {
target: mt
width:5;
visible:false;
}
},
State {
name: "hide"
PropertyChanges {
target: mt
visible:false;
}
}
]
}
thumbComponent: TRectangle{
id:mth
theme.enabled: false;
state: toou2d_scrollbarv.state;
radius: width / 2;
color: "#B2B2B2"
states: [
State {
name: "full"
PropertyChanges {
target: mth
width:8;
}
},
State {
name: "narrowed"
PropertyChanges {
target: mth
width:3;
}
},
State {
name: "hide"
PropertyChanges {
target: mth
visible:false;
}
}
]
}
Timer{
id:stateTimer;
property bool isrun: narrowed || autoHide
interval: stateDuration; running: isrun ; repeat : true;
onTriggered:{
if(toou2d_scrollbarv.state === "full"){
if(toou2d_scrollbarv.narrowed){
toou2d_scrollbarv.state = "narrowed";
}
else if(toou2d_scrollbarv.autoHide){
toou2d_scrollbarv.state = "hide";
}
}
else if(toou2d_scrollbarv.state === "narrowed"){
if(toou2d_scrollbarv.autoHide){
toou2d_scrollbarv.state = "hide";
}
}
if(toou2d_scrollbarv.state === "hide"){
stop();
}
}
function rStart(){
if(isrun)restart();
}
}
}