update
@ -46,13 +46,13 @@ endif()
|
||||
#国际化
|
||||
find_program(QT_LUPDATE NAMES lupdate)
|
||||
find_program(QT_LRELEASE NAMES lrelease)
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}_en_US.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts ${PROJECT_NAME}_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} ${PROJECT_NAME}_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/FluentUI_en_US.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts FluentUI_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} FluentUI_en_US.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif ()
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/${PROJECT_NAME}_zh_CN.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts ${PROJECT_NAME}_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} ${PROJECT_NAME}_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
if (NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/FluentUI_zh_CN.qm)
|
||||
execute_process(COMMAND ${QT_LUPDATE} ${CMAKE_CURRENT_LIST_DIR} -ts FluentUI_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
execute_process(COMMAND ${QT_LRELEASE} FluentUI_zh_CN.ts WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif ()
|
||||
|
||||
file(GLOB QM_FILE_PATHS ${CMAKE_CURRENT_LIST_DIR}/ *.qm)
|
||||
|
@ -24,7 +24,7 @@ void FluApp::init(QObject *target,QLocale locale){
|
||||
qApp->installTranslator(_translator);
|
||||
const QStringList uiLanguages = _locale.uiLanguages();
|
||||
for (const QString &name : uiLanguages) {
|
||||
const QString baseName = "fluentuiplugin_" + QLocale(name).name();
|
||||
const QString baseName = "FluentUI_" + QLocale(name).name();
|
||||
if (_translator->load(":/qt/qml/FluentUI/i18n/"+ baseName)) {
|
||||
_engine->retranslate();
|
||||
break;
|
||||
@ -63,7 +63,7 @@ void FluApp::navigate(const QString& route,const QJsonObject& argument,FluWindow
|
||||
if(win){
|
||||
int launchMode = win->property("launchMode").toInt();
|
||||
if(launchMode == 1){
|
||||
win->setProperty("argument",argument);
|
||||
win->setProperty("",argument);
|
||||
win->show();
|
||||
win->raise();
|
||||
win->requestActivate();
|
||||
|
@ -1,41 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
id: control
|
||||
property color tintColor: Qt.rgba(1, 1, 1, 1)
|
||||
property real tintOpacity: 0.65
|
||||
property real luminosity: 0.01
|
||||
property real noiseOpacity: 0.02
|
||||
property alias target: effect_source.sourceItem
|
||||
property int blurRadius: 32
|
||||
property rect targetRect: Qt.rect(control.x, control.y, control.width,
|
||||
control.height)
|
||||
ShaderEffectSource {
|
||||
id: effect_source
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
sourceRect: control.targetRect
|
||||
}
|
||||
FastBlur {
|
||||
id: fast_blur
|
||||
anchors.fill: parent
|
||||
source: effect_source
|
||||
radius: control.blurRadius
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(1, 1, 1, luminosity)
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(tintColor.r, tintColor.g, tintColor.b, tintOpacity)
|
||||
}
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: "../Image/noise.png"
|
||||
fillMode: Image.Tile
|
||||
opacity: control.noiseOpacity
|
||||
}
|
||||
}
|
@ -1,347 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Rectangle{
|
||||
property string title: ""
|
||||
property string darkText : qsTr("Dark")
|
||||
property string lightText : qsTr("Light")
|
||||
property string minimizeText : qsTr("Minimize")
|
||||
property string restoreText : qsTr("Restore")
|
||||
property string maximizeText : qsTr("Maximize")
|
||||
property string closeText : qsTr("Close")
|
||||
property string stayTopText : qsTr("Sticky on Top")
|
||||
property string stayTopCancelText : qsTr("Sticky on Top cancelled")
|
||||
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
|
||||
property color minimizeNormalColor: FluTheme.itemNormalColor
|
||||
property color minimizeHoverColor: FluTheme.itemHoverColor
|
||||
property color minimizePressColor: FluTheme.itemPressColor
|
||||
property color maximizeNormalColor: FluTheme.itemNormalColor
|
||||
property color maximizeHoverColor: FluTheme.itemHoverColor
|
||||
property color maximizePressColor: FluTheme.itemPressColor
|
||||
property color closeNormalColor: Qt.rgba(0,0,0,0)
|
||||
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
|
||||
property color closePressColor: Qt.rgba(251/255,115/255,115/255,0.8)
|
||||
property bool showDark: false
|
||||
property bool showClose: true
|
||||
property bool showMinimize: true
|
||||
property bool showMaximize: true
|
||||
property bool showStayTop: true
|
||||
property bool titleVisible: true
|
||||
property url icon
|
||||
property int iconSize: 20
|
||||
property bool isMac: FluTools.isMacos()
|
||||
property color borerlessColor : FluTheme.primaryColor
|
||||
property bool systemMoveEnable: true
|
||||
property var maxClickListener : function(){
|
||||
if(FluTools.isMacos()){
|
||||
if (d.win.visibility === Window.FullScreen)
|
||||
d.win.showNormal()
|
||||
else
|
||||
d.win.showFullScreen()
|
||||
}else{
|
||||
if (d.win.visibility === Window.Maximized)
|
||||
d.win.showNormal()
|
||||
else
|
||||
d.win.showMaximized()
|
||||
d.hoverMaxBtn = false
|
||||
}
|
||||
}
|
||||
property var minClickListener: function(){
|
||||
if(d.win.transientParent != null){
|
||||
d.win.transientParent.showMinimized()
|
||||
}else{
|
||||
d.win.showMinimized()
|
||||
}
|
||||
}
|
||||
property var closeClickListener : function(){
|
||||
d.win.close()
|
||||
}
|
||||
property var stayTopClickListener: function(){
|
||||
if(d.win instanceof FluWindow){
|
||||
d.win.stayTop = !d.win.stayTop
|
||||
}
|
||||
}
|
||||
property var darkClickListener: function(){
|
||||
if(FluTheme.dark){
|
||||
FluTheme.darkMode = FluThemeType.Light
|
||||
}else{
|
||||
FluTheme.darkMode = FluThemeType.Dark
|
||||
}
|
||||
}
|
||||
property var systemMenuListener: function(){
|
||||
if(d.win instanceof FluWindow){
|
||||
d.win.showSystemMenu()
|
||||
}
|
||||
}
|
||||
property alias buttonStayTop: btn_stay_top
|
||||
property alias buttonMinimize: btn_minimize
|
||||
property alias buttonMaximize: btn_maximize
|
||||
property alias buttonClose: btn_close
|
||||
property alias buttonDark: btn_dark
|
||||
id:control
|
||||
color: Qt.rgba(0,0,0,0)
|
||||
height: visible ? 30 : 0
|
||||
opacity: visible
|
||||
z: 65535
|
||||
Item{
|
||||
id:d
|
||||
property var hitTestList: []
|
||||
property bool hoverMaxBtn: false
|
||||
property var win: Window.window
|
||||
property bool stayTop: {
|
||||
if(d.win instanceof FluWindow){
|
||||
return d.win.stayTop
|
||||
}
|
||||
return false
|
||||
}
|
||||
property bool isRestore: win && Window.Maximized === win.visibility
|
||||
property bool resizable: win && !(win.height === win.maximumHeight && win.height === win.minimumHeight && win.width === win.maximumWidth && win.width === win.minimumWidth)
|
||||
function containsPointToItem(point,item){
|
||||
var pos = item.mapToGlobal(0,0)
|
||||
var rect = Qt.rect(pos.x,pos.y,item.width,item.height)
|
||||
if(point.x>rect.x && point.x<(rect.x+rect.width) && point.y>rect.y && point.y<(rect.y+rect.height)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_app_bar
|
||||
anchors.fill: parent
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable){
|
||||
d.win.startSystemMove()
|
||||
}
|
||||
}
|
||||
onDoubleClicked:
|
||||
(mouse)=>{
|
||||
if(systemMoveEnable && d.resizable && Qt.LeftButton){
|
||||
btn_maximize.clicked()
|
||||
}
|
||||
}
|
||||
acceptedButtons: Qt.LeftButton|Qt.RightButton
|
||||
onClicked:
|
||||
(mouse)=>{
|
||||
if (systemMoveEnable && mouse.button === Qt.RightButton){
|
||||
control.systemMenuListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: isMac ? undefined : parent.left
|
||||
leftMargin: isMac ? undefined : 10
|
||||
horizontalCenter: isMac ? parent.horizontalCenter : undefined
|
||||
}
|
||||
spacing: 10
|
||||
Image{
|
||||
width: control.iconSize
|
||||
height: control.iconSize
|
||||
visible: status === Image.Ready ? true : false
|
||||
source: control.icon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
FluText {
|
||||
text: title
|
||||
visible: control.titleVisible
|
||||
color:control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_mac_buttons
|
||||
RowLayout{
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
Layout.preferredWidth: 12
|
||||
normalImage: "../Image/btn_close_normal.png"
|
||||
hoveredImage: "../Image/btn_close_hovered.png"
|
||||
pushedImage: "../Image/btn_close_pushed.png"
|
||||
visible: showClose
|
||||
onClicked: closeClickListener()
|
||||
}
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
Layout.preferredWidth: 12
|
||||
normalImage: "../Image/btn_min_normal.png"
|
||||
hoveredImage: "../Image/btn_min_hovered.png"
|
||||
pushedImage: "../Image/btn_min_pushed.png"
|
||||
onClicked: minClickListener()
|
||||
visible: showMinimize
|
||||
}
|
||||
FluImageButton{
|
||||
Layout.preferredHeight: 12
|
||||
Layout.preferredWidth: 12
|
||||
normalImage: "../Image/btn_max_normal.png"
|
||||
hoveredImage: "../Image/btn_max_hovered.png"
|
||||
pushedImage: "../Image/btn_max_pushed.png"
|
||||
onClicked: maxClickListener()
|
||||
visible: d.resizable && showMaximize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
sourceComponent: isMac ? com_mac_buttons : undefined
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
id:layout_row
|
||||
anchors.right: parent.right
|
||||
height: control.height
|
||||
spacing: 0
|
||||
Component.onCompleted: {
|
||||
setHitTestVisible(layout_row)
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_dark
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
rightPadding: 2
|
||||
iconSource: FluTheme.dark ? FluentIcons.Brightness : FluentIcons.QuietHours
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 15
|
||||
visible: showDark
|
||||
text: FluTheme.dark ? control.lightText : control.darkText
|
||||
radius: 0
|
||||
iconColor:control.textColor
|
||||
onClicked:()=> darkClickListener(btn_dark)
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_stay_top
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : FluentIcons.Pinned
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 14
|
||||
visible: {
|
||||
if(!(d.win instanceof FluWindow)){
|
||||
return false
|
||||
}
|
||||
return showStayTop
|
||||
}
|
||||
text:d.stayTop ? control.stayTopCancelText : control.stayTopText
|
||||
radius: 0
|
||||
iconColor: d.stayTop ? FluTheme.primaryColor : control.textColor
|
||||
onClicked: stayTopClickListener()
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_minimize
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : FluentIcons.ChromeMinimize
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconSize: 11
|
||||
text:minimizeText
|
||||
radius: 0
|
||||
visible: !isMac && showMinimize
|
||||
iconColor: control.textColor
|
||||
color: {
|
||||
if(pressed){
|
||||
return minimizePressColor
|
||||
}
|
||||
return hovered ? minimizeHoverColor : minimizeNormalColor
|
||||
}
|
||||
onClicked: minClickListener()
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_maximize
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
|
||||
color: {
|
||||
if(down){
|
||||
return maximizePressColor
|
||||
}
|
||||
if(FluTools.isWindows11OrGreater()){
|
||||
return d.hoverMaxBtn ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
return hovered ? maximizeHoverColor : maximizeNormalColor
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: d.resizable && !isMac && showMaximize
|
||||
radius: 0
|
||||
iconColor: control.textColor
|
||||
text:d.isRestore?restoreText:maximizeText
|
||||
iconSize: 11
|
||||
onClicked: maxClickListener()
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_close
|
||||
Layout.preferredWidth: 40
|
||||
Layout.preferredHeight: 30
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSource : FluentIcons.ChromeClose
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text:closeText
|
||||
visible: !isMac && showClose
|
||||
radius: 0
|
||||
iconSize: 10
|
||||
iconColor: hovered ? Qt.rgba(1,1,1,1) : control.textColor
|
||||
color:{
|
||||
if(pressed){
|
||||
return closePressColor
|
||||
}
|
||||
return hovered ? closeHoverColor : closeNormalColor
|
||||
}
|
||||
onClicked: closeClickListener()
|
||||
}
|
||||
}
|
||||
function _maximizeButtonHover(){
|
||||
var hover = false
|
||||
if(btn_maximize.visible && FluTools.isWindows11OrGreater() && d.resizable){
|
||||
if(d.containsPointToItem(FluTools.cursorPos(),btn_maximize)){
|
||||
hover = true
|
||||
}else{
|
||||
if(btn_maximize.down){
|
||||
btn_maximize.down = false
|
||||
}
|
||||
}
|
||||
}
|
||||
d.hoverMaxBtn = hover
|
||||
return hover;
|
||||
}
|
||||
function _appBarHover(){
|
||||
var cursorPos = FluTools.cursorPos()
|
||||
for(var i =0 ;i< d.hitTestList.length; i++){
|
||||
var item = d.hitTestList[i]
|
||||
if(item.visible){
|
||||
if(d.containsPointToItem(cursorPos,item)){
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d.containsPointToItem(cursorPos,control)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
function setHitTestVisible(id){
|
||||
d.hitTestList.push(id)
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
default property alias contentData : layout_content.data
|
||||
property int paddings : 0
|
||||
property int leftPadding : 0
|
||||
property int rightPadding : 0
|
||||
property int topPadding : 0
|
||||
property int bottomPadding : 0
|
||||
id:control
|
||||
radius: 4
|
||||
color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
implicitHeight: height
|
||||
implicitWidth: width
|
||||
Item {
|
||||
id: layout_content
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Math.max(paddings,leftPadding)
|
||||
anchors.rightMargin: Math.max(paddings,rightPadding)
|
||||
anchors.topMargin: Math.max(paddings,topPadding)
|
||||
anchors.bottomMargin: Math.max(paddings,bottomPadding)
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluTextBox{
|
||||
property var items:[]
|
||||
property string emptyText: qsTr("No results found")
|
||||
property int autoSuggestBoxReplacement: FluentIcons.Search
|
||||
property var filter: function(item){
|
||||
if(item.title.indexOf(control.text)!==-1){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
signal itemClicked(var data)
|
||||
id:control
|
||||
Component.onCompleted: {
|
||||
d.loadData()
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property bool flagVisible: true
|
||||
property var window : Window.window
|
||||
function handleClick(modelData){
|
||||
control_popup.visible = false
|
||||
control.itemClicked(modelData)
|
||||
d.updateText(modelData.title)
|
||||
}
|
||||
function updateText(text){
|
||||
d.flagVisible = false
|
||||
control.text = text
|
||||
d.flagVisible = true
|
||||
}
|
||||
function loadData(){
|
||||
var result = []
|
||||
if(items==null){
|
||||
list_view.model = result
|
||||
return
|
||||
}
|
||||
items.map(function(item){
|
||||
if(control.filter(item)){
|
||||
result.push(item)
|
||||
}
|
||||
})
|
||||
list_view.model = result
|
||||
}
|
||||
}
|
||||
onActiveFocusChanged: {
|
||||
if(!activeFocus){
|
||||
control_popup.visible = false
|
||||
}
|
||||
}
|
||||
Popup{
|
||||
id:control_popup
|
||||
y:control.height
|
||||
focus: false
|
||||
padding: 0
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
contentItem: FluRectangle{
|
||||
radius: [4,4,4,4]
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
header: Item{
|
||||
width: control.width
|
||||
height: visible ? 38 : 0
|
||||
visible: list_view.count === 0
|
||||
FluText{
|
||||
text:emptyText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate:FluControl{
|
||||
id:item_control
|
||||
height: 38
|
||||
width: control.width
|
||||
onClicked:{
|
||||
d.handleClick(modelData)
|
||||
}
|
||||
background: Rectangle{
|
||||
FluFocusRectangle{
|
||||
visible: item_control.activeFocus
|
||||
radius:4
|
||||
}
|
||||
color: {
|
||||
if(hovered){
|
||||
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
}
|
||||
contentItem: FluText{
|
||||
text:modelData.title
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
verticalAlignment : Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Item{
|
||||
id:container
|
||||
implicitWidth: control.width
|
||||
implicitHeight: 38*Math.min(Math.max(list_view.count,1),8)
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
d.loadData()
|
||||
if(d.flagVisible){
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.implicitHeight){
|
||||
control_popup.y = control.height
|
||||
} else if(pos.y>container.implicitHeight){
|
||||
control_popup.y = -container.implicitHeight
|
||||
} else {
|
||||
control_popup.y = d.window.height-(pos.y+container.implicitHeight)
|
||||
}
|
||||
control_popup.visible = true
|
||||
}
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Rectangle{
|
||||
property bool isDot: false
|
||||
property bool showZero: false
|
||||
property int count: 0
|
||||
property bool topRight: false
|
||||
id:control
|
||||
color:Qt.rgba(255/255,77/255,79/255,1)
|
||||
width: {
|
||||
if(isDot)
|
||||
return 10
|
||||
if(count<10){
|
||||
return 20
|
||||
}else if(count<100){
|
||||
return 30
|
||||
}
|
||||
return 40
|
||||
}
|
||||
height: {
|
||||
if(isDot)
|
||||
return 10
|
||||
return 20
|
||||
}
|
||||
radius: {
|
||||
if(isDot)
|
||||
return 5
|
||||
return 10
|
||||
}
|
||||
border.width: 1
|
||||
border.color: Qt.rgba(1,1,1,1)
|
||||
anchors{
|
||||
right: {
|
||||
if(parent && topRight)
|
||||
return parent.right
|
||||
return undefined
|
||||
}
|
||||
top: {
|
||||
if(parent && topRight)
|
||||
return parent.top
|
||||
return undefined
|
||||
}
|
||||
rightMargin: {
|
||||
if(parent && topRight){
|
||||
if(isDot){
|
||||
return -2.5
|
||||
}
|
||||
return -(control.width/2)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
topMargin: {
|
||||
if(parent && topRight){
|
||||
if(isDot){
|
||||
return -2.5
|
||||
}
|
||||
return -10
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
visible: {
|
||||
if(showZero)
|
||||
return true
|
||||
return count!==0
|
||||
}
|
||||
FluText{
|
||||
anchors.centerIn: parent
|
||||
color: Qt.rgba(1,1,1,1)
|
||||
visible: !isDot
|
||||
text:{
|
||||
if(count<100)
|
||||
return count
|
||||
return count+"+"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int textSize: 15
|
||||
property string separator: "/"
|
||||
property var items: []
|
||||
property int spacing: 5
|
||||
signal clickItem(var model)
|
||||
id:control
|
||||
implicitWidth: 300
|
||||
height: 30
|
||||
onItemsChanged: {
|
||||
list_model.clear()
|
||||
list_model.append(items)
|
||||
}
|
||||
ListModel{
|
||||
id:list_model
|
||||
}
|
||||
ListView{
|
||||
id:list_view
|
||||
width: parent.width
|
||||
height: 30
|
||||
orientation: ListView.Horizontal
|
||||
model: list_model
|
||||
clip: true
|
||||
spacing : control.spacing
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
remove: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: FluTheme.enableAnimation ? 83 : 1
|
||||
}
|
||||
}
|
||||
add: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: FluTheme.enableAnimation ? 83 : 1
|
||||
}
|
||||
}
|
||||
delegate: Item{
|
||||
height: item_layout.height
|
||||
width: item_layout.width
|
||||
RowLayout{
|
||||
id:item_layout
|
||||
spacing: list_view.spacing
|
||||
height: list_view.height
|
||||
|
||||
FluText{
|
||||
text:model.title
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: {
|
||||
if(item_mouse.pressed){
|
||||
return FluTheme.dark ? Qt.rgba(150/255,150/255,150/235,1) : Qt.rgba(134/255,134/255,134/235,1)
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return FluTheme.dark ? Qt.rgba(204/255,204/255,204/235,1) : Qt.rgba(92/255,92/255,92/235,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/235,1) : Qt.rgba(26/255,26/255,26/235,1)
|
||||
}
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
control.clickItem(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluText{
|
||||
text:control.separator
|
||||
font.pixelSize: control.textSize
|
||||
visible: list_view.count-1 !== index
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function remove(index,count){
|
||||
list_model.remove(index,count)
|
||||
}
|
||||
function count(){
|
||||
return list_model.count
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(246/255,246/255,246/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id: control
|
||||
enabled: !disabled
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
font:FluTextStyle.Body
|
||||
focusPolicy:Qt.TabFocus
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
radius: 4
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:4
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
}
|
||||
}
|
@ -1,661 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property string text: qsTr("Pick a date")
|
||||
property date from: new Date(1924, 0, 1)
|
||||
property date to: new Date(2124, 11, 31)
|
||||
property var current
|
||||
signal accepted()
|
||||
id:control
|
||||
color: {
|
||||
if(mouse_area.containsMouse){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
height: 30
|
||||
width: 120
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: dividerColor
|
||||
MouseArea{
|
||||
id:mouse_area
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
popup.showPopup()
|
||||
}
|
||||
}
|
||||
CalendarModel {
|
||||
id:calender_model
|
||||
from: control.from
|
||||
to: control.to
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property var window : Window.window
|
||||
property date displayDate: {
|
||||
if(control.current){
|
||||
return control.current
|
||||
}
|
||||
return new Date()
|
||||
}
|
||||
property date toDay : new Date()
|
||||
property int pageIndex: 0
|
||||
signal nextButton
|
||||
signal previousButton
|
||||
property point yearRing : Qt.point(0,0)
|
||||
}
|
||||
FluText{
|
||||
id:text_date
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
rightMargin: 30
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:{
|
||||
if(control.current){
|
||||
return control.current.toLocaleDateString(FluApp.locale,"yyyy/M/d")
|
||||
}
|
||||
return control.text
|
||||
}
|
||||
}
|
||||
FluIcon{
|
||||
iconSource: FluentIcons.Calendar
|
||||
iconSize: 14
|
||||
iconColor: text_date.color
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 12
|
||||
}
|
||||
}
|
||||
Menu{
|
||||
id:popup
|
||||
height: container.height
|
||||
width: container.width
|
||||
modal: true
|
||||
Overlay.modal: Item {}
|
||||
enter: Transition {
|
||||
reversible: true
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
clip: true
|
||||
FluArea{
|
||||
id:container
|
||||
width: 300
|
||||
height: 360
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 50
|
||||
RowLayout{
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.leftMargin: parent.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluTextButton{
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
contentItem: FluText {
|
||||
text: d.displayDate.toLocaleString(FluApp.locale, "MMMM yyyy")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
visible: d.pageIndex === 0
|
||||
onClicked: {
|
||||
d.pageIndex = 1
|
||||
}
|
||||
}
|
||||
FluTextButton{
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
contentItem: FluText {
|
||||
text: d.displayDate.toLocaleString(FluApp.locale, "yyyy")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
visible: d.pageIndex === 1
|
||||
onClicked: {
|
||||
d.pageIndex = 2
|
||||
}
|
||||
}
|
||||
FluTextButton{
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
contentItem: FluText {
|
||||
text: "%1-%2".arg(d.yearRing.x).arg(d.yearRing.y)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
textColor: FluTheme.fontTertiaryColor
|
||||
}
|
||||
visible: d.pageIndex === 2
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:icon_up
|
||||
iconSource: FluentIcons.CaretUpSolid8
|
||||
iconSize: 10
|
||||
onClicked: {
|
||||
d.previousButton()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:icon_down
|
||||
iconSource: FluentIcons.CaretDownSolid8
|
||||
iconSize: 10
|
||||
Layout.rightMargin: parent.spacing
|
||||
onClicked: {
|
||||
d.nextButton()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluDivider{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
StackView{
|
||||
id:stack_view
|
||||
anchors.fill: parent
|
||||
initialItem: com_page_one
|
||||
replaceEnter : Transition{
|
||||
OpacityAnimator{
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 88
|
||||
}
|
||||
ScaleAnimator{
|
||||
from: 0.5
|
||||
to: 1
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
replaceExit : Transition{
|
||||
OpacityAnimator{
|
||||
from: 1
|
||||
to: 0
|
||||
duration: 88
|
||||
}
|
||||
ScaleAnimator{
|
||||
from: 1.0
|
||||
to: 0.5
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onPageIndexChanged(){
|
||||
if(d.pageIndex === 0){
|
||||
stack_view.replace(com_page_one)
|
||||
}
|
||||
if(d.pageIndex === 1){
|
||||
stack_view.replace(com_page_two)
|
||||
}
|
||||
if(d.pageIndex === 2){
|
||||
stack_view.replace(com_page_three)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_page_three
|
||||
GridView{
|
||||
id:grid_view
|
||||
cellHeight: 75
|
||||
cellWidth: 75
|
||||
clip: true
|
||||
boundsBehavior: GridView.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model: {
|
||||
var fromYear = calender_model.from.getFullYear()
|
||||
var toYear = calender_model.to.getFullYear()
|
||||
return toYear-fromYear+1
|
||||
}
|
||||
highlightRangeMode: GridView.StrictlyEnforceRange
|
||||
onCurrentIndexChanged:{
|
||||
var year = currentIndex + calender_model.from.getFullYear()
|
||||
var start = Math.ceil(year / 10) * 10
|
||||
var end = start+10
|
||||
d.yearRing = Qt.point(start,end)
|
||||
}
|
||||
highlightMoveDuration: 100
|
||||
Component.onCompleted: {
|
||||
grid_view.highlightMoveDuration = 0
|
||||
currentIndex = d.displayDate.getFullYear()-calender_model.from.getFullYear()
|
||||
timer_delay.restart()
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onNextButton(){
|
||||
grid_view.currentIndex = Math.min(grid_view.currentIndex+16,grid_view.count-1)
|
||||
}
|
||||
function onPreviousButton(){
|
||||
grid_view.currentIndex = Math.max(grid_view.currentIndex-16,0)
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 100
|
||||
onTriggered: {
|
||||
grid_view.highlightMoveDuration = 100
|
||||
}
|
||||
}
|
||||
currentIndex: -1
|
||||
delegate: Item{
|
||||
property int year : calender_model.from.getFullYear()+modelData
|
||||
property bool toYear: year === d.toDay.getFullYear()
|
||||
implicitHeight: 75
|
||||
implicitWidth: 75
|
||||
FluControl{
|
||||
id:control_delegate
|
||||
width: 60
|
||||
height: 60
|
||||
anchors.centerIn: parent
|
||||
Rectangle{
|
||||
width: 48
|
||||
height: 48
|
||||
radius: width/2
|
||||
color: {
|
||||
if(toYear){
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2)
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1)
|
||||
}
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluColors.Transparent
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
FluText{
|
||||
text: year
|
||||
anchors.centerIn: parent
|
||||
opacity: {
|
||||
if(year >= d.yearRing.x && year <= d.yearRing.y){
|
||||
return 1
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return 1
|
||||
}
|
||||
return 0.3
|
||||
}
|
||||
color: {
|
||||
if(toYear){
|
||||
return FluColors.White
|
||||
}
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
d.displayDate = new Date(year,0,1)
|
||||
d.pageIndex = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_page_two
|
||||
|
||||
ListView{
|
||||
id:listview
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
spacing: 0
|
||||
highlightMoveDuration: 100
|
||||
model: {
|
||||
var fromYear = calender_model.from.getFullYear()
|
||||
var toYear = calender_model.to.getFullYear()
|
||||
var yearsArray = []
|
||||
for (var i = fromYear; i <= toYear; i++) {
|
||||
yearsArray.push(i)
|
||||
}
|
||||
return yearsArray
|
||||
}
|
||||
currentIndex: -1
|
||||
onCurrentIndexChanged:{
|
||||
var year = model[currentIndex]
|
||||
var month = d.displayDate.getMonth()
|
||||
d.displayDate = new Date(year,month,1)
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onNextButton(){
|
||||
listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1)
|
||||
}
|
||||
function onPreviousButton(){
|
||||
listview.currentIndex = Math.max(listview.currentIndex-1,0)
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
listview.highlightMoveDuration = 0
|
||||
currentIndex = model.indexOf(d.displayDate.getFullYear())
|
||||
timer_delay.restart()
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 100
|
||||
onTriggered: {
|
||||
listview.highlightMoveDuration = 100
|
||||
}
|
||||
}
|
||||
delegate: Item{
|
||||
id:layout_congrol
|
||||
property int year : modelData
|
||||
width: listview.width
|
||||
height: 75*3
|
||||
GridView{
|
||||
anchors.fill: parent
|
||||
cellHeight: 75
|
||||
cellWidth: 75
|
||||
clip: true
|
||||
interactive: false
|
||||
boundsBehavior: GridView.StopAtBounds
|
||||
model: 12
|
||||
delegate: Item{
|
||||
property int month : modelData
|
||||
property bool toMonth: layout_congrol.year === d.toDay.getFullYear() && month === d.toDay.getMonth()
|
||||
implicitHeight: 75
|
||||
implicitWidth: 75
|
||||
FluControl{
|
||||
id:control_delegate
|
||||
width: 60
|
||||
height: 60
|
||||
anchors.centerIn: parent
|
||||
Rectangle{
|
||||
width: 48
|
||||
height: 48
|
||||
radius: width/2
|
||||
color: {
|
||||
if(toMonth){
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2)
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1)
|
||||
}
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluColors.Transparent
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
FluText{
|
||||
text: new Date(layout_congrol.year,month).toLocaleString(FluApp.locale, "MMMM")
|
||||
anchors.centerIn: parent
|
||||
opacity: {
|
||||
if(layout_congrol.year === d.displayDate.getFullYear()){
|
||||
return 1
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return 1
|
||||
}
|
||||
return 0.3
|
||||
}
|
||||
color: {
|
||||
if(toMonth){
|
||||
return FluColors.White
|
||||
}
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
d.displayDate = new Date(layout_congrol.year,month)
|
||||
d.pageIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_page_one
|
||||
ColumnLayout {
|
||||
DayOfWeekRow {
|
||||
id: dayOfWeekRow
|
||||
locale: FluApp.locale
|
||||
font.bold: false
|
||||
delegate: Label {
|
||||
text: model.shortName
|
||||
font: dayOfWeekRow.font
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Layout.column: 1
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
ListView{
|
||||
id:listview
|
||||
property bool isCompleted: false
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
spacing: 0
|
||||
highlightMoveDuration: 100
|
||||
currentIndex: -1
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
onCurrentIndexChanged:{
|
||||
if(isCompleted){
|
||||
var month = calender_model.monthAt(currentIndex)
|
||||
var year = calender_model.yearAt(currentIndex)
|
||||
d.displayDate = new Date(year,month,1)
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
listview.model = calender_model
|
||||
listview.highlightMoveDuration = 0
|
||||
currentIndex = calender_model.indexOf(d.displayDate)
|
||||
timer_delay.restart()
|
||||
isCompleted = true
|
||||
}
|
||||
Timer{
|
||||
id:timer_delay
|
||||
interval: 100
|
||||
onTriggered: {
|
||||
listview.highlightMoveDuration = 100
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: d
|
||||
function onNextButton(){
|
||||
listview.currentIndex = Math.min(listview.currentIndex+1,listview.count-1)
|
||||
}
|
||||
function onPreviousButton(){
|
||||
listview.currentIndex = Math.max(listview.currentIndex-1,0)
|
||||
}
|
||||
}
|
||||
delegate: MonthGrid {
|
||||
id: grid
|
||||
width: listview.width
|
||||
height: listview.height
|
||||
month: model.month
|
||||
year: model.year
|
||||
spacing: 0
|
||||
locale: FluApp.locale
|
||||
delegate: FluControl {
|
||||
required property bool today
|
||||
required property int year
|
||||
required property int month
|
||||
required property int day
|
||||
required property int visibleMonth
|
||||
id: control_delegate
|
||||
visibleMonth: grid.month
|
||||
implicitHeight: 40
|
||||
implicitWidth: 40
|
||||
Rectangle{
|
||||
width: 34
|
||||
height: 34
|
||||
radius: width/2
|
||||
color: {
|
||||
if(today){
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.2) : Qt.lighter(FluTheme.primaryColor,1.2)
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? Qt.darker(FluTheme.primaryColor,1.1) : Qt.lighter(FluTheme.primaryColor,1.1)
|
||||
}
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluColors.Transparent
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Rectangle{
|
||||
width: 40
|
||||
height: 40
|
||||
border.width: 1
|
||||
anchors.centerIn: parent
|
||||
radius: width/2
|
||||
border.color: FluTheme.primaryColor
|
||||
color: FluColors.Transparent
|
||||
visible: {
|
||||
if(control.current){
|
||||
var y = control.current.getFullYear()
|
||||
var m = control.current.getMonth()
|
||||
var d = control.current.getDate()
|
||||
if(y === year && m === month && d === day){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: day
|
||||
opacity: {
|
||||
if(month === grid.month){
|
||||
return 1
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return 1
|
||||
}
|
||||
return 0.3
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
color: {
|
||||
if(today){
|
||||
return FluColors.White
|
||||
}
|
||||
if(control_delegate.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey100 : FluColors.Grey100
|
||||
}
|
||||
if(control_delegate.hovered){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
control.current = new Date(year,month,day)
|
||||
control.accepted()
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
x: grid.leftPadding
|
||||
y: grid.topPadding
|
||||
width: grid.availableWidth
|
||||
height: grid.availableHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Item{
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
function showPopup() {
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.height){
|
||||
popup.y = control.height
|
||||
} else if(pos.y>container.height){
|
||||
popup.y = -container.height
|
||||
} else {
|
||||
popup.y = d.window.height-(pos.y+container.height)
|
||||
}
|
||||
popup.x = -(popup.width-control.width)/2
|
||||
popup.open()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,206 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property bool autoPlay: true
|
||||
property int loopTime: 2000
|
||||
property var model
|
||||
property Component delegate
|
||||
property bool showIndicator: true
|
||||
property int indicatorGravity : Qt.AlignBottom | Qt.AlignHCenter
|
||||
property int indicatorMarginLeft: 0
|
||||
property int indicatorMarginRight: 0
|
||||
property int indicatorMarginTop: 0
|
||||
property int indicatorMarginBottom: 20
|
||||
property int indicatorSpacing: 10
|
||||
property alias indicatorAnchors: layout_indicator.anchors
|
||||
property Component indicatorDelegate : com_indicator
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
ListModel{
|
||||
id:content_model
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flagXChanged: true
|
||||
property bool isAnimEnable: control.autoPlay && list_view.count>3
|
||||
function setData(data){
|
||||
if(!data){
|
||||
return
|
||||
}
|
||||
content_model.clear()
|
||||
content_model.append(data[data.length-1])
|
||||
content_model.append(data)
|
||||
content_model.append(data[0])
|
||||
list_view.highlightMoveDuration = 0
|
||||
list_view.currentIndex = 1
|
||||
list_view.highlightMoveDuration = 250
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:list_view
|
||||
anchors.fill: parent
|
||||
snapMode: ListView.SnapOneItem
|
||||
clip: true
|
||||
boundsBehavior: ListView.StopAtBounds
|
||||
model:content_model
|
||||
maximumFlickVelocity: 4 * (list_view.orientation === Qt.Horizontal ? width : height)
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
Component.onCompleted: {
|
||||
d.setData(control.model)
|
||||
}
|
||||
interactive: list_view.count>3
|
||||
Connections{
|
||||
target: control
|
||||
function onModelChanged(){
|
||||
d.setData(control.model)
|
||||
}
|
||||
}
|
||||
orientation : ListView.Horizontal
|
||||
delegate: Item{
|
||||
id:item_control
|
||||
width: ListView.view.width
|
||||
height: ListView.view.height
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return content_model.count-3
|
||||
if(index === content_model.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
FluLoader{
|
||||
property int displayIndex : item_control.displayIndex
|
||||
property var model: list_view.model.get(index)
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(model){
|
||||
return control.delegate
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
onMovementEnded:{
|
||||
currentIndex = list_view.contentX/list_view.width
|
||||
if(currentIndex === 0){
|
||||
currentIndex = list_view.count-2
|
||||
}else if(currentIndex === list_view.count-1){
|
||||
currentIndex = 1
|
||||
}
|
||||
d.flagXChanged = false
|
||||
timer_run.restart()
|
||||
}
|
||||
onMovementStarted: {
|
||||
d.flagXChanged = true
|
||||
timer_run.stop()
|
||||
}
|
||||
onContentXChanged: {
|
||||
if(d.flagXChanged){
|
||||
var maxX = Math.min(list_view.width*(currentIndex+1),list_view.count*list_view.width)
|
||||
var minY = Math.max(0,(list_view.width*(currentIndex-1)))
|
||||
if(contentX>=maxX){
|
||||
contentX = maxX
|
||||
}
|
||||
if(contentX<=minY){
|
||||
contentX = minY
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_indicator
|
||||
Rectangle{
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 4
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
scale: checked ? 1.2 : 1
|
||||
color: checked ? FluTheme.primaryColor : Qt.rgba(1,1,1,0.7)
|
||||
border.width: mouse_item.containsMouse ? 1 : 0
|
||||
border.color: FluTheme.primaryColor
|
||||
MouseArea{
|
||||
id:mouse_item
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
changedIndex(realIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:layout_indicator
|
||||
spacing: control.indicatorSpacing
|
||||
anchors{
|
||||
horizontalCenter:(indicatorGravity & Qt.AlignHCenter) ? parent.horizontalCenter : undefined
|
||||
verticalCenter: (indicatorGravity & Qt.AlignVCenter) ? parent.verticalCenter : undefined
|
||||
bottom: (indicatorGravity & Qt.AlignBottom) ? parent.bottom : undefined
|
||||
top: (indicatorGravity & Qt.AlignTop) ? parent.top : undefined
|
||||
left: (indicatorGravity & Qt.AlignLeft) ? parent.left : undefined
|
||||
right: (indicatorGravity & Qt.AlignRight) ? parent.right : undefined
|
||||
bottomMargin: control.indicatorMarginBottom
|
||||
leftMargin: control.indicatorMarginBottom
|
||||
rightMargin: control.indicatorMarginBottom
|
||||
topMargin: control.indicatorMarginBottom
|
||||
}
|
||||
visible: showIndicator
|
||||
Repeater{
|
||||
id:repeater_indicator
|
||||
model: list_view.count
|
||||
FluLoader{
|
||||
property int displayIndex: {
|
||||
if(index === 0)
|
||||
return list_view.count-3
|
||||
if(index === list_view.count-1)
|
||||
return 0
|
||||
return index-1
|
||||
}
|
||||
property int realIndex: index
|
||||
property bool checked: list_view.currentIndex === index
|
||||
sourceComponent: {
|
||||
if(index===0 || index===list_view.count-1)
|
||||
return undefined
|
||||
return control.indicatorDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_anim
|
||||
interval: 250
|
||||
onTriggered: {
|
||||
list_view.highlightMoveDuration = 0
|
||||
if(list_view.currentIndex === list_view.count-1){
|
||||
list_view.currentIndex = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer_run
|
||||
interval: control.loopTime
|
||||
repeat: d.isAnimEnable
|
||||
onTriggered: {
|
||||
list_view.highlightMoveDuration = 250
|
||||
list_view.currentIndex = list_view.currentIndex+1
|
||||
timer_anim.start()
|
||||
}
|
||||
}
|
||||
function changedIndex(index){
|
||||
d.flagXChanged = true
|
||||
timer_run.stop()
|
||||
list_view.currentIndex = index
|
||||
d.flagXChanged = false
|
||||
if(d.isAnimEnable){
|
||||
timer_run.restart()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,117 +0,0 @@
|
||||
import QtQuick
|
||||
import "./../JS/Chart.js" as Chart
|
||||
|
||||
Canvas {
|
||||
id: control
|
||||
property string chartType
|
||||
property var chartData
|
||||
property var chartOptions
|
||||
property double chartAnimationProgress: 0.1
|
||||
property int animationEasingType: Easing.InOutExpo
|
||||
property double animationDuration: 300
|
||||
property alias animationRunning: chartAnimator.running
|
||||
signal animationFinished()
|
||||
function animateToNewData()
|
||||
{
|
||||
chartAnimationProgress = 0.1;
|
||||
d.jsChart.update();
|
||||
chartAnimator.restart();
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property var jsChart: undefined
|
||||
property var memorizedContext
|
||||
property var memorizedData
|
||||
property var memorizedOptions
|
||||
}
|
||||
MouseArea {
|
||||
id: event
|
||||
anchors.fill: control
|
||||
hoverEnabled: true
|
||||
enabled: true
|
||||
property var handler: undefined
|
||||
property QtObject mouseEvent: QtObject {
|
||||
property int left: 0
|
||||
property int top: 0
|
||||
property int x: 0
|
||||
property int y: 0
|
||||
property int clientX: 0
|
||||
property int clientY: 0
|
||||
property string type: ""
|
||||
property var target
|
||||
}
|
||||
function submitEvent(mouse, type) {
|
||||
mouseEvent.type = type
|
||||
mouseEvent.clientX = mouse ? mouse.x : 0;
|
||||
mouseEvent.clientY = mouse ? mouse.y : 0;
|
||||
mouseEvent.x = mouse ? mouse.x : 0;
|
||||
mouseEvent.y = mouse ? mouse.y : 0;
|
||||
mouseEvent.left = 0;
|
||||
mouseEvent.top = 0;
|
||||
mouseEvent.target = control;
|
||||
if(handler) {
|
||||
handler(mouseEvent);
|
||||
}
|
||||
control.requestPaint();
|
||||
}
|
||||
onClicked:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "click");
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "mousemove");
|
||||
}
|
||||
onExited: {
|
||||
submitEvent(undefined, "mouseout");
|
||||
}
|
||||
onEntered: {
|
||||
submitEvent(undefined, "mouseenter");
|
||||
}
|
||||
onPressed:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "mousedown");
|
||||
}
|
||||
onReleased:
|
||||
(mouse)=> {
|
||||
submitEvent(mouse, "mouseup");
|
||||
}
|
||||
}
|
||||
PropertyAnimation {
|
||||
id: chartAnimator
|
||||
target: control
|
||||
property: "chartAnimationProgress"
|
||||
alwaysRunToEnd: true
|
||||
to: 1
|
||||
duration: control.animationDuration
|
||||
easing.type: control.animationEasingType
|
||||
onFinished: {
|
||||
control.animationFinished();
|
||||
}
|
||||
}
|
||||
onChartAnimationProgressChanged: {
|
||||
control.requestPaint();
|
||||
}
|
||||
onPaint: {
|
||||
if(control.getContext('2d') !== null && d.memorizedContext !== control.getContext('2d') || d.memorizedData !== control.chartData || d.memorizedOptions !== control.chartOptions) {
|
||||
var ctx = control.getContext('2d');
|
||||
d.jsChart = Chart.build(ctx, {type: control.chartType,data: control.chartData,options: control.chartOptions});
|
||||
d.memorizedData = control.chartData ;
|
||||
d.memorizedContext = control.getContext('2d');
|
||||
d.memorizedOptions = control.chartOptions;
|
||||
d.jsChart.bindEvents(function(newHandler) {event.handler = newHandler;});
|
||||
chartAnimator.start();
|
||||
}
|
||||
d.jsChart.draw(chartAnimationProgress);
|
||||
}
|
||||
onWidthChanged: {
|
||||
if(d.jsChart) {
|
||||
d.jsChart.resize();
|
||||
}
|
||||
}
|
||||
onHeightChanged: {
|
||||
if(d.jsChart) {
|
||||
d.jsChart.resize();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color borderNormalColor: FluTheme.dark ? Qt.rgba(160/255,160/255,160/255,1) : Qt.rgba(136/255,136/255,136/255,1)
|
||||
property color bordercheckedColor: FluTheme.primaryColor
|
||||
property color borderHoverColor: FluTheme.dark ? Qt.rgba(167/255,167/255,167/255,1) : Qt.rgba(135/255,135/255,135/255,1)
|
||||
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color borderPressedColor: FluTheme.dark ? Qt.rgba(90/255,90/255,90/255,1) : Qt.rgba(191/255,191/255,191/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(247/255,247/255,247/255,1)
|
||||
property color checkedColor: FluTheme.primaryColor
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(72/255,72/255,72/255,1) : Qt.rgba(236/255,236/255,236/255,1)
|
||||
property color checkedHoverColor: FluTheme.dark ? Qt.darker(checkedColor,1.15) : Qt.lighter(checkedColor,1.15)
|
||||
property color checkedPreesedColor: FluTheme.dark ? Qt.darker(checkedColor,1.3) : Qt.lighter(checkedColor,1.3)
|
||||
property color checkedDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1)
|
||||
property real size: 18
|
||||
property alias textColor: btn_text.textColor
|
||||
property bool textRight: true
|
||||
property real textSpacing: 6
|
||||
property bool enableAnimation: FluTheme.enableAnimation
|
||||
property var clickListener : function(){
|
||||
checked = !checked
|
||||
}
|
||||
property bool indeterminate : false
|
||||
id:control
|
||||
enabled: !disabled
|
||||
onClicked: clickListener()
|
||||
onCheckableChanged: {
|
||||
if(checkable){
|
||||
checkable = false
|
||||
}
|
||||
}
|
||||
background: Item{
|
||||
FluFocusRectangle{
|
||||
radius: 4
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
horizontalPadding:0
|
||||
verticalPadding: 0
|
||||
padding: 0
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
focusPolicy:Qt.TabFocus
|
||||
contentItem: RowLayout{
|
||||
spacing: control.textSpacing
|
||||
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
|
||||
Rectangle{
|
||||
width: control.size
|
||||
height: control.size
|
||||
radius: 4
|
||||
border.color: {
|
||||
if(!enabled){
|
||||
return borderDisableColor
|
||||
}
|
||||
if(checked){
|
||||
return bordercheckedColor
|
||||
}
|
||||
if(pressed){
|
||||
return borderPressedColor
|
||||
}
|
||||
if(hovered){
|
||||
return borderHoverColor
|
||||
}
|
||||
return borderNormalColor
|
||||
}
|
||||
border.width: 1
|
||||
color: {
|
||||
if(checked){
|
||||
if(!enabled){
|
||||
return checkedDisableColor
|
||||
}
|
||||
if(pressed){
|
||||
return checkedPreesedColor
|
||||
}
|
||||
if(hovered){
|
||||
return checkedHoverColor
|
||||
}
|
||||
return checkedColor
|
||||
}
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(hovered){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
Behavior on color {
|
||||
enabled: control.enableAnimation
|
||||
ColorAnimation{
|
||||
duration: 83
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.CheckboxIndeterminate
|
||||
iconSize: 14
|
||||
visible: indeterminate
|
||||
iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
Behavior on visible {
|
||||
enabled: control.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 83
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSource: FluentIcons.AcceptMedium
|
||||
iconSize: 14
|
||||
visible: checked && !indeterminate
|
||||
iconColor: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
Behavior on visible {
|
||||
enabled: control.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 83
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
id:btn_text
|
||||
text: control.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: text !== ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import FluentUI
|
||||
|
||||
FluRectangle {
|
||||
id:control
|
||||
color: "#00000000"
|
||||
layer.enabled: !FluTools.isSoftware()
|
||||
layer.textureSize: Qt.size(control.width*2*Math.ceil(Screen.devicePixelRatio),control.height*2*Math.ceil(Screen.devicePixelRatio))
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: ShaderEffectSource{
|
||||
sourceItem: FluRectangle{
|
||||
radius: control.radius
|
||||
width: control.width
|
||||
height: control.height
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,589 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Button{
|
||||
id:control
|
||||
width: 36
|
||||
height: 36
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
property color current : Qt.rgba(1,1,1,1)
|
||||
signal accepted()
|
||||
property int colorHandleRadius: 8
|
||||
property string cancelText: "取消"
|
||||
property string okText: "确定"
|
||||
property string titleText: "颜色选择器"
|
||||
property string editText: "编辑颜色"
|
||||
property string redText: "红色"
|
||||
property string greenText: "绿色"
|
||||
property string blueText: "蓝色"
|
||||
property string opacityText: "透明度"
|
||||
background:
|
||||
Rectangle{
|
||||
id:layout_color
|
||||
radius: 5
|
||||
color:"#00000000"
|
||||
border.color: {
|
||||
if(hovered)
|
||||
return FluTheme.primaryColor
|
||||
return FluTheme.dark ? Qt.rgba(100/255,100/255,100/255,1) : Qt.rgba(200/255,200/255,200/255,1)
|
||||
}
|
||||
border.width: 1
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
radius: 5
|
||||
color: control.current
|
||||
}
|
||||
}
|
||||
contentItem: Item{}
|
||||
onClicked: {
|
||||
color_dialog.open()
|
||||
}
|
||||
FluPopup{
|
||||
id:color_dialog
|
||||
implicitWidth: 326
|
||||
implicitHeight: 560
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
width: parent.width
|
||||
height: 60
|
||||
radius: 5
|
||||
z:999
|
||||
anchors.bottom: parent.bottom
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
RowLayout{
|
||||
anchors
|
||||
{
|
||||
centerIn: parent
|
||||
margins: spacing
|
||||
fill: parent
|
||||
}
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluButton{
|
||||
text: control.cancelText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
color_dialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluFilledButton{
|
||||
text: control.okText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
current = layout_color_hue.colorValue
|
||||
control.accepted()
|
||||
color_dialog.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem: Flickable{
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: Math.min(layout_content.height,560,color_dialog.height)
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
contentHeight: layout_content.height + 70
|
||||
contentWidth: width
|
||||
clip: true
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
Item{
|
||||
id: layout_content
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
FluText{
|
||||
id: text_titile
|
||||
font: FluTextStyle.Subtitle
|
||||
text: control.titleText
|
||||
anchors{
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
leftMargin: 20
|
||||
topMargin: 20
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id: layout_sb
|
||||
width: 200
|
||||
height: 200
|
||||
anchors{
|
||||
left: parent.left
|
||||
top: text_titile.bottom
|
||||
leftMargin: 12
|
||||
}
|
||||
FluClip{
|
||||
id: layout_color_hue
|
||||
property color colorValue
|
||||
property real xPercent: pickerCursor.x/width
|
||||
property real yPercent: pickerCursor.y/height
|
||||
property real blackPercent: blackCursor.x/(layout_black.width-12)
|
||||
property real opacityPercent: opacityCursor.x/(layout_opacity.width-12)
|
||||
property color opacityColor:{
|
||||
var c = blackColor
|
||||
c = Qt.rgba(c.r,c.g,c.b,opacityPercent)
|
||||
return c
|
||||
}
|
||||
onOpacityColorChanged: {
|
||||
layout_color_hue.colorValue = opacityColor
|
||||
updateColorText(opacityColor)
|
||||
}
|
||||
function updateColorText(color){
|
||||
text_box_r.text = String(Math.floor(color.r*255))
|
||||
text_box_g.text = String(Math.floor(color.g*255))
|
||||
text_box_b.text = String(Math.floor(color.b*255))
|
||||
text_box_a.text = String(Math.floor(color.a*100))
|
||||
var colorString = color.toString().slice(1)
|
||||
if(color.a===1){
|
||||
colorString = "FF"+colorString
|
||||
}
|
||||
text_box_color.text = colorString.toUpperCase()
|
||||
}
|
||||
property color blackColor: {
|
||||
var c = whiteColor
|
||||
c = Qt.rgba(c.r*blackPercent,c.g*blackPercent,c.b*blackPercent,1)
|
||||
return c
|
||||
}
|
||||
property color hueColor: {
|
||||
var v = 1.0-xPercent
|
||||
var c
|
||||
if(0.0 <= v && v < 0.16) {
|
||||
c = Qt.rgba(1.0, 0.0, v/0.16, 1.0)
|
||||
} else if(0.16 <= v && v < 0.33) {
|
||||
c = Qt.rgba(1.0 - (v-0.16)/0.17, 0.0, 1.0, 1.0)
|
||||
} else if(0.33 <= v && v < 0.5) {
|
||||
c = Qt.rgba(0.0, ((v-0.33)/0.17), 1.0, 1.0)
|
||||
} else if(0.5 <= v && v < 0.76) {
|
||||
c = Qt.rgba(0.0, 1.0, 1.0 - (v-0.5)/0.26, 1.0)
|
||||
} else if(0.76 <= v && v < 0.85) {
|
||||
c = Qt.rgba((v-0.76)/0.09, 1.0, 0.0, 1.0)
|
||||
} else if(0.85 <= v && v <= 1.0) {
|
||||
c = Qt.rgba(1.0, 1.0 - (v-0.85)/0.15, 0.0, 1.0)
|
||||
} else {
|
||||
c = Qt.rgba(1.0,0.0,0.0,1.0)
|
||||
}
|
||||
return c
|
||||
}
|
||||
property color whiteColor: {
|
||||
var c = hueColor
|
||||
c = Qt.rgba((1-c.r)*yPercent+c.r,(1-c.g)*yPercent+c.g,(1-c.b)*yPercent+c.b,1.0)
|
||||
return c
|
||||
}
|
||||
function updateColor(){
|
||||
var r = Number(text_box_r.text)/255
|
||||
var g = Number(text_box_g.text)/255
|
||||
var b = Number(text_box_b.text)/255
|
||||
var opacityPercent = Number(text_box_a.text)/100
|
||||
var blackPercent = Math.max(r,g,b)
|
||||
r = r/blackPercent
|
||||
g = g/blackPercent
|
||||
b = b/blackPercent
|
||||
var yPercent = Math.min(r,g,b)
|
||||
if(r === g && r === b){
|
||||
r = 1
|
||||
b = 1
|
||||
g = 1
|
||||
}else{
|
||||
r = (yPercent-r)/(yPercent-1)
|
||||
g = (yPercent-g)/(yPercent-1)
|
||||
b = (yPercent-b)/(yPercent-1)
|
||||
}
|
||||
var xPercent
|
||||
if (r === 1.0 && g === 0.0 && b <= 1.0) {
|
||||
if(b===0.0){
|
||||
xPercent = 0
|
||||
}else{
|
||||
xPercent = 1.0 - b * 0.16
|
||||
}
|
||||
} else if (r <= 1.0 && g === 0.0 && b === 1.0) {
|
||||
xPercent = 1.0 - (1.0 - r) * 0.17 - 0.16
|
||||
} else if (r === 0.0 && g <= 1.0 && b === 1.0) {
|
||||
xPercent = 1.0 - (g * 0.17 + 0.33)
|
||||
} else if (r === 0.0 && g === 1.0 && b <= 1.0) {
|
||||
xPercent = 1.0 - (1.0 - b) * 0.26 - 0.5
|
||||
} else if (r <= 1.0 && g === 1.0 && b === 0.0) {
|
||||
xPercent = 1.0 - (r * 0.09 + 0.76)
|
||||
} else if (r === 1.0 && g <= 1.0 && b === 0.0) {
|
||||
xPercent = 1.0 - (1.0 - g) * 0.15 - 0.85
|
||||
} else {
|
||||
xPercent = 0
|
||||
}
|
||||
pickerCursor.x = xPercent * width
|
||||
pickerCursor.y = yPercent * height
|
||||
blackCursor.x = blackPercent * (layout_black.width-12)
|
||||
opacityCursor.x = opacityPercent * (layout_opacity.width-12)
|
||||
}
|
||||
radius: [4,4,4,4]
|
||||
x: colorHandleRadius
|
||||
y: colorHandleRadius
|
||||
width: parent.width - 2 * colorHandleRadius
|
||||
height: parent.height - 2 * colorHandleRadius
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.0; color: "#FF0000" }
|
||||
GradientStop { position: 0.16; color: "#FFFF00" }
|
||||
GradientStop { position: 0.33; color: "#00FF00" }
|
||||
GradientStop { position: 0.5; color: "#00FFFF" }
|
||||
GradientStop { position: 0.76; color: "#0000FF" }
|
||||
GradientStop { position: 0.85; color: "#FF00FF" }
|
||||
GradientStop { position: 1.0; color: "#FF0000" }
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#FFFFFFFF" }
|
||||
GradientStop { position: 0.0; color: "#00000000" }
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors.fill: parent
|
||||
border.width: 1
|
||||
border.color: FluTheme.dividerColor
|
||||
color:"#00000000"
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: pickerCursor
|
||||
Rectangle {
|
||||
width: colorHandleRadius*2; height: colorHandleRadius*2
|
||||
radius: colorHandleRadius
|
||||
border.color: "black"; border.width: 2
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent; anchors.margins: 2;
|
||||
border.color: "white"; border.width: 2
|
||||
radius: width/2
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
x: colorHandleRadius
|
||||
y: colorHandleRadius
|
||||
preventStealing: true
|
||||
function handleMouse(mouse) {
|
||||
if (mouse.buttons & Qt.LeftButton) {
|
||||
pickerCursor.x = Math.max(0,Math.min(mouse.x - colorHandleRadius,width-2*colorHandleRadius));
|
||||
pickerCursor.y = Math.max(0,Math.min(mouse.y - colorHandleRadius,height-2*colorHandleRadius));
|
||||
}
|
||||
}
|
||||
onPositionChanged:(mouse)=> handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
}
|
||||
FluClip{
|
||||
width: 40
|
||||
height: 200
|
||||
anchors{
|
||||
top: layout_sb.top
|
||||
bottom: layout_sb.bottom
|
||||
left: layout_sb.right
|
||||
topMargin: colorHandleRadius
|
||||
bottomMargin: colorHandleRadius
|
||||
leftMargin: 4
|
||||
}
|
||||
radius: [4,4,4,4]
|
||||
Grid {
|
||||
padding: 0
|
||||
id:target_grid_color
|
||||
anchors.fill: parent
|
||||
rows: height/5+1
|
||||
columns: width/5+1
|
||||
Repeater {
|
||||
model: (target_grid_color.columns-1)*(target_grid_color.rows-1)
|
||||
Rectangle {
|
||||
width: 6
|
||||
height: 6
|
||||
color: (model.index%2 == 0) ? "gray" : "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color:layout_color_hue.colorValue
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: FluTheme.dividerColor
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
id:layout_slider_bar
|
||||
spacing: 8
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 18
|
||||
right: parent.right
|
||||
rightMargin: 18
|
||||
top: layout_sb.bottom
|
||||
topMargin: 10
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_black
|
||||
radius: 6
|
||||
height: 12
|
||||
width:parent.width
|
||||
gradient: Gradient {
|
||||
orientation:Gradient.Horizontal
|
||||
GradientStop { position: 0.0; color: "#FF000000" }
|
||||
GradientStop { position: 1.0; color: layout_color_hue.hueColor }
|
||||
}
|
||||
Item {
|
||||
id:blackCursor
|
||||
x:layout_black.width-12
|
||||
Rectangle {
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 6
|
||||
border.color: "black"
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
border.color: "white"
|
||||
border.width: 2
|
||||
radius: width/2
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
function handleMouse(mouse) {
|
||||
if (mouse.buttons & Qt.LeftButton) {
|
||||
blackCursor.x = Math.max(0,Math.min(mouse.x - 6,width-2*6));
|
||||
blackCursor.y = 0
|
||||
}
|
||||
}
|
||||
onPositionChanged:(mouse)=> handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
|
||||
}
|
||||
FluClip{
|
||||
id:layout_opacity
|
||||
height: 12
|
||||
width:parent.width
|
||||
radius: [6,6,6,6]
|
||||
Grid {
|
||||
id:grid_opacity
|
||||
anchors.fill: parent
|
||||
rows: height/4
|
||||
columns: width/4+1
|
||||
clip: true
|
||||
Repeater {
|
||||
model: grid_opacity.columns*grid_opacity.rows
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: 4
|
||||
color: (model.index%2 == 0) ? "gray" : "white"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.debug(grid_opacity.columns,grid_opacity.rows)
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
orientation:Gradient.Horizontal
|
||||
GradientStop { position: 0.0; color: "#00000000" }
|
||||
GradientStop { position: 1.0; color: layout_color_hue.blackColor }
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id:opacityCursor
|
||||
x:layout_opacity.width-12
|
||||
Rectangle {
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 6
|
||||
border.color: "black"
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
border.color: "white"
|
||||
border.width: 2
|
||||
radius: width/2
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id:mouse_opacity
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
function handleMouse(mouse) {
|
||||
if (mouse.buttons & Qt.LeftButton) {
|
||||
opacityCursor.x = Math.max(0,Math.min(mouse.x - 6,width-2*6));
|
||||
opacityCursor.y = 0
|
||||
}
|
||||
}
|
||||
onPositionChanged:(mouse)=> handleMouse(mouse)
|
||||
onPressed:(mouse)=> handleMouse(mouse)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
top: layout_slider_bar.bottom
|
||||
topMargin: 10
|
||||
right: parent.right
|
||||
rightMargin: 20
|
||||
}
|
||||
spacing: 5
|
||||
Item{
|
||||
width: parent.width
|
||||
height: text_box_color.height
|
||||
FluText{
|
||||
text: control.editText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left:parent.left
|
||||
}
|
||||
}
|
||||
FluTextBox{
|
||||
id:text_box_color
|
||||
width: 136
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^[0-9A-F]{8}$/
|
||||
}
|
||||
anchors{
|
||||
right: parent.right
|
||||
}
|
||||
leftPadding: 20
|
||||
FluText{
|
||||
text:"#"
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 5
|
||||
}
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
var colorString = text_box_color.text.padStart(8,"0")
|
||||
var c = Qt.rgba(
|
||||
parseInt(colorString.substring(2, 4), 16) / 255,
|
||||
parseInt(colorString.substring(4, 6), 16) / 255,
|
||||
parseInt(colorString.substring(6, 8), 16) / 255,
|
||||
parseInt(colorString.substring(0, 2), 16) / 255)
|
||||
layout_color_hue.colorValue = c
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_r
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
layout_color_hue.updateColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.redText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_g
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
layout_color_hue.updateColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.greenText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_b
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
layout_color_hue.updateColor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.blueText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 10
|
||||
FluTextBox{
|
||||
id:text_box_a
|
||||
width: 120
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^(100|[1-9]?\d)$/
|
||||
}
|
||||
FluText{
|
||||
id:text_opacity
|
||||
text:"%"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x:Math.min(text_box_a.implicitWidth,text_box_a.width)-38
|
||||
}
|
||||
onTextEdited: {
|
||||
if(text!==""){
|
||||
opacityCursor.x = Number(text)/100 * (layout_opacity.width-12)
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: control.opacityText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
import QtQuick.Templates as T
|
||||
|
||||
T.ComboBox {
|
||||
id: control
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
font: FluTextStyle.Body
|
||||
leftPadding: padding + (!control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
|
||||
rightPadding: padding + (control.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
|
||||
enabled: !disabled
|
||||
delegate: FluItemDelegate {
|
||||
width: ListView.view.width
|
||||
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
|
||||
palette.text: control.palette.text
|
||||
font: control.font
|
||||
palette.highlightedText: control.palette.highlightedText
|
||||
highlighted: control.highlightedIndex === index
|
||||
hoverEnabled: control.hoverEnabled
|
||||
}
|
||||
focusPolicy:Qt.TabFocus
|
||||
indicator: FluIcon {
|
||||
x: control.mirrored ? control.padding : control.width - width - control.padding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
width: 28
|
||||
iconSource:FluentIcons.ChevronDown
|
||||
iconSize: 15
|
||||
opacity: enabled ? 1 : 0.3
|
||||
}
|
||||
contentItem: T.TextField {
|
||||
property bool disabled: !control.editable
|
||||
leftPadding: !control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1
|
||||
rightPadding: control.mirrored ? 10 : control.editable && activeFocus ? 3 : 1
|
||||
topPadding: 6 - control.padding
|
||||
bottomPadding: 6 - control.padding
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
selectedTextColor: color
|
||||
text: control.editable ? control.editText : control.displayText
|
||||
enabled: control.editable
|
||||
autoScroll: control.editable
|
||||
font:control.font
|
||||
readOnly: control.down
|
||||
color: {
|
||||
if(control.disabled) {
|
||||
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
}
|
||||
inputMethodHints: control.inputMethodHints
|
||||
validator: control.validator
|
||||
selectByMouse: true
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
leftInset:1
|
||||
topInset:1
|
||||
bottomInset:1
|
||||
rightInset:1
|
||||
background: FluTextBoxBackground{
|
||||
borderWidth: 0
|
||||
inputItem: contentItem
|
||||
}
|
||||
Component.onCompleted: {
|
||||
forceActiveFocus()
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> handleCommit(event)
|
||||
function handleCommit(event){
|
||||
control.commit(control.editText)
|
||||
accepted()
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 140
|
||||
implicitHeight: 32
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
visible: !control.flat || control.down
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.visualFocus
|
||||
radius:4
|
||||
anchors.margins: -2
|
||||
}
|
||||
color:{
|
||||
if(disabled){
|
||||
return disableColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
|
||||
popup: T.Popup {
|
||||
y: control.height
|
||||
width: control.width
|
||||
height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin)
|
||||
topMargin: 6
|
||||
bottomMargin: 6
|
||||
modal: true
|
||||
contentItem: ListView {
|
||||
clip: true
|
||||
implicitHeight: contentHeight
|
||||
model: control.delegateModel
|
||||
currentIndex: control.highlightedIndex
|
||||
highlightMoveDuration: 0
|
||||
boundsMovement: Flickable.StopAtBounds
|
||||
T.ScrollIndicator.vertical: ScrollIndicator { }
|
||||
}
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
background:Rectangle{
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
radius: 5
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
FluPopup {
|
||||
id: control
|
||||
property string title: ""
|
||||
property string message: ""
|
||||
property string neutralText: qsTr("Close")
|
||||
property string negativeText: qsTr("Cancel")
|
||||
property string positiveText: qsTr("OK")
|
||||
property int messageTextFormart: Text.AutoText
|
||||
property int delayTime: 100
|
||||
property int buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton
|
||||
property var contentDelegate: Component{
|
||||
Item{
|
||||
}
|
||||
}
|
||||
property var onNeutralClickListener
|
||||
property var onNegativeClickListener
|
||||
property var onPositiveClickListener
|
||||
signal neutralClicked
|
||||
signal negativeClicked
|
||||
signal positiveClicked
|
||||
implicitWidth: 400
|
||||
implicitHeight: layout_content.height
|
||||
focus: true
|
||||
Component{
|
||||
id:com_message
|
||||
Flickable{
|
||||
id:sroll_message
|
||||
contentHeight: text_message.height
|
||||
contentWidth: width
|
||||
clip: true
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
width: parent.width
|
||||
height: message === "" ? 0 : Math.min(text_message.height,300)
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
FluText{
|
||||
id:text_message
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
text:message
|
||||
width: parent.width
|
||||
topPadding: 4
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
bottomPadding: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id:layout_content
|
||||
width: parent.width
|
||||
height: layout_column.childrenRect.height
|
||||
color: 'transparent'
|
||||
radius:5
|
||||
ColumnLayout{
|
||||
id:layout_column
|
||||
width: parent.width
|
||||
FluText{
|
||||
id:text_title
|
||||
font: FluTextStyle.Title
|
||||
text:title
|
||||
topPadding: 20
|
||||
leftPadding: 20
|
||||
rightPadding: 20
|
||||
wrapMode: Text.WrapAnywhere
|
||||
}
|
||||
FluLoader{
|
||||
sourceComponent: com_message
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: status===Loader.Ready ? item.height : 0
|
||||
}
|
||||
FluLoader{
|
||||
sourceComponent:control.visible ? control.contentDelegate : undefined
|
||||
Layout.fillWidth: true
|
||||
onStatusChanged: {
|
||||
if(status===Loader.Ready){
|
||||
Layout.preferredHeight = item.implicitHeight
|
||||
}else{
|
||||
Layout.preferredHeight = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 60
|
||||
radius: 5
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
RowLayout{
|
||||
anchors
|
||||
{
|
||||
centerIn: parent
|
||||
margins: spacing
|
||||
fill: parent
|
||||
}
|
||||
spacing: 10
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluButton{
|
||||
id:neutral_btn
|
||||
visible: control.buttonFlags&FluContentDialogType.NeutralButton
|
||||
text: neutralText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
if(control.onNeutralClickListener){
|
||||
control.onNeutralClickListener()
|
||||
}else{
|
||||
neutralClicked()
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluButton{
|
||||
id:negative_btn
|
||||
visible: control.buttonFlags&FluContentDialogType.NegativeButton
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
text: negativeText
|
||||
onClicked: {
|
||||
if(control.onNegativeClickListener){
|
||||
control.onNegativeClickListener()
|
||||
}else{
|
||||
negativeClicked()
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
FluFilledButton{
|
||||
id:positive_btn
|
||||
visible: control.buttonFlags&FluContentDialogType.PositiveButton
|
||||
text: positiveText
|
||||
width: parent.width
|
||||
anchors.centerIn: parent
|
||||
onClicked: {
|
||||
if(control.onPositiveClickListener){
|
||||
control.onPositiveClickListener()
|
||||
}else{
|
||||
positiveClicked()
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluPage {
|
||||
property alias title: text_title.text
|
||||
default property alias content: container.data
|
||||
property int leftPadding: 10
|
||||
property int topPadding: 0
|
||||
property int rightPadding: 10
|
||||
property int bottomPadding: 10
|
||||
property alias color: status_view.color
|
||||
property alias statusMode: status_view.statusMode
|
||||
property alias loadingText: status_view.loadingText
|
||||
property alias emptyText:status_view.emptyText
|
||||
property alias errorText:status_view.errorText
|
||||
property alias errorButtonText:status_view.errorButtonText
|
||||
property alias loadingItem :status_view.loadingItem
|
||||
property alias emptyItem : status_view.emptyItem
|
||||
property alias errorItem :status_view.errorItem
|
||||
signal errorClicked
|
||||
|
||||
id:control
|
||||
FluText{
|
||||
id:text_title
|
||||
visible: text !== ""
|
||||
height: visible ? contentHeight : 0
|
||||
font: FluTextStyle.Title
|
||||
anchors{
|
||||
top: parent.top
|
||||
topMargin: control.topPadding
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: control.leftPadding
|
||||
rightMargin: control.rightPadding
|
||||
}
|
||||
}
|
||||
FluStatusLayout{
|
||||
id:status_view
|
||||
color: "#00000000"
|
||||
statusMode: FluStatusLayoutType.Success
|
||||
onErrorClicked: control.errorClicked()
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: text_title.bottom
|
||||
bottom: parent.bottom
|
||||
leftMargin: control.leftPadding
|
||||
rightMargin: control.rightPadding
|
||||
bottomMargin: control.bottomPadding
|
||||
}
|
||||
Item{
|
||||
clip: true
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import FluentUI
|
||||
import QtQuick.Templates as T
|
||||
|
||||
T.Button {
|
||||
id: control
|
||||
property string contentDescription: ""
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
padding: 0
|
||||
horizontalPadding: 0
|
||||
spacing: 0
|
||||
contentItem: Item{}
|
||||
focusPolicy:Qt.TabFocus
|
||||
background: Item{
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:8
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
TextEdit {
|
||||
property color textColor: FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
id:control
|
||||
color: textColor
|
||||
readOnly: true
|
||||
activeFocusOnTab: false
|
||||
activeFocusOnPress: false
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
padding: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
selectByMouse: true
|
||||
selectedTextColor: color
|
||||
bottomPadding: 0
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
font:FluTextStyle.Body
|
||||
onSelectedTextChanged: {
|
||||
control.forceActiveFocus()
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: control.echoMode !== TextInput.Password && menu.popup()
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
@ -1,415 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property bool showYear: true
|
||||
property var current
|
||||
property string yearText: qsTr("Year")
|
||||
property string monthText: qsTr("Month")
|
||||
property string dayText: qsTr("Day")
|
||||
property string cancelText: qsTr("Cancel")
|
||||
property string okText: qsTr("OK")
|
||||
signal accepted()
|
||||
id:control
|
||||
color: {
|
||||
if(mouse_area.containsMouse){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
height: 30
|
||||
width: 300
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: dividerColor
|
||||
Component.onCompleted: {
|
||||
if(current){
|
||||
const now = current;
|
||||
var year = text_year.text === control.yearText? now.getFullYear() : Number(text_year.text);
|
||||
var month = text_month.text === control.monthText? now.getMonth() + 1 : Number(text_month.text);
|
||||
var day = text_day.text === control.dayText ? now.getDate() : Number(text_day.text);
|
||||
text_year.text = year
|
||||
text_month.text = month
|
||||
text_day.text = day
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property var window: Window.window
|
||||
property bool changeFlag: true
|
||||
property var rowData: ["","",""]
|
||||
visible: false
|
||||
}
|
||||
MouseArea{
|
||||
id:mouse_area
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
popup.showPopup()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:divider_1
|
||||
width: 1
|
||||
x: parent.width/3
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
visible: showYear
|
||||
}
|
||||
Rectangle{
|
||||
id:divider_2
|
||||
width: 1
|
||||
x: showYear ? parent.width*2/3 : parent.width/2
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
FluText{
|
||||
id:text_year
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: divider_1.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
visible: showYear
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:control.yearText
|
||||
}
|
||||
FluText{
|
||||
id:text_month
|
||||
anchors{
|
||||
left: showYear ? divider_1.right : parent.left
|
||||
right: divider_2.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:control.monthText
|
||||
}
|
||||
FluText{
|
||||
id:text_day
|
||||
anchors{
|
||||
left: divider_2.right
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text:control.dayText
|
||||
}
|
||||
Menu{
|
||||
id:popup
|
||||
modal: true
|
||||
width: container.width
|
||||
height: container.height
|
||||
Overlay.modal: Item {}
|
||||
enter: Transition {
|
||||
reversible: true
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
background:Item{
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
id:container
|
||||
radius: 4
|
||||
width: 300
|
||||
height: 340
|
||||
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
}
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
RowLayout{
|
||||
id:layout_content
|
||||
spacing: 0
|
||||
width: parent.width
|
||||
height: 300
|
||||
Component{
|
||||
id:list_delegate
|
||||
Item{
|
||||
height:38
|
||||
width:getListView().width
|
||||
function getListView(){
|
||||
if(type === 0)
|
||||
return list_view_1
|
||||
if(type === 1)
|
||||
return list_view_2
|
||||
if(type === 2)
|
||||
return list_view_3
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 2
|
||||
anchors.bottomMargin: 2
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
color: {
|
||||
if(getListView().currentIndex === position){
|
||||
return item_mouse.containsMouse ? Qt.lighter(FluTheme.primaryColor,1.1): FluTheme.primaryColor
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
radius: 3
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
getListView().currentIndex = position
|
||||
if(type === 0){
|
||||
text_year.text = model
|
||||
list_view_2.model = generateMonthArray(1,12)
|
||||
text_month.text = list_view_2.model[list_view_2.currentIndex]
|
||||
|
||||
list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex])
|
||||
text_day.text = list_view_3.model[list_view_3.currentIndex]
|
||||
}
|
||||
if(type === 1){
|
||||
text_month.text = model
|
||||
list_view_3.model = generateMonthDaysArray(list_view_1.model[list_view_1.currentIndex],list_view_2.model[list_view_2.currentIndex])
|
||||
text_day.text = list_view_3.model[list_view_3.currentIndex]
|
||||
|
||||
}
|
||||
if(type === 2){
|
||||
text_day.text = model
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:model
|
||||
color: {
|
||||
if(getListView().currentIndex === position){
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}else{
|
||||
return FluTheme.dark ? "#FFFFFF" : "#1A1A1A"
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:list_view_1
|
||||
width: 100
|
||||
height: parent.height
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
model: generateYearArray(1924,2048)
|
||||
clip: true
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
visible: showYear
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:0
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
ListView{
|
||||
id:list_view_2
|
||||
width: showYear ? 100 : 150
|
||||
height: parent.height
|
||||
clip: true
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:1
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
ListView{
|
||||
id:list_view_3
|
||||
width: showYear ? 100 : 150
|
||||
height: parent.height
|
||||
clip: true
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:2
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: layout_content.bottom
|
||||
color: dividerColor
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
height: 40
|
||||
radius: 5
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
anchors{
|
||||
bottom:parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
Item {
|
||||
id:divider
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
FluButton{
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
rightMargin: 10
|
||||
right: divider.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: control.cancelText
|
||||
onClicked: {
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
FluFilledButton{
|
||||
anchors{
|
||||
right: parent.right
|
||||
left: divider.right
|
||||
rightMargin: 20
|
||||
leftMargin: 10
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: control.okText
|
||||
onClicked: {
|
||||
d.changeFlag = false
|
||||
popup.close()
|
||||
const year = text_year.text
|
||||
const month = text_month.text
|
||||
const day = text_day.text
|
||||
const date = new Date()
|
||||
date.setFullYear(parseInt(year));
|
||||
date.setMonth(parseInt(month) - 1);
|
||||
date.setDate(parseInt(day));
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
current = date
|
||||
control.accepted()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
y:35
|
||||
function showPopup() {
|
||||
d.changeFlag = true
|
||||
d.rowData[0] = text_year.text
|
||||
d.rowData[1] = text_month.text
|
||||
d.rowData[2] = text_day.text
|
||||
const now = new Date();
|
||||
var year = text_year.text === control.yearText? now.getFullYear() : Number(text_year.text);
|
||||
var month = text_month.text === control.monthText? now.getMonth() + 1 : Number(text_month.text);
|
||||
var day = text_day.text === control.dayText ? now.getDate() : Number(text_day.text);
|
||||
list_view_1.currentIndex = list_view_1.model.indexOf(year)
|
||||
text_year.text = year
|
||||
list_view_2.model = generateMonthArray(1,12)
|
||||
list_view_2.currentIndex = list_view_2.model.indexOf(month)
|
||||
text_month.text = month
|
||||
list_view_3.model = generateMonthDaysArray(year,month)
|
||||
list_view_3.currentIndex = list_view_3.model.indexOf(day)
|
||||
text_day.text = day
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.height){
|
||||
popup.y = control.height
|
||||
} else if(pos.y>container.height){
|
||||
popup.y = -container.height
|
||||
} else {
|
||||
popup.y = d.window.height-(pos.y+container.height)
|
||||
}
|
||||
popup.open()
|
||||
}
|
||||
onClosed: {
|
||||
if(d.changeFlag){
|
||||
text_year.text = d.rowData[0]
|
||||
text_month.text = d.rowData[1]
|
||||
text_day.text = d.rowData[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
function generateYearArray(startYear, endYear) {
|
||||
const yearArray = [];
|
||||
for (let year = startYear; year <= endYear; year++) {
|
||||
yearArray.push(year);
|
||||
}
|
||||
return yearArray;
|
||||
}
|
||||
function generateMonthArray(startMonth, endMonth) {
|
||||
const monthArray = [];
|
||||
for (let month = startMonth; month <= endMonth; month++) {
|
||||
monthArray.push(month);
|
||||
}
|
||||
return monthArray;
|
||||
}
|
||||
function generateMonthDaysArray(year, month) {
|
||||
const monthDaysArray = [];
|
||||
const lastDayOfMonth = new Date(year, month, 0).getDate();
|
||||
for (let day = 1; day <= lastDayOfMonth; day++) {
|
||||
monthDaysArray.push(day);
|
||||
}
|
||||
return monthDaysArray;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
id:control
|
||||
property int orientation: Qt.Horizontal
|
||||
property int spacing:0
|
||||
property int size: 1
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isVertical : orientation === Qt.Vertical
|
||||
property int parentHeight: {
|
||||
if(control.parent){
|
||||
return control.parent.height
|
||||
}
|
||||
return control.height
|
||||
}
|
||||
property int parentWidth: {
|
||||
if(control.parent){
|
||||
return control.parent.width
|
||||
}
|
||||
return control.width
|
||||
}
|
||||
}
|
||||
width: d.isVertical ? spacing*2+size : d.parentWidth
|
||||
height: d.isVertical ? d.parentHeight : spacing*2+size
|
||||
FluRectangle{
|
||||
color: FluTheme.dividerColor
|
||||
width: d.isVertical ? size : control.width
|
||||
height: d.isVertical ? control.height : size
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(246/255,246/255,246/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
property var window : Window.window
|
||||
default property alias contentData: menu.contentData
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id: control
|
||||
rightPadding:35
|
||||
enabled: !disabled
|
||||
focusPolicy:Qt.TabFocus
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:8
|
||||
}
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
FluIcon{
|
||||
iconSource:FluentIcons.ChevronDown
|
||||
iconSize: 15
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 10
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
iconColor:title.color
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
id:title
|
||||
text: control.text
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: control.textColor
|
||||
}
|
||||
onClicked: {
|
||||
if(menu.count !==0){
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
var containerHeight = menu.count*36
|
||||
if(window.height>pos.y+control.height+containerHeight){
|
||||
menu.y = control.height
|
||||
}else if(pos.y>containerHeight){
|
||||
menu.y = -containerHeight
|
||||
}else{
|
||||
menu.y = window.height-(pos.y+containerHeight)
|
||||
}
|
||||
menu.open()
|
||||
}
|
||||
}
|
||||
FluMenu{
|
||||
id:menu
|
||||
modal:true
|
||||
width: control.width
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property string headerText: ""
|
||||
property bool expand: false
|
||||
property int contentHeight : 300
|
||||
default property alias content: container.data
|
||||
id:control
|
||||
implicitHeight: Math.max((layout_header.height + layout_container.height),layout_header.height)
|
||||
implicitWidth: 400
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flag: false
|
||||
function toggle(){
|
||||
d.flag = true
|
||||
expand = !expand
|
||||
d.flag = false
|
||||
}
|
||||
}
|
||||
clip: true
|
||||
Rectangle{
|
||||
id:layout_header
|
||||
width: parent.width
|
||||
height: 45
|
||||
radius: 4
|
||||
color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1) : Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
MouseArea{
|
||||
id:control_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
d.toggle()
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text: headerText
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: 15
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 15
|
||||
}
|
||||
color:{
|
||||
if(control_mouse.containsMouse || hovered){
|
||||
return FluTheme.dark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(245/255,245/255,245/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(0,0,0,0) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
onClicked: {
|
||||
d.toggle()
|
||||
}
|
||||
contentItem: FluIcon{
|
||||
rotation: expand?0:180
|
||||
iconSource:FluentIcons.ChevronUp
|
||||
iconSize: 15
|
||||
Behavior on rotation {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:layout_container
|
||||
anchors{
|
||||
top: layout_header.bottom
|
||||
topMargin: -1
|
||||
left: layout_header.left
|
||||
}
|
||||
visible: contentHeight+container.anchors.topMargin !== 0
|
||||
height: contentHeight+container.anchors.topMargin
|
||||
width: parent.width
|
||||
z:-999
|
||||
Rectangle{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
radius: 4
|
||||
clip: true
|
||||
color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
border.color: FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
anchors.topMargin: -contentHeight
|
||||
states: [
|
||||
State{
|
||||
name:"expand"
|
||||
when: control.expand
|
||||
PropertyChanges {
|
||||
target: container
|
||||
anchors.topMargin:0
|
||||
}
|
||||
},
|
||||
State{
|
||||
name:"collapsed"
|
||||
when: !control.expand
|
||||
PropertyChanges {
|
||||
target: container
|
||||
anchors.topMargin:-contentHeight
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
to:"expand"
|
||||
NumberAnimation {
|
||||
properties: "anchors.topMargin"
|
||||
duration: FluTheme.enableAnimation && d.flag ? 167 : 0
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
to:"collapsed"
|
||||
NumberAnimation {
|
||||
properties: "anchors.topMargin"
|
||||
duration: FluTheme.enableAnimation && d.flag ? 167 : 0
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color normalColor: FluTheme.primaryColor
|
||||
property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(173/255,173/255,173/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id: control
|
||||
enabled: !disabled
|
||||
focusPolicy:Qt.TabFocus
|
||||
font:FluTextStyle.Body
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.visualFocus
|
||||
radius:4
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.33; color: control.enabled ? control.normalColor : Qt.rgba(0,0,0,0) }
|
||||
GradientStop { position: 1.0; color: control.enabled ? Qt.darker(control.normalColor,1.3) : Qt.rgba(0,0,0,0) }
|
||||
}
|
||||
Rectangle{
|
||||
radius: parent.radius
|
||||
anchors{
|
||||
fill: parent
|
||||
topMargin: control.enabled ? 0 : 0
|
||||
leftMargin: control.enabled ? 1 : 0
|
||||
rightMargin: control.enabled ? 1 : 0
|
||||
bottomMargin: control.enabled ? 2 : 0
|
||||
}
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
font: control.font
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: control.textColor
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
property bool vertical: false
|
||||
default property alias content : swipe.contentData
|
||||
property alias currentIndex: swipe.currentIndex
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
QtObject{
|
||||
id:d
|
||||
property bool flag: true
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onWheel:
|
||||
(wheel)=>{
|
||||
if(!d.flag)
|
||||
return
|
||||
if (wheel.angleDelta.y > 0){
|
||||
btn_start.clicked()
|
||||
}else{
|
||||
btn_end.clicked()
|
||||
}
|
||||
d.flag = false
|
||||
timer.restart()
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer
|
||||
interval: 250
|
||||
onTriggered: {
|
||||
d.flag = true
|
||||
}
|
||||
}
|
||||
SwipeView {
|
||||
id:swipe
|
||||
clip: true
|
||||
interactive: false
|
||||
orientation:control.vertical ? Qt.Vertical : Qt.Horizontal
|
||||
anchors.fill: parent
|
||||
}
|
||||
Button{
|
||||
id:btn_start
|
||||
height: vertical ? 20 : 40
|
||||
width: vertical ? 40 : 20
|
||||
anchors{
|
||||
left: vertical ? undefined : parent.left
|
||||
leftMargin: vertical ? undefined : 2
|
||||
verticalCenter: vertical ? undefined : parent.verticalCenter
|
||||
horizontalCenter: !vertical ? undefined : parent.horizontalCenter
|
||||
top: !vertical ? undefined :parent.top
|
||||
topMargin: !vertical ? undefined :2
|
||||
}
|
||||
background: Rectangle{
|
||||
radius: 4
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
|
||||
}
|
||||
contentItem:FluIcon{
|
||||
iconSource: vertical ? FluentIcons.CaretUpSolid8 : FluentIcons.CaretLeftSolid8
|
||||
width: 10
|
||||
height: 10
|
||||
iconSize: 10
|
||||
iconColor: btn_start.hovered ? FluColors.Grey220 : FluColors.Grey120
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
visible: swipe.currentIndex !==0
|
||||
onClicked: {
|
||||
swipe.currentIndex = Math.max(swipe.currentIndex - 1, 0)
|
||||
}
|
||||
}
|
||||
Button{
|
||||
id:btn_end
|
||||
height: vertical ? 20 : 40
|
||||
width: vertical ? 40 : 20
|
||||
anchors{
|
||||
right: vertical ? undefined : parent.right
|
||||
rightMargin: vertical ? undefined : 2
|
||||
verticalCenter: vertical ? undefined : parent.verticalCenter
|
||||
horizontalCenter: !vertical ? undefined : parent.horizontalCenter
|
||||
bottom: !vertical ? undefined :parent.bottom
|
||||
bottomMargin: !vertical ? undefined :2
|
||||
}
|
||||
background: Rectangle{
|
||||
radius: 4
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,0.97) : Qt.rgba(237/255,237/255,237/255,0.97)
|
||||
}
|
||||
visible: swipe.currentIndex !== swipe.count - 1
|
||||
contentItem:FluIcon{
|
||||
iconSource: vertical ? FluentIcons.CaretDownSolid8 : FluentIcons.CaretRightSolid8
|
||||
width: 10
|
||||
height: 10
|
||||
iconSize: 10
|
||||
iconColor: btn_end.hovered ? FluColors.Grey220 : FluColors.Grey120
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
onClicked: {
|
||||
swipe.currentIndex = Math.min(swipe.currentIndex + 1,swipe.count-1)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int radius: 4
|
||||
id:control
|
||||
anchors.fill: parent
|
||||
Rectangle{
|
||||
width: control.width
|
||||
height: control.height
|
||||
anchors.centerIn: parent
|
||||
color: "#00000000"
|
||||
border.width: 2
|
||||
radius: control.radius
|
||||
border.color: FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1)
|
||||
z: 65535
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Text {
|
||||
property int iconSource
|
||||
property int iconSize: 20
|
||||
property color iconColor: FluTheme.dark ? "#FFFFFF" : "#000000"
|
||||
id:control
|
||||
font.family: "Segoe Fluent Icons"
|
||||
font.pixelSize: iconSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: iconColor
|
||||
text: (String.fromCharCode(iconSource).toString(16))
|
||||
FontLoader{
|
||||
source: "../Font/Segoe_Fluent_Icons.ttf"
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
display: Button.IconOnly
|
||||
property int iconSize: 20
|
||||
property int iconSource
|
||||
property bool disabled: false
|
||||
property int radius:4
|
||||
property string contentDescription: ""
|
||||
property color hoverColor: FluTheme.itemHoverColor
|
||||
property color pressedColor: FluTheme.itemPressColor
|
||||
property color normalColor: FluTheme.itemNormalColor
|
||||
property color disableColor: FluTheme.itemNormalColor
|
||||
property Component iconDelegate: com_icon
|
||||
property color color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor : normalColor
|
||||
}
|
||||
property color iconColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(130/255,130/255,130/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(161/255,161/255,161/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
property color textColor: FluTheme.fontPrimaryColor
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id:control
|
||||
focusPolicy:Qt.TabFocus
|
||||
padding: 0
|
||||
verticalPadding: 8
|
||||
horizontalPadding: 8
|
||||
enabled: !disabled
|
||||
font:FluTextStyle.Caption
|
||||
background: Rectangle{
|
||||
implicitWidth: 30
|
||||
implicitHeight: 30
|
||||
radius: control.radius
|
||||
color:control.color
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_icon
|
||||
FluIcon {
|
||||
id:text_icon
|
||||
font.pixelSize: iconSize
|
||||
iconSize: control.iconSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
iconColor: control.iconColor
|
||||
iconSource: control.iconSource
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_row
|
||||
RowLayout{
|
||||
FluLoader{
|
||||
sourceComponent: iconDelegate
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.TextOnly
|
||||
}
|
||||
FluText{
|
||||
text:control.text
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.IconOnly
|
||||
color: control.textColor
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_column
|
||||
ColumnLayout{
|
||||
FluLoader{
|
||||
sourceComponent: iconDelegate
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.TextOnly
|
||||
}
|
||||
FluText{
|
||||
text:control.text
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
visible: display !== Button.IconOnly
|
||||
color: control.textColor
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem:FluLoader{
|
||||
sourceComponent: {
|
||||
if(display === Button.TextUnderIcon){
|
||||
return com_column
|
||||
}
|
||||
return com_row
|
||||
}
|
||||
}
|
||||
FluTooltip{
|
||||
id:tool_tip
|
||||
visible: {
|
||||
if(control.text === ""){
|
||||
return false
|
||||
}
|
||||
if(control.display !== Button.IconOnly){
|
||||
return false
|
||||
}
|
||||
return hovered
|
||||
}
|
||||
text:control.text
|
||||
delay: 1000
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Image {
|
||||
property string errorButtonText: qsTr("Reload")
|
||||
property var clickErrorListener : function(){
|
||||
image.source = ""
|
||||
image.source = control.source
|
||||
}
|
||||
property Component errorItem : com_error
|
||||
property Component loadingItem: com_loading
|
||||
id: control
|
||||
FluLoader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(control.status === Image.Loading){
|
||||
return com_loading
|
||||
}else if(control.status == Image.Error){
|
||||
return com_error
|
||||
}else{
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_loading
|
||||
Rectangle{
|
||||
color: FluTheme.itemHoverColor
|
||||
FluProgressRing{
|
||||
anchors.centerIn: parent
|
||||
visible: control.status === Image.Loading
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_error
|
||||
Rectangle{
|
||||
color: FluTheme.itemHoverColor
|
||||
FluFilledButton{
|
||||
text: control.errorButtonText
|
||||
anchors.centerIn: parent
|
||||
visible: control.status === Image.Error
|
||||
onClicked: clickErrorListener()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Button{
|
||||
id:control
|
||||
property string normalImage: ""
|
||||
property string hoveredImage: ""
|
||||
property string pushedImage: ""
|
||||
background: Item{
|
||||
implicitHeight: 12
|
||||
implicitWidth: 12
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
source: control.hovered ? (control.pressed ? control.pushedImage : control.hoveredImage ) : control.normalImage
|
||||
}
|
||||
}
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluObject {
|
||||
property var root;
|
||||
property int layoutY: 75
|
||||
id:control
|
||||
FluObject{
|
||||
id:mcontrol
|
||||
property string const_success: "success";
|
||||
property string const_info: "info";
|
||||
property string const_warning: "warning";
|
||||
property string const_error: "error";
|
||||
property int maxWidth: 300;
|
||||
property var screenLayout: null;
|
||||
function create(type,text,duration,moremsg){
|
||||
if(screenLayout){
|
||||
var last = screenLayout.getLastloader();
|
||||
if(last.type === type && last.text === text && moremsg === last.moremsg){
|
||||
last.restart();
|
||||
return;
|
||||
}
|
||||
}
|
||||
initScreenLayout();
|
||||
contentComponent.createObject(screenLayout,{
|
||||
type:type,
|
||||
text:text,
|
||||
duration:duration,
|
||||
moremsg:moremsg,
|
||||
});
|
||||
}
|
||||
function createCustom(itemcomponent,duration){
|
||||
initScreenLayout();
|
||||
if(itemcomponent){
|
||||
contentComponent.createObject(screenLayout,{itemcomponent:itemcomponent,duration:duration});
|
||||
}
|
||||
}
|
||||
function initScreenLayout(){
|
||||
if(screenLayout == null){
|
||||
screenLayout = screenlayoutComponent.createObject(root);
|
||||
screenLayout.y = control.layoutY;
|
||||
screenLayout.z = 100000;
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:screenlayoutComponent
|
||||
Column{
|
||||
parent: Overlay.overlay
|
||||
z:999
|
||||
spacing: 20
|
||||
width: root.width
|
||||
move: Transition {
|
||||
NumberAnimation {
|
||||
properties: "y"
|
||||
easing.type: Easing.OutCubic
|
||||
duration: FluTheme.enableAnimation ? 333 : 0
|
||||
}
|
||||
}
|
||||
onChildrenChanged: if(children.length === 0) destroy();
|
||||
function getLastloader(){
|
||||
if(children.length > 0){
|
||||
return children[children.length - 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:contentComponent
|
||||
Item{
|
||||
id:content;
|
||||
property int duration: 1500
|
||||
property var itemcomponent
|
||||
property string type
|
||||
property string text
|
||||
property string moremsg
|
||||
width: parent.width;
|
||||
height: loader.height;
|
||||
function close(){
|
||||
content.destroy();
|
||||
}
|
||||
function restart(){
|
||||
delayTimer.restart();
|
||||
}
|
||||
Timer {
|
||||
id:delayTimer
|
||||
interval: duration; running: duration > 0; repeat: duration > 0
|
||||
onTriggered: content.close();
|
||||
}
|
||||
FluLoader{
|
||||
id:loader;
|
||||
x:(parent.width - width) / 2;
|
||||
property var _super: content;
|
||||
scale: item ? 1 : 0;
|
||||
asynchronous: true
|
||||
Behavior on scale {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation {
|
||||
easing.type: Easing.OutCubic
|
||||
duration: 167
|
||||
}
|
||||
}
|
||||
sourceComponent:itemcomponent ? itemcomponent : mcontrol.fluent_sytle;
|
||||
}
|
||||
}
|
||||
}
|
||||
property Component fluent_sytle: Rectangle{
|
||||
width: rowlayout.width + (btn_close.visible ? 30 : 48);
|
||||
height: rowlayout.height + 20;
|
||||
color: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(57/255,61/255,27/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(67/255,53/255,25/255,1);
|
||||
case mcontrol.const_info: return Qt.rgba(39/255,39/255,39/255,1);
|
||||
case mcontrol.const_error: return Qt.rgba(68/255,39/255,38/255,1);
|
||||
}
|
||||
return Qt.rgba(255,255,255,1)
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#dff6dd";
|
||||
case mcontrol.const_warning: return "#fff4ce";
|
||||
case mcontrol.const_info: return "#f4f4f4";
|
||||
case mcontrol.const_error: return "#fde7e9";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(56/255,61/255,27/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(66/255,53/255,25/255,1);
|
||||
case mcontrol.const_info: return Qt.rgba(38/255,39/255,39/255,1);
|
||||
case mcontrol.const_error: return Qt.rgba(67/255,39/255,38/255,1);
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#d2e8d0";
|
||||
case mcontrol.const_warning: return "#f0e6c2";
|
||||
case mcontrol.const_info: return "#e6e6e6";
|
||||
case mcontrol.const_error: return "#eed9db";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:rowlayout
|
||||
x:20;
|
||||
y:(parent.height - height) / 2;
|
||||
spacing: 10
|
||||
FluIcon{
|
||||
iconSource:{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return FluentIcons.CompletedSolid;
|
||||
case mcontrol.const_warning: return FluentIcons.InfoSolid;
|
||||
case mcontrol.const_info: return FluentIcons.InfoSolid;
|
||||
case mcontrol.const_error: return FluentIcons.StatusErrorFull;
|
||||
}FluentIcons.StatusErrorFull
|
||||
return FluentIcons.FA_info_circle
|
||||
}
|
||||
iconSize:20
|
||||
iconColor: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1);
|
||||
case mcontrol.const_info: return FluTheme.primaryColor;
|
||||
case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1);
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#0f7b0f";
|
||||
case mcontrol.const_warning: return "#9d5d00";
|
||||
case mcontrol.const_info: return "#0066b4";
|
||||
case mcontrol.const_error: return "#c42b1c";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
spacing: 5
|
||||
FluText{
|
||||
text:_super.text
|
||||
wrapMode: Text.WrapAnywhere
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
FluText{
|
||||
text: _super.moremsg
|
||||
visible: _super.moremsg
|
||||
wrapMode : Text.WrapAnywhere
|
||||
textColor: FluColors.Grey120
|
||||
width: Math.min(implicitWidth,mcontrol.maxWidth)
|
||||
}
|
||||
}
|
||||
|
||||
FluIconButton{
|
||||
id:btn_close
|
||||
iconSource: FluentIcons.ChromeClose
|
||||
iconSize: 10
|
||||
y:5
|
||||
visible: _super.duration<=0
|
||||
iconColor: {
|
||||
if(FluTheme.dark){
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return Qt.rgba(108/255,203/255,95/255,1);
|
||||
case mcontrol.const_warning: return Qt.rgba(252/255,225/255,0/255,1);
|
||||
case mcontrol.const_info: return FluTheme.primaryColor;
|
||||
case mcontrol.const_error: return Qt.rgba(255/255,153/255,164/255,1);
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}else{
|
||||
switch(_super.type){
|
||||
case mcontrol.const_success: return "#0f7b0f";
|
||||
case mcontrol.const_warning: return "#9d5d00";
|
||||
case mcontrol.const_info: return "#0066b4";
|
||||
case mcontrol.const_error: return "#c42b1c";
|
||||
}
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
onClicked: _super.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function showSuccess(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_success,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showInfo(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_info,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showWarning(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_warning,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showError(text,duration=1000,moremsg){
|
||||
mcontrol.create(mcontrol.const_error,text,duration,moremsg ? moremsg : "");
|
||||
}
|
||||
function showCustom(itemcomponent,duration=1000){
|
||||
mcontrol.createCustom(itemcomponent,duration);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.ItemDelegate {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
padding: 0
|
||||
verticalPadding: 8
|
||||
horizontalPadding: 10
|
||||
icon.color: control.palette.text
|
||||
contentItem:FluText {
|
||||
text: control.text
|
||||
font: control.font
|
||||
color:{
|
||||
if(control.down){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 30
|
||||
color:{
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(1,1,1,0.05)
|
||||
}else{
|
||||
return Qt.rgba(0,0,0,0.05)
|
||||
}
|
||||
}
|
||||
visible: control.down || control.highlighted || control.visualFocus
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import QtQuick
|
||||
|
||||
Loader {
|
||||
Component.onDestruction: sourceComponent = undefined
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
FluButton {
|
||||
property bool loading: false
|
||||
id: control
|
||||
disabled: loading
|
||||
contentItem: Row{
|
||||
spacing: 6
|
||||
FluText {
|
||||
text: control.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Item{
|
||||
width: control.loading ? 16 : 0
|
||||
height: 16
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: Number(width)!==0
|
||||
clip: true
|
||||
Behavior on width {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
FluProgressRing{
|
||||
width: 16
|
||||
height: 16
|
||||
strokeWidth:3
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.Menu {
|
||||
property bool enableAnimation: true
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
contentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
contentHeight + topPadding + bottomPadding)
|
||||
margins: 0
|
||||
overlap: 1
|
||||
spacing: 0
|
||||
delegate: FluMenuItem { }
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation && control.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation && control.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
contentItem: ListView {
|
||||
implicitHeight: contentHeight
|
||||
model: control.contentModel
|
||||
interactive: Window.window
|
||||
? contentHeight + control.topPadding + control.bottomPadding > Window.window.height
|
||||
: false
|
||||
clip: true
|
||||
currentIndex: control.currentIndex
|
||||
ScrollIndicator.vertical: ScrollIndicator {}
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
implicitHeight: 36
|
||||
color:FluTheme.dark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
border.color: FluTheme.dark ? Window.active ? Qt.rgba(55/255,55/255,55/255,1):Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(226/255,229/255,234/255,1)
|
||||
border.width: 1
|
||||
radius: 5
|
||||
FluShadow{}
|
||||
}
|
||||
T.Overlay.modal: Rectangle {
|
||||
color: Color.transparent(control.palette.shadow, 0.5)
|
||||
}
|
||||
T.Overlay.modeless: Rectangle {
|
||||
color: Color.transparent(control.palette.shadow, 0.12)
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Templates as T
|
||||
import QtQuick.Controls.impl
|
||||
|
||||
T.MenuBar {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
contentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
contentHeight + topPadding + bottomPadding)
|
||||
delegate: FluMenuBarItem { }
|
||||
contentItem: Row {
|
||||
spacing: control.spacing
|
||||
Repeater {
|
||||
model: control.contentModel
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
implicitHeight: 30
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Templates as T
|
||||
import QtQuick.Controls.impl
|
||||
import FluentUI
|
||||
|
||||
T.MenuBarItem {
|
||||
property bool disabled: false
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(disabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(disabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
id: control
|
||||
enabled: !disabled
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
spacing: 6
|
||||
padding: 6
|
||||
leftPadding: 12
|
||||
rightPadding: 16
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: control.palette.buttonText
|
||||
contentItem: FluText {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: control.text
|
||||
color:control.textColor
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 30
|
||||
implicitHeight: 30
|
||||
radius: 3
|
||||
color: {
|
||||
if(control.highlighted){
|
||||
return FluTheme.itemCheckColor
|
||||
}
|
||||
if(control.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluTheme.itemNormalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.MenuItem {
|
||||
property Component iconDelegate : com_icon
|
||||
property int iconSpacing: 5
|
||||
property int iconSource
|
||||
property int iconSize: 16
|
||||
property color textColor: {
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
padding: 6
|
||||
spacing: 6
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: control.palette.windowText
|
||||
height: visible ? implicitHeight : 0
|
||||
font:FluTextStyle.Body
|
||||
Component{
|
||||
id:com_icon
|
||||
FluIcon{
|
||||
id:content_icon
|
||||
iconSize: control.iconSize
|
||||
iconSource:control.iconSource
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
Row{
|
||||
spacing: control.iconSpacing
|
||||
readonly property real arrowPadding: control.subMenu && control.arrow ? control.arrow.width + control.spacing : 0
|
||||
readonly property real indicatorPadding: control.checkable && control.indicator ? control.indicator.width + control.spacing : 0
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: (!control.mirrored ? indicatorPadding : arrowPadding)+5
|
||||
right: parent.right
|
||||
rightMargin: (control.mirrored ? indicatorPadding : arrowPadding)+5
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_icon
|
||||
sourceComponent: iconDelegate
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: status === Loader.Ready
|
||||
}
|
||||
FluText {
|
||||
id:content_text
|
||||
text: control.text
|
||||
font: control.font
|
||||
color: control.textColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
indicator: FluIcon {
|
||||
x: control.mirrored ? control.width - width - control.rightPadding : control.leftPadding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
visible: control.checked
|
||||
iconSource: FluentIcons.CheckMark
|
||||
}
|
||||
arrow: FluIcon {
|
||||
x: control.mirrored ? control.leftPadding : control.width - width - control.rightPadding
|
||||
y: control.topPadding + (control.availableHeight - height) / 2
|
||||
visible: control.subMenu
|
||||
iconSource: FluentIcons.ChevronRightMed
|
||||
}
|
||||
background: Item {
|
||||
implicitWidth: 150
|
||||
implicitHeight: 36
|
||||
x: 1
|
||||
y: 1
|
||||
width: control.width - 2
|
||||
height: control.height - 2
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 3
|
||||
radius: 4
|
||||
color:{
|
||||
if(control.highlighted){
|
||||
return FluTheme.itemCheckColor
|
||||
}
|
||||
return FluTheme.itemNormalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.MenuSeparator {
|
||||
id: control
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
padding: 0
|
||||
verticalPadding: 0
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: 188
|
||||
implicitHeight: 1
|
||||
color: FluTheme.dark ? Qt.rgba(60/255,60/255,60/255,1) : Qt.rgba(210/255,210/255,210/255,1)
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextArea{
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property bool isCtrlEnterForNewline: false
|
||||
id:control
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
padding: 8
|
||||
leftPadding: padding+4
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectedTextColor: color
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
placeholderTextColor: {
|
||||
if(!enabled){
|
||||
return placeholderDisableColor
|
||||
}
|
||||
if(focus){
|
||||
return placeholderFocusColor
|
||||
}
|
||||
return placeholderNormalColor
|
||||
}
|
||||
selectByMouse: true
|
||||
width: 240
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: control
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> d.handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> d.handleCommit(event)
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
if(isCtrlEnterForNewline){
|
||||
if(event.modifiers & Qt.ControlModifier){
|
||||
insert(control.cursorPosition, "\n")
|
||||
return
|
||||
}
|
||||
control.commit(control.text)
|
||||
}else{
|
||||
if(event.modifiers & Qt.ControlModifier){
|
||||
control.commit(control.text)
|
||||
return
|
||||
}
|
||||
insert(control.cursorPosition, "\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: {
|
||||
if(control.echoMode === TextInput.Password){
|
||||
return
|
||||
}
|
||||
if(control.readOnly && control.text === ""){
|
||||
return
|
||||
}
|
||||
menu.popup()
|
||||
}
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
default property list<QtObject> children
|
||||
id:control
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int launchMode: FluPageType.SingleTop
|
||||
property bool animDisabled: false
|
||||
property string url : ""
|
||||
signal animationEnd()
|
||||
id: control
|
||||
opacity: visible
|
||||
visible: false
|
||||
StackView.onRemoved: destroy()
|
||||
Behavior on opacity{
|
||||
enabled: !animDisabled && FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
}
|
||||
}
|
||||
transform: Translate {
|
||||
y: control.visible ? 0 : 80
|
||||
Behavior on y{
|
||||
enabled: !animDisabled && FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
visible = true
|
||||
timer.restart()
|
||||
}
|
||||
Timer{
|
||||
id:timer
|
||||
interval: !animDisabled && FluTheme.enableAnimation ? 200 : 0
|
||||
onTriggered: {
|
||||
control.animationEnd()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
signal requestPage(int page,int count)
|
||||
property string previousText: qsTr("<Previous")
|
||||
property string nextText: qsTr("Next>")
|
||||
property int pageCurrent: 0
|
||||
property int itemCount: 0
|
||||
property int pageButtonCount: 5
|
||||
property int pageCount: itemCount>0?Math.ceil(itemCount/__itemPerPage):0
|
||||
property int __itemPerPage: 10
|
||||
property int __pageButtonHalf: Math.floor(pageButtonCount/2)+1
|
||||
id: control
|
||||
implicitHeight: 40
|
||||
implicitWidth: content.width
|
||||
Row{
|
||||
id: content
|
||||
height: control.height
|
||||
spacing: 10
|
||||
padding: 10
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent<=1
|
||||
text:control.previousText
|
||||
clickListener:function() {
|
||||
control.calcNewPage(control.pageCurrent-1);
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing: 5
|
||||
FluToggleButton{
|
||||
property int pageNumber:1
|
||||
visible: control.pageCount>0
|
||||
checked: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
clickListener:function() {
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: (control.pageCount>control.pageButtonCount&&
|
||||
control.pageCurrent>control.__pageButtonHalf)
|
||||
text: "..."
|
||||
}
|
||||
Repeater{
|
||||
id: button_repeator
|
||||
model: (control.pageCount<2)?0:(control.pageCount>=control.pageButtonCount)?(control.pageButtonCount-2):(control.pageCount-2)
|
||||
delegate:FluToggleButton{
|
||||
property int pageNumber: {
|
||||
return (control.pageCurrent<=control.__pageButtonHalf)
|
||||
?(2+index)
|
||||
:(control.pageCount-control.pageCurrent<=control.pageButtonCount-control.__pageButtonHalf)
|
||||
?(control.pageCount-button_repeator.count+index)
|
||||
:(control.pageCurrent+2+index-control.__pageButtonHalf)
|
||||
}
|
||||
text:String(pageNumber)
|
||||
checked: pageNumber === control.pageCurrent
|
||||
clickListener:function(){
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
visible: (control.pageCount>control.pageButtonCount&&
|
||||
control.pageCount-control.pageCurrent>control.pageButtonCount-control.__pageButtonHalf)
|
||||
text: "..."
|
||||
}
|
||||
FluToggleButton{
|
||||
property int pageNumber:control.pageCount
|
||||
visible: control.pageCount>1
|
||||
checked: pageNumber === control.pageCurrent
|
||||
text:String(pageNumber)
|
||||
clickListener:function(){
|
||||
control.calcNewPage(pageNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
FluToggleButton{
|
||||
visible: control.pageCount>1
|
||||
disabled: control.pageCurrent>=control.pageCount
|
||||
text:control.nextText
|
||||
clickListener:function() {
|
||||
control.calcNewPage(control.pageCurrent+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
function calcNewPage(page)
|
||||
{
|
||||
if(!page)
|
||||
return
|
||||
let page_num=Number(page)
|
||||
if(page_num<1||page_num>control.pageCount||page_num===control.pageCurrent)
|
||||
return
|
||||
control.pageCurrent=page_num
|
||||
control.requestPage(page_num,control.__itemPerPage)
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property var _ext
|
||||
property var _parent
|
||||
property bool visible: true
|
||||
property string title
|
||||
property var url
|
||||
property bool disabled: false
|
||||
property int icon
|
||||
property bool iconVisible: true
|
||||
property Component infoBadge
|
||||
property int count: 0
|
||||
property var onTapListener
|
||||
property Component iconDelegate
|
||||
property Component menuDelegate
|
||||
property Component editDelegate
|
||||
property var extra
|
||||
property bool showEdit
|
||||
signal tap
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property var _ext
|
||||
property var _parent
|
||||
property bool visible: true
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property bool visible: true
|
||||
property string title
|
||||
property var icon
|
||||
property bool disabled: false
|
||||
property bool iconVisible: true
|
||||
property bool isExpand: false
|
||||
property bool showEdit
|
||||
property Component iconDelegate
|
||||
property Component menuDelegate
|
||||
property Component editDelegate
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property bool visible: true
|
||||
property string title
|
||||
property var parent
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
readonly property string key : FluTools.uuid()
|
||||
property int _idx
|
||||
property bool visible: true
|
||||
property var parent
|
||||
property real spacing
|
||||
property int size:1
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextField{
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property int iconSource: 0
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
id:control
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
padding: 7
|
||||
rightPadding: 40
|
||||
leftPadding: padding+4
|
||||
echoMode:btn_reveal.pressed ? TextField.Normal : TextField.Password
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
selectedTextColor: color
|
||||
placeholderTextColor: {
|
||||
if(!enabled){
|
||||
return placeholderDisableColor
|
||||
}
|
||||
if(focus){
|
||||
return placeholderFocusColor
|
||||
}
|
||||
return placeholderNormalColor
|
||||
}
|
||||
selectByMouse: true
|
||||
width: 240
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: control
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> d.handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> d.handleCommit(event)
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
control.commit(control.text)
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_reveal
|
||||
iconSource:FluentIcons.RevealPasswordMedium
|
||||
iconSize: 10
|
||||
width: 30
|
||||
height: 20
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconColor: FluTheme.dark ? Qt.rgba(222/255,222/255,222/255,1) : Qt.rgba(97/255,97/255,97/255,1)
|
||||
visible: control.text !== ""
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
}
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Page {
|
||||
default property alias content: d.children
|
||||
property alias currentIndex: nav_list.currentIndex
|
||||
property color textNormalColor: FluTheme.dark ? FluColors.Grey120 : FluColors.Grey120
|
||||
property color textHoverColor: FluTheme.dark ? FluColors.Grey10 : FluColors.Black
|
||||
property int textSize: 28
|
||||
property bool textBold: true
|
||||
property int textSpacing: 10
|
||||
property int headerSpacing: 20
|
||||
property int headerHeight: 40
|
||||
id:control
|
||||
width: 400
|
||||
height: 300
|
||||
implicitHeight: height
|
||||
implicitWidth: width
|
||||
FluObject{
|
||||
id:d
|
||||
property int tabY: control.headerHeight/2+control.textSize/2 + 3
|
||||
}
|
||||
background:Item{}
|
||||
header:ListView{
|
||||
id:nav_list
|
||||
implicitHeight: control.headerHeight
|
||||
implicitWidth: control.width
|
||||
model:d.children
|
||||
spacing: control.headerSpacing
|
||||
interactive: false
|
||||
orientation: ListView.Horizontal
|
||||
highlightMoveDuration: FluTheme.enableAnimation ? 167 : 0
|
||||
highlight: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
height: 3
|
||||
radius: 1.5
|
||||
color: FluTheme.primaryColor
|
||||
width: nav_list.currentItem ? nav_list.currentItem.width : 0
|
||||
y:d.tabY
|
||||
Behavior on width {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: Button{
|
||||
id:item_button
|
||||
width: item_title.width
|
||||
height: nav_list.height
|
||||
focusPolicy:Qt.TabFocus
|
||||
background:Item{
|
||||
FluFocusRectangle{
|
||||
anchors.margins: -4
|
||||
visible: item_button.activeFocus
|
||||
radius:4
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
FluText {
|
||||
id:item_title
|
||||
text: modelData.title
|
||||
anchors.centerIn: parent
|
||||
font.pixelSize: control.textSize
|
||||
font.bold: control.textBold
|
||||
color: {
|
||||
if(item_button.hovered || nav_list.currentIndex === index)
|
||||
return textHoverColor
|
||||
return textNormalColor
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
nav_list.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
Repeater{
|
||||
model:d.children
|
||||
FluLoader{
|
||||
property var argument: modelData.argument
|
||||
anchors.fill: parent
|
||||
sourceComponent: modelData.contentItem
|
||||
visible: nav_list.currentIndex === index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
QtObject {
|
||||
property string title
|
||||
property Component contentItem
|
||||
property var argument
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Popup {
|
||||
id: control
|
||||
padding: 0
|
||||
modal:true
|
||||
parent: Overlay.overlay
|
||||
x: Math.round((d.parentWidth - width) / 2)
|
||||
y: Math.round((d.parentHeight - height) / 2)
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
from:0
|
||||
to:1
|
||||
}
|
||||
}
|
||||
height:Math.min(implicitHeight,d.parentHeight)
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
from:1
|
||||
to:0
|
||||
}
|
||||
}
|
||||
background: FluRectangle{
|
||||
radius: [5,5,5,5]
|
||||
color: FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(1,1,1,1)
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property int parentHeight: {
|
||||
if(control.parent){
|
||||
return control.parent.height
|
||||
}
|
||||
return control.height
|
||||
}
|
||||
property int parentWidth: {
|
||||
if(control.parent){
|
||||
return control.parent.width
|
||||
}
|
||||
return control.width
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
ProgressBar{
|
||||
property int duration: 888
|
||||
property real strokeWidth: 6
|
||||
property bool progressVisible: false
|
||||
property color color: FluTheme.primaryColor
|
||||
property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
|
||||
id:control
|
||||
indeterminate : true
|
||||
QtObject{
|
||||
id:d
|
||||
property real _radius: strokeWidth/2
|
||||
}
|
||||
onIndeterminateChanged:{
|
||||
if(!indeterminate){
|
||||
animator_x.duration = 0
|
||||
rect_progress.x = 0
|
||||
animator_x.duration = control.duration
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
implicitHeight: control.strokeWidth
|
||||
color: control.backgroundColor
|
||||
radius: d._radius
|
||||
}
|
||||
contentItem: FluClip {
|
||||
clip: true
|
||||
radius: [d._radius,d._radius,d._radius,d._radius]
|
||||
Rectangle {
|
||||
id:rect_progress
|
||||
width: {
|
||||
if(control.indeterminate){
|
||||
return 0.5 * parent.width
|
||||
}
|
||||
return control.visualPosition * parent.width
|
||||
}
|
||||
height: parent.height
|
||||
radius: d._radius
|
||||
color: control.color
|
||||
PropertyAnimation on x {
|
||||
id:animator_x
|
||||
running: control.indeterminate && control.visible
|
||||
from: -rect_progress.width
|
||||
to:control.width+rect_progress.width
|
||||
loops: Animation.Infinite
|
||||
duration: control.duration
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:(control.visualPosition * 100).toFixed(0) + "%"
|
||||
visible: {
|
||||
if(control.indeterminate){
|
||||
return false
|
||||
}
|
||||
return control.progressVisible
|
||||
}
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: control.width+5
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property real progress
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
QtObject{
|
||||
id:d
|
||||
property bool checked: (rect_back.height === background.height) && (progress === 1)
|
||||
}
|
||||
property color normalColor: {
|
||||
if(d.checked){
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
}
|
||||
}
|
||||
property color hoverColor: {
|
||||
if(d.checked){
|
||||
return FluTheme.dark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1)
|
||||
}else{
|
||||
return FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(246/255,246/255,246/255,1)
|
||||
}
|
||||
}
|
||||
property color disableColor: {
|
||||
if(d.checked){
|
||||
return FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
}else{
|
||||
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
}
|
||||
}
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
focusPolicy:Qt.TabFocus
|
||||
id: control
|
||||
enabled: !disabled
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
background: FluClip{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
radius: [4,4,4,4]
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: d.checked ? 0 : 1
|
||||
radius: 4
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(d.checked){
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_back
|
||||
width: parent.width * control.progress
|
||||
height: control.progress === 1 ? background.height : 3
|
||||
visible: !d.checked
|
||||
color: FluTheme.primaryColor
|
||||
anchors.bottom: parent.bottom
|
||||
Behavior on height{
|
||||
enabled: control.progress !== 0
|
||||
SequentialAnimation {
|
||||
PauseAnimation {
|
||||
duration: FluTheme.enableAnimation ? 167 : 0
|
||||
}
|
||||
NumberAnimation{
|
||||
duration: FluTheme.enableAnimation ? 167 : 0
|
||||
from: 3
|
||||
to: background.height
|
||||
}
|
||||
}
|
||||
}
|
||||
Behavior on width{
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
}
|
||||
}
|
||||
}
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:4
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: {
|
||||
if(d.checked){
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(173/255,173/255,173/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}else{
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(!d.checked){
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(!d.checked){
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
ProgressBar{
|
||||
property int duration: 2000
|
||||
property real strokeWidth: 6
|
||||
property bool progressVisible: false
|
||||
property color color: FluTheme.primaryColor
|
||||
property color backgroundColor : FluTheme.dark ? Qt.rgba(99/255,99/255,99/255,1) : Qt.rgba(214/255,214/255,214/255,1)
|
||||
id:control
|
||||
indeterminate : true
|
||||
clip: true
|
||||
background: Rectangle {
|
||||
implicitWidth: 56
|
||||
implicitHeight: 56
|
||||
radius: control.width/2
|
||||
color:"transparent"
|
||||
border.color: control.backgroundColor
|
||||
border.width: control.strokeWidth
|
||||
}
|
||||
onIndeterminateChanged:{
|
||||
canvas.requestPaint()
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property real _radius: control.width/2-control.strokeWidth/2
|
||||
property real _progress: control.indeterminate ? 0.0 : control.visualPosition
|
||||
on_ProgressChanged: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: FluTheme
|
||||
function onDarkChanged(){
|
||||
canvas.requestPaint()
|
||||
}
|
||||
}
|
||||
contentItem: Item {
|
||||
id:layout_item
|
||||
Canvas {
|
||||
id:canvas
|
||||
anchors.fill: parent
|
||||
antialiasing: true
|
||||
renderTarget: Canvas.Image
|
||||
property real startAngle: 0
|
||||
property real sweepAngle: 0
|
||||
SequentialAnimation on startAngle {
|
||||
loops: Animation.Infinite
|
||||
running: control.visible && control.indeterminate
|
||||
PropertyAnimation { from: 0; to: 450; duration: control.duration/2 }
|
||||
PropertyAnimation { from: 450; to: 1080; duration: control.duration/2 }
|
||||
}
|
||||
SequentialAnimation on sweepAngle {
|
||||
loops: Animation.Infinite
|
||||
running: control.visible && control.indeterminate
|
||||
PropertyAnimation { from: 0; to: 180; duration: control.duration/2 }
|
||||
PropertyAnimation { from: 180; to: 0; duration: control.duration/2 }
|
||||
}
|
||||
onStartAngleChanged: {
|
||||
requestPaint()
|
||||
}
|
||||
onPaint: {
|
||||
var ctx = canvas.getContext("2d")
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||||
ctx.save()
|
||||
ctx.lineWidth = control.strokeWidth
|
||||
ctx.strokeStyle = control.color
|
||||
ctx.lineCap = "round"
|
||||
ctx.beginPath()
|
||||
if(control.indeterminate){
|
||||
ctx.arc(width/2, height/2, d._radius , Math.PI * (startAngle - 90) / 180, Math.PI * (startAngle - 90 + sweepAngle) / 180)
|
||||
}else{
|
||||
ctx.arc(width/2, height/2, d._radius , -0.5 * Math.PI , -0.5 * Math.PI + d._progress * 2 * Math.PI)
|
||||
}
|
||||
ctx.stroke()
|
||||
ctx.closePath()
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:(control.visualPosition * 100).toFixed(0) + "%"
|
||||
visible: {
|
||||
if(control.indeterminate){
|
||||
return false
|
||||
}
|
||||
return control.progressVisible
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
property alias text: qrcode.text
|
||||
property alias color: qrcode.color
|
||||
property alias bgColor: qrcode.bgColor
|
||||
property int size: 50
|
||||
property int margins: 0
|
||||
id:control
|
||||
width: size
|
||||
height: size
|
||||
Rectangle{
|
||||
color: bgColor
|
||||
anchors.fill: parent
|
||||
}
|
||||
FluQrCodeItem{
|
||||
id:qrcode
|
||||
size:control.size-margins
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property string contentDescription: ""
|
||||
property bool disabled: false
|
||||
property color borderNormalColor: checked ? FluTheme.primaryColor : FluTheme.dark ? Qt.rgba(161/255,161/255,161/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color borderDisableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(198/255,198/255,198/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1)
|
||||
property color hoverColor: checked ? FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(1,1,1,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)
|
||||
property color disableColor: checked ? FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(159/255,159/255,159/255,1) : FluTheme.dark ? Qt.rgba(43/255,43/255,43/255,1) : Qt.rgba(222/255,222/255,222/255,1)
|
||||
property alias textColor: btn_text.textColor
|
||||
property real size: 18
|
||||
property bool textRight: true
|
||||
property real textSpacing: 6
|
||||
property var clickListener : function(){
|
||||
checked = !checked
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
id:control
|
||||
enabled: !disabled
|
||||
horizontalPadding:2
|
||||
verticalPadding: 2
|
||||
background: Item{
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
focusPolicy:Qt.TabFocus
|
||||
font:FluTextStyle.Body
|
||||
onClicked: clickListener()
|
||||
contentItem: RowLayout{
|
||||
spacing: control.textSpacing
|
||||
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
|
||||
Rectangle{
|
||||
id:rect_check
|
||||
width: control.size
|
||||
height: control.size
|
||||
radius: size/2
|
||||
border.width: {
|
||||
if(checked&&!enabled){
|
||||
return 3
|
||||
}
|
||||
if(pressed){
|
||||
if(checked){
|
||||
return 4
|
||||
}
|
||||
return 1
|
||||
}
|
||||
if(hovered){
|
||||
if(checked){
|
||||
return 3
|
||||
}
|
||||
return 1
|
||||
}
|
||||
return checked ? 4 : 1
|
||||
}
|
||||
Behavior on border.width {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
border.color: {
|
||||
if(!enabled){
|
||||
return borderDisableColor
|
||||
}
|
||||
return borderNormalColor
|
||||
}
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(hovered){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
id:btn_text
|
||||
text: control.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font: control.font
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
ColumnLayout {
|
||||
default property alias buttons: control.data
|
||||
property int currentIndex : -1
|
||||
id:control
|
||||
onCurrentIndexChanged: {
|
||||
for(var i = 0;i<buttons.length;i++){
|
||||
buttons[i].checked = false
|
||||
}
|
||||
var button = buttons[currentIndex]
|
||||
if(button){
|
||||
button.checked = true
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
for(var i = 0;i<buttons.length;i++){
|
||||
buttons[i].clickListener = function(){
|
||||
for(var i = 0;i<buttons.length;i++){
|
||||
var button = buttons[i]
|
||||
if(this === button){
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentIndex = 0
|
||||
}
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.RangeSlider {
|
||||
id: control
|
||||
property bool tooltipEnabled: true
|
||||
property bool isTipInt: true
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
first.implicitHandleWidth + leftPadding + rightPadding,
|
||||
second.implicitHandleWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
first.implicitHandleHeight + topPadding + bottomPadding,
|
||||
second.implicitHandleHeight + topPadding + bottomPadding)
|
||||
padding: 6
|
||||
first.value: 0
|
||||
second.value: 100
|
||||
stepSize: 1
|
||||
from: 0
|
||||
to:100
|
||||
snapMode: RangeSlider.SnapAlways
|
||||
first.handle: Rectangle {
|
||||
x: control.leftPadding + (control.horizontal ? control.first.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)
|
||||
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.first.visualPosition * (control.availableHeight - height))
|
||||
implicitWidth: 20
|
||||
implicitHeight: 20
|
||||
radius: width / 2
|
||||
color:FluTheme.dark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
|
||||
FluShadow{
|
||||
radius: 10
|
||||
}
|
||||
FluIcon{
|
||||
width: 10
|
||||
height: 10
|
||||
iconSource: FluentIcons.FullCircleMask
|
||||
iconSize: 10
|
||||
scale:{
|
||||
if(control.first.pressed){
|
||||
return 0.9
|
||||
}
|
||||
return control.first.hovered ? 1.2 : 1
|
||||
}
|
||||
iconColor: FluTheme.primaryColor
|
||||
anchors.centerIn: parent
|
||||
Behavior on scale{
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
second.handle: Rectangle {
|
||||
x: control.leftPadding + (control.horizontal ? control.second.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)
|
||||
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.second.visualPosition * (control.availableHeight - height))
|
||||
implicitWidth: 20
|
||||
implicitHeight: 20
|
||||
radius: width / 2
|
||||
color:FluTheme.dark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
|
||||
FluShadow{
|
||||
radius: 10
|
||||
}
|
||||
FluIcon{
|
||||
width: 10
|
||||
height: 10
|
||||
iconSource: FluentIcons.FullCircleMask
|
||||
iconSize: 10
|
||||
scale:{
|
||||
if(control.second.pressed){
|
||||
return 0.9
|
||||
}
|
||||
return control.second.hovered ? 1.2 : 1
|
||||
}
|
||||
iconColor: FluTheme.primaryColor
|
||||
anchors.centerIn: parent
|
||||
Behavior on scale{
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2)
|
||||
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0)
|
||||
implicitWidth: control.horizontal ? 180 : 6
|
||||
implicitHeight: control.horizontal ? 6 : 180
|
||||
width: control.horizontal ? control.availableWidth : implicitWidth
|
||||
height: control.horizontal ? implicitHeight : control.availableHeight
|
||||
scale: control.horizontal && control.mirrored ? -1 : 1
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
radius: 2
|
||||
color:FluTheme.dark ? Qt.rgba(162/255,162/255,162/255,1) : Qt.rgba(138/255,138/255,138/255,1)
|
||||
}
|
||||
Rectangle {
|
||||
x: control.horizontal ? control.first.position * parent.width + 3 : 0
|
||||
y: control.horizontal ? 0 : control.second.visualPosition * parent.height + 3
|
||||
width: control.horizontal ? control.second.position * parent.width - control.first.position * parent.width - 6 : 6
|
||||
height: control.horizontal ? 6 : control.second.position * parent.height - control.first.position * parent.height - 6
|
||||
color: FluTheme.primaryColor
|
||||
}
|
||||
}
|
||||
FluTooltip{
|
||||
parent: control.first.handle
|
||||
visible: control.tooltipEnabled && (control.first.pressed || control.first.hovered)
|
||||
text:String(isTipInt?Math.round(control.first.value):control.first.value)
|
||||
}
|
||||
FluTooltip{
|
||||
parent: control.second.handle
|
||||
visible: control.tooltipEnabled && (control.second.pressed || control.second.hovered)
|
||||
text:String(isTipInt?Math.round(control.second.value):control.second.value)
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int number: 5
|
||||
property int spacing: 4
|
||||
property int size: 18
|
||||
property int value:0
|
||||
id:control
|
||||
implicitWidth: container.width
|
||||
implicitHeight: container.height
|
||||
QtObject{
|
||||
id:d
|
||||
property int mouseValue: 0
|
||||
property int itemSize: control.size+spacing*2
|
||||
}
|
||||
Row{
|
||||
id:container
|
||||
spacing: 0
|
||||
Repeater{
|
||||
model:control.number
|
||||
Item{
|
||||
width: d.itemSize
|
||||
height: d.itemSize
|
||||
FluIcon{
|
||||
property bool isSelected : {
|
||||
if(d.mouseValue!==0){
|
||||
return index<d.mouseValue
|
||||
}
|
||||
return index<control.value
|
||||
}
|
||||
iconSize: control.size
|
||||
iconSource: isSelected ? FluentIcons.FavoriteStarFill : FluentIcons.FavoriteStar
|
||||
iconColor: isSelected ? FluTheme.primaryColor : (FluTheme.dark ? "#FFFFFF" : "#000000")
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: container
|
||||
hoverEnabled: true
|
||||
onPositionChanged: (mouse)=>{
|
||||
d.mouseValue = Number(mouse.x / d.itemSize)+1
|
||||
}
|
||||
onExited: {
|
||||
d.mouseValue = 0
|
||||
}
|
||||
onClicked: (mouse)=>{
|
||||
control.value = Number(mouse.x / d.itemSize)+1
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluStatusLayout {
|
||||
property url source: ""
|
||||
property bool lazy: false
|
||||
color:"transparent"
|
||||
id:control
|
||||
onErrorClicked: {
|
||||
reload()
|
||||
}
|
||||
Component.onCompleted: {
|
||||
if(!lazy){
|
||||
loader.source = control.source
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id:loader
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
onStatusChanged: {
|
||||
if(status === Loader.Error){
|
||||
control.statusMode = FluStatusLayoutType.Error
|
||||
}else if(status === Loader.Loading){
|
||||
control.statusMode = FluStatusLayoutType.Loading
|
||||
}else{
|
||||
control.statusMode = FluStatusLayoutType.Success
|
||||
}
|
||||
}
|
||||
}
|
||||
function reload(){
|
||||
var timestamp = Date.now();
|
||||
loader.source = control.source+"?"+timestamp
|
||||
}
|
||||
function itemLodaer(){
|
||||
return loader
|
||||
}
|
||||
}
|
@ -1,187 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.ScrollBar {
|
||||
id: control
|
||||
|
||||
property color color : FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(138/255,138/255,138/255,1)
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(color,1.2) : Qt.lighter(color,1.2)
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
visible: control.policy !== T.ScrollBar.AlwaysOff
|
||||
minimumSize: Math.max(orientation === Qt.Horizontal ? height / width : width / height,0.3)
|
||||
QtObject{
|
||||
id:d
|
||||
property int minLine : 2
|
||||
property int maxLine : 6
|
||||
}
|
||||
z: horizontal? 10 : 20
|
||||
verticalPadding : vertical ? 15 : 3
|
||||
horizontalPadding : horizontal ? 15 : 3
|
||||
background: Rectangle{
|
||||
id:back_rect
|
||||
radius: 5
|
||||
color:FluTheme.dark ? Qt.rgba(44/255,44/255,44/255,1) : Qt.rgba(255/255,255/255,255/255,1)
|
||||
opacity:{
|
||||
if(vertical){
|
||||
return d.maxLine === Number(rect_bar.width)
|
||||
}
|
||||
return d.maxLine === Number(rect_bar.height)
|
||||
}
|
||||
Behavior on opacity {
|
||||
NumberAnimation{
|
||||
duration: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
width: 12
|
||||
height: 12
|
||||
iconSize: 8
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
visible: control.horizontal
|
||||
opacity: back_rect.opacity
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
iconColor: control.color
|
||||
iconSource: FluentIcons.CaretLeftSolid8
|
||||
onClicked: {
|
||||
control.decrease()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
width: 12
|
||||
height: 12
|
||||
iconSize: 8
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconColor: control.color
|
||||
opacity: back_rect.opacity
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
visible: control.horizontal
|
||||
iconSource: FluentIcons.CaretRightSolid8
|
||||
onClicked: {
|
||||
control.increase()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
width: 12
|
||||
height: 12
|
||||
iconSize: 8
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconColor: control.color
|
||||
opacity: back_rect.opacity
|
||||
anchors{
|
||||
top: parent.top
|
||||
topMargin: 2
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
visible: control.vertical
|
||||
iconSource: FluentIcons.CaretUpSolid8
|
||||
onClicked: {
|
||||
control.decrease()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
width: 12
|
||||
height: 12
|
||||
iconSize: 8
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconColor: control.color
|
||||
opacity: back_rect.opacity
|
||||
anchors{
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 2
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
visible: control.vertical
|
||||
iconSource: FluentIcons.CaretDownSolid8
|
||||
onClicked: {
|
||||
control.increase()
|
||||
}
|
||||
}
|
||||
contentItem: Item {
|
||||
property bool collapsed: (control.policy === T.ScrollBar.AlwaysOn || (control.active && control.size < 1.0))
|
||||
implicitWidth: control.interactive ? d.maxLine : d.minLine
|
||||
implicitHeight: control.interactive ? d.maxLine : d.minLine
|
||||
Rectangle{
|
||||
id:rect_bar
|
||||
width: vertical ? d.minLine : parent.width
|
||||
height: horizontal ? d.minLine : parent.height
|
||||
color:{
|
||||
if(control.pressed){
|
||||
return control.pressedColor
|
||||
}
|
||||
return control .color
|
||||
}
|
||||
anchors{
|
||||
right: vertical ? parent.right : undefined
|
||||
bottom: horizontal ? parent.bottom : undefined
|
||||
}
|
||||
radius: width / 2
|
||||
visible: control.size < 1.0
|
||||
}
|
||||
states: [
|
||||
State{
|
||||
name:"show"
|
||||
when: contentItem.collapsed
|
||||
PropertyChanges {
|
||||
target: rect_bar
|
||||
width: vertical ? d.maxLine : parent.width
|
||||
height: horizontal ? d.maxLine : parent.height
|
||||
}
|
||||
}
|
||||
,State{
|
||||
name:"hide"
|
||||
when: !contentItem.collapsed
|
||||
PropertyChanges {
|
||||
target: rect_bar
|
||||
width: vertical ? d.minLine : parent.width
|
||||
height: horizontal ? d.minLine : parent.height
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions:[
|
||||
Transition {
|
||||
to: "hide"
|
||||
SequentialAnimation {
|
||||
PauseAnimation { duration: 450 }
|
||||
NumberAnimation {
|
||||
target: rect_bar
|
||||
properties: vertical ? "width" : "height"
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
,Transition {
|
||||
to: "show"
|
||||
SequentialAnimation {
|
||||
PauseAnimation { duration: 450 }
|
||||
NumberAnimation {
|
||||
target: rect_bar
|
||||
properties: vertical ? "width" : "height"
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
|
||||
T.ScrollIndicator {
|
||||
id: control
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
padding: 2
|
||||
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: 2
|
||||
implicitHeight: 2
|
||||
|
||||
color: control.palette.mid
|
||||
visible: control.size < 1.0
|
||||
opacity: 0.0
|
||||
|
||||
states: State {
|
||||
name: "active"
|
||||
when: control.active
|
||||
PropertyChanges {
|
||||
target: control
|
||||
contentItem.opacity: 0.75
|
||||
}
|
||||
}
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "active"
|
||||
SequentialAnimation {
|
||||
PauseAnimation {
|
||||
duration: 450
|
||||
}
|
||||
NumberAnimation {
|
||||
target: control.contentItem
|
||||
duration: 200
|
||||
property: "opacity"
|
||||
to: 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluPage {
|
||||
property alias title: text_title.text
|
||||
default property alias content: container.data
|
||||
property int spacing : 0
|
||||
property int leftPadding: 10
|
||||
property int topPadding: 0
|
||||
property int rightPadding: 10
|
||||
property int bottomPadding: 10
|
||||
property alias color: status_view.color
|
||||
property alias statusMode: status_view.statusMode
|
||||
property alias loadingText: status_view.loadingText
|
||||
property alias emptyText:status_view.emptyText
|
||||
property alias errorText:status_view.errorText
|
||||
property alias errorButtonText:status_view.errorButtonText
|
||||
property alias loadingItem :status_view.loadingItem
|
||||
property alias emptyItem : status_view.emptyItem
|
||||
property alias errorItem :status_view.errorItem
|
||||
signal errorClicked
|
||||
id:control
|
||||
FluText{
|
||||
id:text_title
|
||||
font: FluTextStyle.Title
|
||||
visible: text !== ""
|
||||
height: visible ? contentHeight : 0
|
||||
padding: 0
|
||||
anchors{
|
||||
top: parent.top
|
||||
topMargin: control.topPadding
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: control.leftPadding
|
||||
rightMargin: control.rightPadding
|
||||
}
|
||||
}
|
||||
FluStatusLayout{
|
||||
id:status_view
|
||||
color: "#00000000"
|
||||
statusMode: FluStatusLayoutType.Success
|
||||
onErrorClicked: control.errorClicked()
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: text_title.bottom
|
||||
bottom: parent.bottom
|
||||
bottomMargin: control.bottomPadding
|
||||
}
|
||||
Flickable{
|
||||
id:flickview
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
contentWidth: parent.width
|
||||
contentHeight: container.height
|
||||
ScrollBar.vertical: FluScrollBar {
|
||||
anchors.right: flickview.right
|
||||
anchors.rightMargin: 2
|
||||
}
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
ColumnLayout{
|
||||
id:container
|
||||
spacing: control.spacing
|
||||
clip: true
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
leftMargin: control.leftPadding
|
||||
rightMargin: control.rightPadding
|
||||
}
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
//高性能阴影!!!比DropShadow阴影性能高出数倍!!!
|
||||
property color color: FluTheme.dark ? "#FFFFFF" : "#999999"
|
||||
property int elevation: 6
|
||||
property int radius: 4
|
||||
id:control
|
||||
anchors.fill: parent
|
||||
Repeater{
|
||||
model: elevation
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color: "#00000000"
|
||||
opacity: 0.01 * (elevation-index+1)
|
||||
anchors.margins: -index
|
||||
radius: control.radius+index
|
||||
border.width: index
|
||||
border.color: control.color
|
||||
}
|
||||
}
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluIconButton {
|
||||
id:control
|
||||
property var current : ["Ctrl","Shift","A"]
|
||||
property string title: qsTr("Activate the Shortcut")
|
||||
property string message: qsTr("Press the key combination to change the shortcut")
|
||||
property string positiveText: qsTr("Save")
|
||||
property string neutralText: qsTr("Cancel")
|
||||
property string negativeText: qsTr("Reset")
|
||||
signal accepted()
|
||||
QtObject{
|
||||
id: d
|
||||
function keyToString(key_code,shift = true)
|
||||
{
|
||||
switch(key_code)
|
||||
{
|
||||
case Qt.Key_Period: return ".";
|
||||
case Qt.Key_Greater: return shift ? ">" : ".";
|
||||
case Qt.Key_Comma: return ",";
|
||||
case Qt.Key_Less: return shift ? "<" : ",";
|
||||
case Qt.Key_Slash: return "/";
|
||||
case Qt.Key_Question: return shift ? "?" : "/";
|
||||
case Qt.Key_Semicolon: return ";";
|
||||
case Qt.Key_Colon: return shift ? ":" : ";";
|
||||
case Qt.Key_Apostrophe: return "'";
|
||||
case Qt.Key_QuoteDbl: return shift ? "'" : "\"";
|
||||
case Qt.Key_QuoteLeft: return "`";
|
||||
case Qt.Key_AsciiTilde: return shift ? "~" : "`";
|
||||
case Qt.Key_Minus: return "-";
|
||||
case Qt.Key_Underscore: return shift ? "_" : "-";
|
||||
case Qt.Key_Equal: return "=";
|
||||
case Qt.Key_Plus: return shift ? "+" : "=";
|
||||
case Qt.Key_BracketLeft: return "[";
|
||||
case Qt.Key_BraceLeft: return shift ? "{" : "[";
|
||||
case Qt.Key_BracketRight: return "]";
|
||||
case Qt.Key_BraceRight: return shift ? "}" : "]";
|
||||
case Qt.Key_Backslash: return "\\";
|
||||
case Qt.Key_Bar: return shift ? "|" : "\\";
|
||||
case Qt.Key_Up: return "Up";
|
||||
case Qt.Key_Down: return "Down";
|
||||
case Qt.Key_Right: return "Right";
|
||||
case Qt.Key_Left: return "Left";
|
||||
case Qt.Key_Space: return "Space";
|
||||
case Qt.Key_PageDown: return "PgDown";
|
||||
case Qt.Key_PageUp: return "PgUp";
|
||||
case Qt.Key_0: return "0";
|
||||
case Qt.Key_1: return "1";
|
||||
case Qt.Key_2: return "2";
|
||||
case Qt.Key_3: return "3";
|
||||
case Qt.Key_4: return "4";
|
||||
case Qt.Key_5: return "5";
|
||||
case Qt.Key_6: return "6";
|
||||
case Qt.Key_7: return "7";
|
||||
case Qt.Key_8: return "8";
|
||||
case Qt.Key_9: return "9";
|
||||
case Qt.Key_Exclam: return shift ? "!" : "1";
|
||||
case Qt.Key_At: return shift ? "@" : "2";
|
||||
case Qt.Key_NumberSign: return shift ? "#" : "3";
|
||||
case Qt.Key_Dollar: return shift ? "$" : "4";
|
||||
case Qt.Key_Percent: return shift ? "%" : "5";
|
||||
case Qt.Key_AsciiCircum: return shift ? "^" : "6";
|
||||
case Qt.Key_Ampersand: return shift ? "&" : "7";
|
||||
case Qt.Key_Asterisk: return shift ? "*" : "8";
|
||||
case Qt.Key_ParenLeft: return shift ? "(" : "9";
|
||||
case Qt.Key_ParenRight: return shift ? ")" : "0";
|
||||
case Qt.Key_A: return "A";
|
||||
case Qt.Key_B: return "B";
|
||||
case Qt.Key_C: return "C";
|
||||
case Qt.Key_D: return "D";
|
||||
case Qt.Key_E: return "E";
|
||||
case Qt.Key_F: return "F";
|
||||
case Qt.Key_G: return "G";
|
||||
case Qt.Key_H: return "H";
|
||||
case Qt.Key_I: return "I";
|
||||
case Qt.Key_J: return "J";
|
||||
case Qt.Key_K: return "K";
|
||||
case Qt.Key_L: return "L";
|
||||
case Qt.Key_M: return "M";
|
||||
case Qt.Key_N: return "N";
|
||||
case Qt.Key_O: return "O";
|
||||
case Qt.Key_P: return "P";
|
||||
case Qt.Key_Q: return "Q";
|
||||
case Qt.Key_R: return "R";
|
||||
case Qt.Key_S: return "S";
|
||||
case Qt.Key_T: return "T";
|
||||
case Qt.Key_U: return "U";
|
||||
case Qt.Key_V: return "V";
|
||||
case Qt.Key_W: return "W";
|
||||
case Qt.Key_X: return "X";
|
||||
case Qt.Key_Y: return "Y";
|
||||
case Qt.Key_Z: return "Z";
|
||||
case Qt.Key_F1: return "F1";
|
||||
case Qt.Key_F2: return "F2";
|
||||
case Qt.Key_F3: return "F3";
|
||||
case Qt.Key_F4: return "F4";
|
||||
case Qt.Key_F5: return "F5";
|
||||
case Qt.Key_F6: return "F6";
|
||||
case Qt.Key_F7: return "F7";
|
||||
case Qt.Key_F8: return "F8";
|
||||
case Qt.Key_F9: return "F9";
|
||||
case Qt.Key_F10: return "F10";
|
||||
case Qt.Key_F11: return "F11";
|
||||
case Qt.Key_F12: return "F12";
|
||||
case Qt.Key_Home: return "Home";
|
||||
case Qt.Key_End: return "End";
|
||||
case Qt.Key_Insert: return "Insert";
|
||||
case Qt.Key_Delete: return "Delete";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
background: Rectangle{
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: 1
|
||||
implicitHeight: 42
|
||||
implicitWidth: layout_row.width+28
|
||||
radius: control.radius
|
||||
color:control.color
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_item_key
|
||||
Rectangle{
|
||||
id:item_key_control
|
||||
color:FluTheme.primaryColor
|
||||
width: Math.max(item_text.implicitWidth+12,28)
|
||||
height: Math.max(item_text.implicitHeight,28)
|
||||
radius: 4
|
||||
Text{
|
||||
id:item_text
|
||||
color: FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
font.pixelSize: 13
|
||||
text: keyText
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
id:layout_row
|
||||
spacing: 5
|
||||
anchors.centerIn: parent
|
||||
Repeater{
|
||||
model: control.current
|
||||
delegate: Loader{
|
||||
property var keyText: modelData
|
||||
sourceComponent: com_item_key
|
||||
}
|
||||
}
|
||||
Item{
|
||||
width: 3
|
||||
height: 1
|
||||
}
|
||||
FluIcon{
|
||||
iconSource: FluentIcons.EditMirrored
|
||||
iconSize: 13
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
FluContentDialog{
|
||||
id:content_dialog
|
||||
property var keysModel: []
|
||||
title: control.title
|
||||
message: control.message
|
||||
buttonFlags: FluContentDialogType.NegativeButton | FluContentDialogType.PositiveButton | FluContentDialogType.NeutralButton
|
||||
positiveText: control.positiveText
|
||||
neutralText: control.neutralText
|
||||
negativeText: control.negativeText
|
||||
onVisibleChanged: {
|
||||
if(visible){
|
||||
content_dialog.keysModel = control.current
|
||||
}
|
||||
}
|
||||
onPositiveClicked: {
|
||||
control.current = content_dialog.keysModel
|
||||
control.accepted()
|
||||
}
|
||||
onNegativeClickListener: function(){
|
||||
content_dialog.keysModel = control.current
|
||||
}
|
||||
contentDelegate: Component{
|
||||
Item{
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: 100
|
||||
Component.onCompleted: {
|
||||
forceActiveFocus()
|
||||
}
|
||||
Keys.enabled: true
|
||||
Keys.onPressed:
|
||||
(event)=>{
|
||||
var keyNames = []
|
||||
if (event.modifiers & Qt.AltModifier) {
|
||||
keyNames.push("Alt")
|
||||
}
|
||||
if (event.modifiers & Qt.ControlModifier) {
|
||||
keyNames.push("Ctrl")
|
||||
}
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
keyNames.push("Shift")
|
||||
}
|
||||
var keyName = d.keyToString(event.key,false)
|
||||
if(keyName!==""){
|
||||
keyNames.push(keyName)
|
||||
content_dialog.keysModel = keyNames
|
||||
}
|
||||
event.accepted = true
|
||||
}
|
||||
Keys.onTabPressed:
|
||||
(event)=>{
|
||||
event.accepted = true
|
||||
}
|
||||
Row{
|
||||
spacing: 5
|
||||
anchors.centerIn: parent
|
||||
Repeater{
|
||||
model: content_dialog.keysModel
|
||||
delegate: Loader{
|
||||
property var keyText: modelData
|
||||
sourceComponent: com_item_key
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
content_dialog.open()
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.Slider {
|
||||
property bool tooltipEnabled: true
|
||||
property string text: String(control.value)
|
||||
id: control
|
||||
to:100
|
||||
stepSize:1
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitHandleWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitHandleHeight + topPadding + bottomPadding)
|
||||
padding: 6
|
||||
handle: Rectangle {
|
||||
x: control.leftPadding + (control.horizontal ? control.visualPosition * (control.availableWidth - width) : (control.availableWidth - width) / 2)
|
||||
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : control.visualPosition * (control.availableHeight - height))
|
||||
implicitWidth: 20
|
||||
implicitHeight: 20
|
||||
radius: 10
|
||||
color:FluTheme.dark ? Qt.rgba(69/255,69/255,69/255,1) :Qt.rgba(1,1,1,1)
|
||||
FluShadow{
|
||||
radius: 10
|
||||
}
|
||||
FluIcon{
|
||||
width: 10
|
||||
height: 10
|
||||
Behavior on scale{
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
iconSource: FluentIcons.FullCircleMask
|
||||
iconSize: 10
|
||||
scale:{
|
||||
if(control.pressed){
|
||||
return 0.9
|
||||
}
|
||||
return control.hovered ? 1.2 : 1
|
||||
}
|
||||
iconColor: FluTheme.primaryColor
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
background: Item {
|
||||
x: control.leftPadding + (control.horizontal ? 0 : (control.availableWidth - width) / 2)
|
||||
y: control.topPadding + (control.horizontal ? (control.availableHeight - height) / 2 : 0)
|
||||
implicitWidth: control.horizontal ? 180 : 6
|
||||
implicitHeight: control.horizontal ? 6 : 180
|
||||
width: control.horizontal ? control.availableWidth : implicitWidth
|
||||
height: control.horizontal ? implicitHeight : control.availableHeight
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
radius: 2
|
||||
color:FluTheme.dark ? Qt.rgba(162/255,162/255,162/255,1) : Qt.rgba(138/255,138/255,138/255,1)
|
||||
}
|
||||
scale: control.horizontal && control.mirrored ? -1 : 1
|
||||
Rectangle {
|
||||
y: control.horizontal ? 0 : control.visualPosition * parent.height
|
||||
width: control.horizontal ? control.position * parent.width : 6
|
||||
height: control.horizontal ? 6 : control.position * parent.height
|
||||
radius: 3
|
||||
color: FluTheme.primaryColor
|
||||
}
|
||||
}
|
||||
FluTooltip{
|
||||
parent: control.handle
|
||||
visible: control.tooltipEnabled && (control.pressed || control.hovered)
|
||||
text:control.text
|
||||
}
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.SpinBox {
|
||||
id: control
|
||||
property bool disabled: false
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(56/255,56/255,56/255,1) : Qt.rgba(232/255,232/255,232/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(64/255,64/255,64/255,1) : Qt.rgba(224/255,224/255,224/255,1)
|
||||
property color pressedColor: FluTheme.dark ? Qt.rgba(72/255,72/255,72/255,1) : Qt.rgba(216/255,216/255,216/255,1)
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
contentItem.implicitWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
up.implicitIndicatorHeight, down.implicitIndicatorHeight)
|
||||
leftPadding: padding + (control.mirrored ? (up.indicator ? up.indicator.width : 0) : (down.indicator ? down.indicator.width : 0))
|
||||
rightPadding: padding + (control.mirrored ? (down.indicator ? down.indicator.width : 0) : (up.indicator ? up.indicator.width : 0))
|
||||
enabled: !disabled
|
||||
validator: IntValidator {
|
||||
locale: control.locale.name
|
||||
bottom: Math.min(control.from, control.to)
|
||||
top: Math.max(control.from, control.to)
|
||||
}
|
||||
|
||||
contentItem: TextInput {
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
z: 2
|
||||
text: control.displayText
|
||||
clip: width < implicitWidth
|
||||
padding: 6
|
||||
font: control.font
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
selectedTextColor: color
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
readOnly: !control.editable
|
||||
validator: control.validator
|
||||
inputMethodHints: control.inputMethodHints
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: contentItem.activeFocus ? 2 : 1
|
||||
anchors.bottom: parent.bottom
|
||||
visible: contentItem.enabled
|
||||
color: {
|
||||
if(contentItem.activeFocus){
|
||||
return FluTheme.primaryColor
|
||||
}
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(166/255,166/255,166/255,1)
|
||||
}else{
|
||||
return Qt.rgba(183/255,183/255,183/255,1)
|
||||
}
|
||||
}
|
||||
Behavior on height{
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 83
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
up.indicator: FluClip {
|
||||
x: control.mirrored ? 0 : control.width - width
|
||||
height: control.height
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
radius: [0,4,4,0]
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color: {
|
||||
if(control.up.pressed){
|
||||
return control.pressedColor
|
||||
}
|
||||
if(control.up.hovered){
|
||||
return control.hoverColor
|
||||
}
|
||||
return control.normalColor
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
width: parent.width / 3
|
||||
height: 2
|
||||
color: enabled ? FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) : FluColors.Grey90
|
||||
}
|
||||
Rectangle {
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
width: 2
|
||||
height: parent.width / 3
|
||||
color: enabled ? FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) : FluColors.Grey90
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
down.indicator: FluClip {
|
||||
x: control.mirrored ? parent.width - width : 0
|
||||
height: control.height
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
radius: [4,0,0,4]
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
color: {
|
||||
if(control.down.pressed){
|
||||
return control.pressedColor
|
||||
}
|
||||
if(control.down.hovered){
|
||||
return control.hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
x: (parent.width - width) / 2
|
||||
y: (parent.height - height) / 2
|
||||
width: parent.width / 3
|
||||
height: 2
|
||||
color: enabled ? FluTheme.dark ? Qt.rgba(1,1,1,1) : Qt.rgba(0,0,0,1) : FluColors.Grey90
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 136
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: {
|
||||
if(contentItem.disabled){
|
||||
return FluTheme.dark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(237/255,237/255,237/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(76/255,76/255,76/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
}
|
||||
color: {
|
||||
if(contentItem.disabled){
|
||||
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
|
||||
}
|
||||
if(contentItem.activeFocus){
|
||||
return FluTheme.dark ? Qt.rgba(36/255,36/255,36/255,1) : Qt.rgba(1,1,1,1)
|
||||
}
|
||||
if(contentItem.hovered){
|
||||
return FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
SplitView {
|
||||
property color handleColor : FluTheme.dark ? Qt.rgba(159/255,159/255,159/255,1) : Qt.rgba(138/255,138/255,138/255,1)
|
||||
id:control
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isVertical: control.orientation === Qt.Vertical
|
||||
}
|
||||
handle: Rectangle {
|
||||
implicitWidth: d.isVertical ? control.width : 12
|
||||
implicitHeight: d.isVertical ? 12 : control.height
|
||||
clip: true
|
||||
color: {
|
||||
if(SplitHandle.pressed){
|
||||
return FluTheme.itemPressColor
|
||||
}
|
||||
return SplitHandle.hovered ? FluTheme.itemHoverColor : FluTheme.itemNormalColor
|
||||
}
|
||||
Rectangle{
|
||||
width: d.isVertical ? 26 : 4
|
||||
height: d.isVertical ? 4 : 26
|
||||
anchors.centerIn: parent
|
||||
color: control.handleColor
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
property int itemWidth : 200
|
||||
property alias model: rep.model
|
||||
property alias delegate: rep.delegate
|
||||
property int rowSpacing: 8
|
||||
property int colSpacing: 8
|
||||
id: control
|
||||
QtObject{
|
||||
id:d
|
||||
property int cellWidth : itemWidth+rowSpacing
|
||||
property int colCount: {
|
||||
var cols = parseInt(control.width/cellWidth)
|
||||
return cols>0?cols:1
|
||||
}
|
||||
property var colsHeightArr: []
|
||||
property int maxHeight: 0
|
||||
property var itemsInRep: []
|
||||
onMaxHeightChanged: {
|
||||
control.implicitHeight = maxHeight
|
||||
}
|
||||
onColCountChanged: {
|
||||
refresh()
|
||||
}
|
||||
function refresh(){
|
||||
d.colsHeightArr = []
|
||||
var count = itemsInRep.length
|
||||
for(var i=0; i<count; ++i){
|
||||
addToFall(i, itemsInRep[i])
|
||||
}
|
||||
}
|
||||
function addToFall(index, item){
|
||||
var top = 0,left = 0
|
||||
if(index<colCount){
|
||||
colsHeightArr.push(item.height)
|
||||
left = index * cellWidth
|
||||
}else{
|
||||
var minHeight = Math.min.apply(null, colsHeightArr)
|
||||
var minIndex = colsHeightArr.indexOf(minHeight)
|
||||
top = minHeight + control.colSpacing
|
||||
left = minIndex * cellWidth
|
||||
colsHeightArr[minIndex] = top + item.height
|
||||
}
|
||||
item.x = left
|
||||
item.y = top
|
||||
item.width = control.itemWidth
|
||||
maxHeight = Math.max.apply(null, colsHeightArr)
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
id: rep
|
||||
onCountChanged: {
|
||||
d.refresh()
|
||||
}
|
||||
onItemAdded:
|
||||
(index,item)=> {
|
||||
d.addToFall(index, item)
|
||||
d.itemsInRep.push(item)
|
||||
}
|
||||
}
|
||||
function clear(){
|
||||
d.maxHeight = 0
|
||||
d.colsHeightArr = []
|
||||
d.itemsInRep = []
|
||||
model.clear()
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
id:control
|
||||
default property alias content: container.data
|
||||
property int statusMode: FluStatusLayoutType.Loading
|
||||
property string loadingText:"正在加载..."
|
||||
property string emptyText: "空空如也"
|
||||
property string errorText: "页面出错了.."
|
||||
property string errorButtonText: "重新加载"
|
||||
property color color: FluTheme.dark ? Window.active ? Qt.rgba(38/255,44/255,54/255,1) : Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
signal errorClicked
|
||||
property Component loadingItem : com_loading
|
||||
property Component emptyItem : com_empty
|
||||
property Component errorItem : com_error
|
||||
|
||||
Item{
|
||||
id:container
|
||||
anchors.fill: parent
|
||||
visible: statusMode===FluStatusLayoutType.Success
|
||||
}
|
||||
FluLoader{
|
||||
id:loader
|
||||
anchors.fill: parent
|
||||
visible: statusMode!==FluStatusLayoutType.Success
|
||||
sourceComponent: {
|
||||
if(statusMode === FluStatusLayoutType.Loading){
|
||||
return loadingItem
|
||||
}
|
||||
if(statusMode === FluStatusLayoutType.Empty){
|
||||
return emptyItem
|
||||
}
|
||||
if(statusMode === FluStatusLayoutType.Error){
|
||||
return errorItem
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_loading
|
||||
FluArea{
|
||||
paddings: 0
|
||||
border.width: 0
|
||||
radius: 0
|
||||
color:control.color
|
||||
ColumnLayout{
|
||||
anchors.centerIn: parent
|
||||
FluProgressRing{
|
||||
indeterminate: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
FluText{
|
||||
text:control.loadingText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id:com_empty
|
||||
FluArea{
|
||||
paddings: 0
|
||||
border.width: 0
|
||||
radius: 0
|
||||
color:control.color
|
||||
ColumnLayout{
|
||||
anchors.centerIn: parent
|
||||
FluText{
|
||||
text:control.emptyText
|
||||
font: FluTextStyle.BodyStrong
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_error
|
||||
FluArea{
|
||||
paddings: 0
|
||||
border.width: 0
|
||||
radius: 0
|
||||
color:control.color
|
||||
ColumnLayout{
|
||||
anchors.centerIn: parent
|
||||
FluText{
|
||||
text:control.errorText
|
||||
font: FluTextStyle.BodyStrong
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
FluFilledButton{
|
||||
id:btn_error
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text:control.errorButtonText
|
||||
onClicked:{
|
||||
control.errorClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function showSuccessView(){
|
||||
statusMode = FluStatusLayoutType.Success
|
||||
}
|
||||
function showLoadingView(){
|
||||
statusMode = FluStatusLayoutType.Loading
|
||||
}
|
||||
function showEmptyView(){
|
||||
statusMode = FluStatusLayoutType.Empty
|
||||
}
|
||||
function showErrorView(){
|
||||
statusMode = FluStatusLayoutType.Error
|
||||
}
|
||||
}
|
@ -1,299 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int tabWidthBehavior : FluTabViewType.Equal
|
||||
property int closeButtonVisibility : FluTabViewType.Always
|
||||
property int itemWidth: 146
|
||||
property bool addButtonVisibility: true
|
||||
signal newPressed
|
||||
id:control
|
||||
implicitHeight: height
|
||||
implicitWidth: width
|
||||
anchors.fill: {
|
||||
if(parent)
|
||||
return parent
|
||||
return undefined
|
||||
}
|
||||
QtObject {
|
||||
id: d
|
||||
property int dragIndex: -1
|
||||
property bool dragBehavior: false
|
||||
property bool itemPress: false
|
||||
property int maxEqualWidth: 240
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
}
|
||||
ListModel{
|
||||
id:tab_model
|
||||
}
|
||||
FluIconButton{
|
||||
id:btn_new
|
||||
visible: addButtonVisibility
|
||||
width: 34
|
||||
height: 34
|
||||
x:Math.min(tab_nav.contentWidth,tab_nav.width)
|
||||
anchors.top: parent.top
|
||||
iconSource: FluentIcons.Add
|
||||
onClicked: {
|
||||
newPressed()
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:tab_nav
|
||||
height: 34
|
||||
orientation: ListView.Horizontal
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
rightMargin: 34
|
||||
}
|
||||
interactive: false
|
||||
model: tab_model
|
||||
move: Transition {
|
||||
NumberAnimation { properties: "x"; duration: 100; easing.type: Easing.OutCubic }
|
||||
NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic }
|
||||
}
|
||||
moveDisplaced: Transition {
|
||||
NumberAnimation { properties: "x"; duration: 300; easing.type: Easing.OutCubic}
|
||||
NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic }
|
||||
}
|
||||
clip: true
|
||||
ScrollBar.horizontal: ScrollBar{
|
||||
id: scroll_nav
|
||||
policy: ScrollBar.AlwaysOff
|
||||
}
|
||||
delegate: Item{
|
||||
width: item_layout.width
|
||||
height: item_container.height
|
||||
z: item_mouse_drag.pressed ? 1000 : 1
|
||||
Item{
|
||||
id:item_layout
|
||||
width: item_container.width
|
||||
height: item_container.height
|
||||
Item{
|
||||
id:item_container
|
||||
property real timestamp: new Date().getTime()
|
||||
height: tab_nav.height
|
||||
width: {
|
||||
if(tabWidthBehavior === FluTabViewType.Equal){
|
||||
return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width)
|
||||
}
|
||||
if(tabWidthBehavior === FluTabViewType.SizeToContent){
|
||||
return itemWidth
|
||||
}
|
||||
if(tabWidthBehavior === FluTabViewType.Compact){
|
||||
return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index ? itemWidth : 41 + item_btn_close.width
|
||||
}
|
||||
return Math.max(Math.min(d.maxEqualWidth,tab_nav.width/tab_nav.count),41 + item_btn_close.width)
|
||||
}
|
||||
Behavior on x { enabled: d.dragBehavior; NumberAnimation { duration: 200 } }
|
||||
Behavior on y { enabled: d.dragBehavior; NumberAnimation { duration: 200 } }
|
||||
MouseArea{
|
||||
id:item_mouse_hove
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
}
|
||||
FluTooltip{
|
||||
visible: item_mouse_hove.containsMouse
|
||||
text:item_text.text
|
||||
delay: 1000
|
||||
}
|
||||
MouseArea{
|
||||
id:item_mouse_drag
|
||||
anchors.fill: parent
|
||||
drag.target: item_container
|
||||
drag.axis: Drag.XAxis
|
||||
onWheel: (wheel)=>{
|
||||
if (wheel.angleDelta.y > 0) scroll_nav.decrease()
|
||||
else scroll_nav.increase()
|
||||
}
|
||||
onPressed: {
|
||||
d.itemPress = true
|
||||
item_container.timestamp = new Date().getTime();
|
||||
d.dragBehavior = false;
|
||||
var pos = tab_nav.mapFromItem(item_container, 0, 0)
|
||||
d.dragIndex = model.index
|
||||
item_container.parent = tab_nav
|
||||
item_container.x = pos.x
|
||||
item_container.y = pos.y
|
||||
}
|
||||
onReleased: {
|
||||
d.itemPress = false
|
||||
timer.stop()
|
||||
var timeDiff = new Date().getTime() - item_container.timestamp
|
||||
if (timeDiff < 300) {
|
||||
tab_nav.currentIndex = index
|
||||
}
|
||||
d.dragIndex = -1;
|
||||
var pos = tab_nav.mapToItem(item_layout, item_container.x, item_container.y)
|
||||
item_container.parent = item_layout;
|
||||
item_container.x = pos.x;
|
||||
item_container.y = pos.y;
|
||||
d.dragBehavior = true;
|
||||
item_container.x = 0;
|
||||
item_container.y = 0;
|
||||
}
|
||||
onPositionChanged: {
|
||||
var pos = tab_nav.mapFromItem(item_container, 0, 0)
|
||||
updatePosition(pos)
|
||||
if(pos.x<0){
|
||||
timer.isIncrease = false
|
||||
timer.restart()
|
||||
}else if(pos.x>tab_nav.width-itemWidth){
|
||||
timer.isIncrease = true
|
||||
timer.restart()
|
||||
}else{
|
||||
timer.stop()
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id:timer
|
||||
property bool isIncrease: true
|
||||
interval: 10
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if(isIncrease){
|
||||
if(tab_nav.contentX>=tab_nav.contentWidth-tab_nav.width){
|
||||
return
|
||||
}
|
||||
tab_nav.contentX = tab_nav.contentX+2
|
||||
}else{
|
||||
if(tab_nav.contentX<=0){
|
||||
return
|
||||
}
|
||||
tab_nav.contentX = tab_nav.contentX-2
|
||||
}
|
||||
item_mouse_drag.updatePosition(tab_nav.mapFromItem(item_container, 0, 0))
|
||||
}
|
||||
}
|
||||
function updatePosition(pos){
|
||||
var idx = tab_nav.indexAt(pos.x+tab_nav.contentX+1, pos.y)
|
||||
if(idx<0){
|
||||
return
|
||||
}
|
||||
if(idx>=tab_nav.count){
|
||||
return
|
||||
}
|
||||
if (d.dragIndex !== idx) {
|
||||
tab_model.move(d.dragIndex, idx, 1)
|
||||
d.dragIndex = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
anchors.fill: parent
|
||||
radius: [6,6,0,0]
|
||||
color: {
|
||||
if(item_mouse_hove.containsMouse || item_btn_close.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
if(tab_nav.currentIndex === index){
|
||||
return FluTheme.itemCheckColor
|
||||
}
|
||||
return FluTheme.itemNormalColor
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
spacing: 0
|
||||
height: parent.height
|
||||
Image{
|
||||
source:model.icon
|
||||
Layout.leftMargin: 10
|
||||
Layout.preferredWidth: 14
|
||||
Layout.preferredHeight: 14
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
FluText{
|
||||
id:item_text
|
||||
text: model.text
|
||||
Layout.leftMargin: 10
|
||||
visible: {
|
||||
if(tabWidthBehavior === FluTabViewType.Equal){
|
||||
return true
|
||||
}
|
||||
if(tabWidthBehavior === FluTabViewType.SizeToContent){
|
||||
return true
|
||||
}
|
||||
if(tabWidthBehavior === FluTabViewType.Compact){
|
||||
return item_mouse_hove.containsMouse || item_btn_close.hovered || tab_nav.currentIndex === index
|
||||
}
|
||||
return false
|
||||
}
|
||||
Layout.preferredWidth: visible?item_container.width - 41 - item_btn_close.width:0
|
||||
elide: Text.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
id:item_btn_close
|
||||
iconSource: FluentIcons.ChromeClose
|
||||
iconSize: 10
|
||||
width: visible ? 24 : 0
|
||||
height: 24
|
||||
visible: {
|
||||
if(closeButtonVisibility === FluTabViewType.Never)
|
||||
return false
|
||||
if(closeButtonVisibility === FluTabViewType.OnHover)
|
||||
return item_mouse_hove.containsMouse || item_btn_close.hovered
|
||||
return true
|
||||
}
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
onClicked: {
|
||||
tab_model.remove(index)
|
||||
}
|
||||
}
|
||||
FluDivider{
|
||||
width: 1
|
||||
height: 16
|
||||
orientation: Qt.Vertical
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:container
|
||||
anchors{
|
||||
top: tab_nav.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
Repeater{
|
||||
model:tab_model
|
||||
FluLoader{
|
||||
property var argument: model.argument
|
||||
anchors.fill: parent
|
||||
sourceComponent: model.page
|
||||
visible: tab_nav.currentIndex === index
|
||||
}
|
||||
}
|
||||
}
|
||||
function createTab(icon,text,page,argument={}){
|
||||
return {icon:icon,text:text,page:page,argument:argument}
|
||||
}
|
||||
function appendTab(icon,text,page,argument){
|
||||
tab_model.append(createTab(icon,text,page,argument))
|
||||
}
|
||||
function setTabList(list){
|
||||
tab_model.clear()
|
||||
tab_model.append(list)
|
||||
}
|
||||
function count(){
|
||||
return tab_nav.count
|
||||
}
|
||||
}
|
@ -1,849 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import Qt.labs.qmlmodels
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
property var columnSource
|
||||
property var dataSource
|
||||
property color borderColor: FluTheme.dark ? "#252525" : "#e4e4e4"
|
||||
property alias rows: table_view.rows
|
||||
property alias columns: table_view.columns
|
||||
property bool horizonalHeaderVisible: true
|
||||
property bool verticalHeaderVisible: true
|
||||
property color selectedBorderColor: FluTheme.primaryColor
|
||||
property color selectedColor: FluTools.colorAlpha(FluTheme.primaryColor,0.3)
|
||||
property alias sourceModel: table_model
|
||||
id:control
|
||||
color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
onColumnSourceChanged: {
|
||||
if(columnSource.length!==0){
|
||||
var columns= []
|
||||
var columnsData = []
|
||||
var headerRow = {}
|
||||
columnSource.forEach(function(item){
|
||||
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model);
|
||||
column.display = item.dataIndex
|
||||
columnsData.push(item)
|
||||
columns.push(column)
|
||||
headerRow[item.dataIndex] = item.title
|
||||
})
|
||||
d.columns_data = columnsData
|
||||
table_model.columns = columns
|
||||
header_column_model.columns = columns
|
||||
header_column_model.rows = [headerRow]
|
||||
}
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property var current
|
||||
property int rowHoverIndex: -1
|
||||
property int defaultItemWidth: 100
|
||||
property int defaultItemHeight: 42
|
||||
property var columns_data: []
|
||||
property var editDelegate
|
||||
property var editPosition
|
||||
function getEditDelegate(column){
|
||||
var obj =d.columns_data[column].editDelegate
|
||||
if(obj){
|
||||
return obj
|
||||
}
|
||||
if(d.columns_data[column].editMultiline === true){
|
||||
return com_edit_multiline
|
||||
}
|
||||
return com_edit
|
||||
}
|
||||
}
|
||||
onDataSourceChanged: {
|
||||
table_model.clear()
|
||||
table_model.rows = dataSource
|
||||
}
|
||||
TableModel {
|
||||
id:table_model
|
||||
TableModelColumn {}
|
||||
}
|
||||
TableModel{
|
||||
id:header_column_model
|
||||
TableModelColumn {}
|
||||
}
|
||||
TableModel{
|
||||
id:header_row_model
|
||||
TableModelColumn { display: "rowIndex" }
|
||||
}
|
||||
FluTableSortProxyModel{
|
||||
id:table_sort_model
|
||||
model: table_model
|
||||
}
|
||||
Component{
|
||||
id:com_edit
|
||||
FluTextBox{
|
||||
id:text_box
|
||||
text: String(display)
|
||||
readOnly: true === d.columns_data[column].readOnly
|
||||
Component.onCompleted: {
|
||||
forceActiveFocus()
|
||||
selectAll()
|
||||
}
|
||||
onCommit: {
|
||||
if(!readOnly){
|
||||
editTextChaged(text_box.text)
|
||||
}
|
||||
tableView.closeEditor()
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_edit_multiline
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
ScrollView{
|
||||
id:item_scroll
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
ScrollBar.vertical: FluScrollBar{
|
||||
parent: item_scroll
|
||||
x: item_scroll.mirrored ? 0 : item_scroll.width - width
|
||||
y: item_scroll.topPadding
|
||||
height: item_scroll.availableHeight
|
||||
active: item_scroll.ScrollBar.horizontal.active
|
||||
}
|
||||
FluMultilineTextBox {
|
||||
id:text_box
|
||||
text: display
|
||||
readOnly: true === d.columns_data[column].readOnly
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
Component.onCompleted: {
|
||||
forceActiveFocus()
|
||||
selectAll()
|
||||
}
|
||||
rightPadding: 24
|
||||
onCommit: {
|
||||
if(!readOnly){
|
||||
editTextChaged(text_box.text)
|
||||
}
|
||||
tableView.closeEditor()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
iconSource:FluentIcons.ChromeClose
|
||||
iconSize: 10
|
||||
width: 20
|
||||
height: 20
|
||||
visible: {
|
||||
if(text_box.readOnly)
|
||||
return false
|
||||
return text_box.text !== ""
|
||||
}
|
||||
anchors{
|
||||
verticalCenter: parent.verticalCenter
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
}
|
||||
onClicked:{
|
||||
text_box.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_text
|
||||
FluText {
|
||||
id:item_text
|
||||
text: String(display)
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.WrapAnywhere
|
||||
anchors{
|
||||
fill: parent
|
||||
leftMargin: 11
|
||||
rightMargin: 11
|
||||
topMargin: 6
|
||||
bottomMargin: 6
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
MouseArea{
|
||||
acceptedButtons: Qt.NoButton
|
||||
id: hover_handler
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
}
|
||||
FluTooltip{
|
||||
text: item_text.text
|
||||
delay: 500
|
||||
visible: item_text.contentWidth < item_text.implicitWidth && item_text.contentHeight < item_text.implicitHeight && hover_handler.containsMouse
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_table_delegate
|
||||
MouseArea{
|
||||
id:item_table_mouse
|
||||
property var rowObject : control.getRow(row)
|
||||
property var itemModel: model
|
||||
property bool editVisible: {
|
||||
if(d.editPosition === undefined){
|
||||
return false
|
||||
}
|
||||
if(d.editPosition._key === rowObject._key && d.editPosition.column === column){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
d.rowHoverIndex = row
|
||||
}
|
||||
onWidthChanged: {
|
||||
if(editVisible){
|
||||
updateEditPosition()
|
||||
}
|
||||
}
|
||||
onHeightChanged: {
|
||||
if(editVisible){
|
||||
updateEditPosition()
|
||||
}
|
||||
}
|
||||
onXChanged: {
|
||||
if(editVisible){
|
||||
updateEditPosition()
|
||||
}
|
||||
}
|
||||
onYChanged: {
|
||||
if(editVisible){
|
||||
updateEditPosition()
|
||||
}
|
||||
}
|
||||
function updateEditPosition(){
|
||||
var obj = {}
|
||||
obj._key = rowObject._key
|
||||
obj.column = column
|
||||
obj.row = row
|
||||
obj.x = item_table_mouse.x
|
||||
obj.y = item_table_mouse.y + 1
|
||||
obj.width = item_table_mouse.width
|
||||
obj.height = item_table_mouse.height - 2
|
||||
d.editPosition = obj
|
||||
}
|
||||
Rectangle{
|
||||
id:item_table
|
||||
anchors.fill: parent
|
||||
property point position: Qt.point(column,row)
|
||||
property bool isRowSelected: {
|
||||
if(rowObject === null)
|
||||
return false
|
||||
if(d.current){
|
||||
return rowObject._key === d.current._key
|
||||
}
|
||||
return false
|
||||
}
|
||||
color:{
|
||||
if(item_table.isRowSelected){
|
||||
return control.selectedColor
|
||||
}
|
||||
if(d.rowHoverIndex === row || item_table.isRowSelected){
|
||||
return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
|
||||
}
|
||||
return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.015) : Qt.rgba(0,0,0,0.015))
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onPressed:{
|
||||
closeEditor()
|
||||
}
|
||||
onCanceled: {
|
||||
}
|
||||
onReleased: {
|
||||
}
|
||||
onDoubleClicked:{
|
||||
if(typeof(display) == "object"){
|
||||
return
|
||||
}
|
||||
d.editDelegate = d.getEditDelegate(column)
|
||||
updateEditPosition()
|
||||
loader_edit.display = display
|
||||
}
|
||||
onClicked:
|
||||
(event)=>{
|
||||
d.current = rowObject
|
||||
closeEditor()
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
property var model: itemModel
|
||||
property var display: itemModel.display
|
||||
property int row: item_table.position.y
|
||||
property int column: item_table.position.x
|
||||
property bool isObject: typeof(display) == "object"
|
||||
property var options: {
|
||||
if(isObject){
|
||||
return display.options
|
||||
}
|
||||
return {}
|
||||
}
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(isObject){
|
||||
return display.comId
|
||||
}
|
||||
return com_text
|
||||
}
|
||||
}
|
||||
Item{
|
||||
anchors.fill: parent
|
||||
visible: item_table.isRowSelected
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.left: parent.left
|
||||
color: control.selectedBorderColor
|
||||
visible: column === 0
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
color: control.selectedBorderColor
|
||||
visible: column === control.columns-1
|
||||
}
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: parent.top
|
||||
color: control.selectedBorderColor
|
||||
}
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color: control.selectedBorderColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:layout_mouse_table
|
||||
hoverEnabled: true
|
||||
anchors{
|
||||
left: header_vertical.right
|
||||
top: header_horizontal.bottom
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
onExited: {
|
||||
d.rowHoverIndex = -1
|
||||
}
|
||||
onCanceled: {
|
||||
d.rowHoverIndex = -1
|
||||
}
|
||||
TableView {
|
||||
id:table_view
|
||||
ListModel{
|
||||
id:model_columns
|
||||
}
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
syncView: header_horizontal
|
||||
syncDirection: Qt.Horizontal
|
||||
anchors.fill: parent
|
||||
ScrollBar.vertical:scroll_bar_v
|
||||
rowHeightProvider: function(row) {
|
||||
var rowObject = control.getRow(row)
|
||||
var height = rowObject.height
|
||||
if(height){
|
||||
return height
|
||||
}
|
||||
var minimumHeight = rowObject._minimumHeight
|
||||
if(minimumHeight){
|
||||
return minimumHeight
|
||||
}
|
||||
return d.defaultItemHeight
|
||||
}
|
||||
model: table_sort_model
|
||||
clip: true
|
||||
onRowsChanged: {
|
||||
closeEditor()
|
||||
}
|
||||
delegate: com_table_delegate
|
||||
FluLoader{
|
||||
id:loader_edit
|
||||
property var tableView: control
|
||||
property var display
|
||||
property int column: {
|
||||
if(d.editPosition){
|
||||
return d.editPosition.column
|
||||
}
|
||||
return 0
|
||||
}
|
||||
property int row: {
|
||||
if(d.editPosition){
|
||||
return d.editPosition.row
|
||||
}
|
||||
return 0
|
||||
}
|
||||
signal editTextChaged(string text)
|
||||
sourceComponent: d.editPosition ? d.editDelegate : undefined
|
||||
onEditTextChaged:
|
||||
(text)=>{
|
||||
var obj = control.getRow(row)
|
||||
obj[d.columns_data[column].dataIndex] = text
|
||||
control.setRow(row,obj)
|
||||
}
|
||||
width: {
|
||||
if(d.editPosition){
|
||||
return d.editPosition.width
|
||||
}
|
||||
return 0
|
||||
}
|
||||
height: {
|
||||
if(d.editPosition){
|
||||
return d.editPosition.height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
x:{
|
||||
if(d.editPosition){
|
||||
return d.editPosition.x
|
||||
}
|
||||
return 0
|
||||
}
|
||||
y:{
|
||||
if(d.editPosition){
|
||||
return d.editPosition.y
|
||||
}
|
||||
return 0
|
||||
}
|
||||
z:999
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_column_header_delegate
|
||||
Rectangle{
|
||||
id:column_item_control
|
||||
readonly property real cellPadding: 8
|
||||
property bool canceled: false
|
||||
property int columnIndex: column
|
||||
readonly property var columnObject : d.columns_data[column]
|
||||
implicitWidth: {
|
||||
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2)
|
||||
}
|
||||
implicitHeight: Math.max(36, (item_column_loader.item&&item_column_loader.item.implicitHeight) + (cellPadding * 2))
|
||||
color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1)
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: parent.top
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.left: parent.left
|
||||
visible: column !== 0
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
color:"#00000000"
|
||||
visible: column === table_view.columns - 1
|
||||
}
|
||||
MouseArea{
|
||||
id:column_item_control_mouse
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 6
|
||||
hoverEnabled: true
|
||||
onCanceled: {
|
||||
column_item_control.canceled = true
|
||||
}
|
||||
onContainsMouseChanged: {
|
||||
if(!containsMouse){
|
||||
column_item_control.canceled = false
|
||||
}
|
||||
}
|
||||
onClicked:
|
||||
(event)=>{
|
||||
closeEditor()
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id:item_column_loader
|
||||
property var itemModel: model
|
||||
property var modelData: model.display
|
||||
property var tableView: table_view
|
||||
property var tableModel: table_model
|
||||
property var options:{
|
||||
if(typeof(modelData) == "object"){
|
||||
return modelData.options
|
||||
}
|
||||
return {}
|
||||
}
|
||||
property int column: column_item_control.columnIndex
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
sourceComponent: {
|
||||
if(typeof(modelData) == "object"){
|
||||
return modelData.comId
|
||||
}
|
||||
return com_column_text
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
property point clickPos: "0,0"
|
||||
height: parent.height
|
||||
width: 6
|
||||
anchors.right: parent.right
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
visible: !(columnObject.width === columnObject.minimumWidth && columnObject.width === columnObject.maximumWidth && columnObject.width)
|
||||
cursorShape: Qt.SplitHCursor
|
||||
preventStealing: true
|
||||
onPressed :
|
||||
(mouse)=>{
|
||||
FluTools.setOverrideCursor(Qt.SplitHCursor)
|
||||
clickPos = Qt.point(mouse.x, mouse.y)
|
||||
}
|
||||
onReleased:{
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onCanceled: {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(!pressed){
|
||||
return
|
||||
}
|
||||
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
|
||||
var minimumWidth = columnObject.minimumWidth
|
||||
var maximumWidth = columnObject.maximumWidth
|
||||
var w = columnObject.width
|
||||
if(!w){
|
||||
w = d.defaultItemWidth
|
||||
}
|
||||
if(!minimumWidth){
|
||||
minimumWidth = d.defaultItemWidth
|
||||
}
|
||||
if(!maximumWidth){
|
||||
maximumWidth = 65535
|
||||
}
|
||||
columnObject.width = Math.min(Math.max(minimumWidth, w + delta.x),maximumWidth)
|
||||
header_horizontal.forceLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_row_header_delegate
|
||||
Rectangle{
|
||||
id:item_control
|
||||
readonly property real cellPadding: 8
|
||||
property bool canceled: false
|
||||
property var rowObject: control.getRow(row)
|
||||
implicitWidth: Math.max(30, row_text.implicitWidth + (cellPadding * 2))
|
||||
implicitHeight: row_text.implicitHeight + (cellPadding * 2)
|
||||
color: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(247/255,247/255,247/255,1)
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: parent.top
|
||||
visible: row !== 0
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
visible: row === table_view.rows - 1
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.left: parent.left
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
color:"#00000000"
|
||||
}
|
||||
FluText{
|
||||
id:row_text
|
||||
anchors.centerIn: parent
|
||||
text: model.display
|
||||
}
|
||||
MouseArea{
|
||||
id:item_control_mouse
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: 6
|
||||
hoverEnabled: true
|
||||
onCanceled: {
|
||||
item_control.canceled = true
|
||||
}
|
||||
onContainsMouseChanged: {
|
||||
if(!containsMouse){
|
||||
item_control.canceled = false
|
||||
}
|
||||
}
|
||||
onClicked:
|
||||
(event)=>{
|
||||
closeEditor()
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
property point clickPos: "0,0"
|
||||
height: 6
|
||||
width: parent.width
|
||||
anchors.bottom: parent.bottom
|
||||
acceptedButtons: Qt.LeftButton
|
||||
cursorShape: Qt.SplitVCursor
|
||||
preventStealing: true
|
||||
visible: {
|
||||
if(rowObject === null)
|
||||
return false
|
||||
return !(rowObject.height === rowObject._minimumHeight && rowObject.height === rowObject._maximumHeight && rowObject.height)
|
||||
}
|
||||
onPressed :
|
||||
(mouse)=>{
|
||||
FluTools.setOverrideCursor(Qt.SplitVCursor)
|
||||
clickPos = Qt.point(mouse.x, mouse.y)
|
||||
}
|
||||
onReleased:{
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onCanceled: {
|
||||
FluTools.restoreOverrideCursor()
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=>{
|
||||
if(!pressed){
|
||||
return
|
||||
}
|
||||
var rowObject = control.getRow(row)
|
||||
var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
|
||||
var minimumHeight = rowObject._minimumHeight
|
||||
var maximumHeight = rowObject._maximumHeight
|
||||
var h = rowObject.height
|
||||
if(!h){
|
||||
h = d.defaultItemHeight
|
||||
}
|
||||
if(!minimumHeight){
|
||||
minimumHeight = d.defaultItemHeight
|
||||
}
|
||||
if(!maximumHeight){
|
||||
maximumHeight = 65535
|
||||
}
|
||||
rowObject.height = Math.min(Math.max(minimumHeight, h + delta.y),maximumHeight)
|
||||
control.setRow(row,rowObject)
|
||||
table_view.forceLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_column_text
|
||||
FluText {
|
||||
id: column_text
|
||||
text: modelData
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id: header_vertical_column
|
||||
anchors{
|
||||
top: header_horizontal.top
|
||||
bottom: header_horizontal.bottom
|
||||
left: parent.left
|
||||
right: header_vertical.right
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: parent.top
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.left: parent.left
|
||||
color:"#00000000"
|
||||
}
|
||||
Rectangle{
|
||||
border.color: control.borderColor
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
color:"#00000000"
|
||||
}
|
||||
}
|
||||
TableView {
|
||||
id: header_horizontal
|
||||
model: header_column_model
|
||||
anchors{
|
||||
left: header_vertical.right
|
||||
right: layout_mouse_table.right
|
||||
top: parent.top
|
||||
}
|
||||
visible: control.horizonalHeaderVisible
|
||||
height: visible ? Math.max(1, contentHeight) : 0
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
clip: true
|
||||
ScrollBar.horizontal:scroll_bar_h
|
||||
columnWidthProvider: function(column) {
|
||||
var columnObject = d.columns_data[column]
|
||||
var width = columnObject.width
|
||||
if(width){
|
||||
return width
|
||||
}
|
||||
var minimumWidth = columnObject.minimumWidth
|
||||
if(minimumWidth){
|
||||
return minimumWidth
|
||||
}
|
||||
return d.defaultItemWidth
|
||||
}
|
||||
onContentXChanged:{
|
||||
timer_horizontal_force_layout.restart()
|
||||
}
|
||||
Timer{
|
||||
id:timer_horizontal_force_layout
|
||||
interval: 50
|
||||
onTriggered: {
|
||||
header_horizontal.forceLayout()
|
||||
}
|
||||
}
|
||||
delegate: com_column_header_delegate
|
||||
}
|
||||
TableView {
|
||||
id: header_vertical
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
anchors{
|
||||
top: layout_mouse_table.top
|
||||
left: parent.left
|
||||
}
|
||||
visible: control.verticalHeaderVisible
|
||||
implicitWidth: visible ? Math.max(1, contentWidth) : 0
|
||||
implicitHeight: syncView ? syncView.height : 0
|
||||
syncDirection: Qt.Vertical
|
||||
syncView: table_view
|
||||
clip: true
|
||||
model: header_row_model
|
||||
Connections{
|
||||
target: table_model
|
||||
function onRowCountChanged(){
|
||||
header_row_model.rows = Array.from({length: table_model.rows.length}, (_, i) => ({rowIndex:i+1}))
|
||||
}
|
||||
}
|
||||
onContentYChanged:{
|
||||
timer_vertical_force_layout.restart()
|
||||
}
|
||||
Timer{
|
||||
id:timer_vertical_force_layout
|
||||
interval: 50
|
||||
onTriggered: {
|
||||
header_vertical.forceLayout()
|
||||
}
|
||||
}
|
||||
delegate: com_row_header_delegate
|
||||
}
|
||||
FluScrollBar {
|
||||
id:scroll_bar_h
|
||||
anchors{
|
||||
left: layout_mouse_table.left
|
||||
right: parent.right
|
||||
bottom: layout_mouse_table.bottom
|
||||
}
|
||||
z:999
|
||||
}
|
||||
FluScrollBar {
|
||||
id:scroll_bar_v
|
||||
anchors{
|
||||
top: layout_mouse_table.top
|
||||
bottom: layout_mouse_table.bottom
|
||||
right: parent.right
|
||||
}
|
||||
z:999
|
||||
}
|
||||
function closeEditor(){
|
||||
d.editPosition = undefined
|
||||
d.editDelegate = undefined
|
||||
}
|
||||
function resetPosition(){
|
||||
scroll_bar_h.position = 0
|
||||
scroll_bar_v.position = 0
|
||||
}
|
||||
function customItem(comId,options={}){
|
||||
var o = {}
|
||||
o.comId = comId
|
||||
o.options = options
|
||||
return o
|
||||
}
|
||||
function sort(callback=undefined){
|
||||
if(callback){
|
||||
table_sort_model.setComparator(function(left,right){
|
||||
return callback(table_model.getRow(left),table_model.getRow(right))
|
||||
})
|
||||
}else{
|
||||
table_sort_model.setComparator(undefined)
|
||||
}
|
||||
}
|
||||
function filter(callback=undefined){
|
||||
if(callback){
|
||||
table_sort_model.setFilter(function(index){
|
||||
return callback(table_model.getRow(index))
|
||||
})
|
||||
}else{
|
||||
table_sort_model.setFilter(undefined)
|
||||
}
|
||||
}
|
||||
function setRow(rowIndex,obj){
|
||||
if(rowIndex>=0 && rowIndex<table_view.rows){
|
||||
table_view.model.setRow(rowIndex,obj)
|
||||
}
|
||||
}
|
||||
function getRow(rowIndex){
|
||||
if(rowIndex>=0 && rowIndex<table_view.rows){
|
||||
return table_view.model.getRow(rowIndex)
|
||||
}
|
||||
return null
|
||||
}
|
||||
function removeRow(rowIndex,rows=1){
|
||||
if(rowIndex>=0 && rowIndex<table_view.rows){
|
||||
table_view.model.removeRow(rowIndex,rows)
|
||||
}
|
||||
}
|
||||
function appendRow(obj){
|
||||
table_model.appendRow(obj)
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Text {
|
||||
property color textColor: FluTheme.fontPrimaryColor
|
||||
id:text
|
||||
color: textColor
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
font: FluTextStyle.Body
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
TextField{
|
||||
signal commit(string text)
|
||||
property bool disabled: false
|
||||
property int iconSource: 0
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property color placeholderNormalColor: FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
|
||||
property color placeholderFocusColor: FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color placeholderDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
|
||||
property bool cleanEnabled: true
|
||||
id:control
|
||||
padding: 7
|
||||
leftPadding: padding+4
|
||||
enabled: !disabled
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
font:FluTextStyle.Body
|
||||
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
|
||||
selectionColor: FluTools.colorAlpha(FluTheme.primaryColor,0.5)
|
||||
selectedTextColor: color
|
||||
placeholderTextColor: {
|
||||
if(!enabled){
|
||||
return placeholderDisableColor
|
||||
}
|
||||
if(focus){
|
||||
return placeholderFocusColor
|
||||
}
|
||||
return placeholderNormalColor
|
||||
}
|
||||
selectByMouse: true
|
||||
rightPadding: {
|
||||
var w = 30
|
||||
if(control.cleanEnabled === false){
|
||||
w = 0
|
||||
}
|
||||
if(control.readOnly)
|
||||
w = 0
|
||||
return icon_end.visible ? w+36 : w+10
|
||||
}
|
||||
width: 240
|
||||
background: FluTextBoxBackground{
|
||||
inputItem: control
|
||||
}
|
||||
Keys.onEnterPressed: (event)=> d.handleCommit(event)
|
||||
Keys.onReturnPressed:(event)=> d.handleCommit(event)
|
||||
QtObject{
|
||||
id:d
|
||||
function handleCommit(event){
|
||||
control.commit(control.text)
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: {
|
||||
if(control.echoMode === TextInput.Password){
|
||||
return
|
||||
}
|
||||
if(control.readOnly && control.text === ""){
|
||||
return
|
||||
}
|
||||
menu.popup()
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
height: parent.height
|
||||
anchors{
|
||||
right: parent.right
|
||||
rightMargin: 5
|
||||
}
|
||||
spacing: 4
|
||||
FluIconButton{
|
||||
iconSource: FluentIcons.Cancel
|
||||
iconSize: 12
|
||||
Layout.preferredWidth: 30
|
||||
Layout.preferredHeight: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
iconColor: FluTheme.dark ? Qt.rgba(222/255,222/255,222/255,1) : Qt.rgba(97/255,97/255,97/255,1)
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
visible: {
|
||||
if(control.cleanEnabled === false){
|
||||
return false
|
||||
}
|
||||
if(control.readOnly)
|
||||
return false
|
||||
return control.text !== ""
|
||||
}
|
||||
contentDescription:"Clean"
|
||||
onClicked:{
|
||||
control.clear()
|
||||
}
|
||||
}
|
||||
FluIcon{
|
||||
id:icon_end
|
||||
iconSource: control.iconSource
|
||||
iconSize: 12
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.rightMargin: 7
|
||||
iconColor: FluTheme.dark ? Qt.rgba(222/255,222/255,222/255,1) : Qt.rgba(97/255,97/255,97/255,1)
|
||||
visible: control.iconSource != 0
|
||||
}
|
||||
}
|
||||
FluTextBoxMenu{
|
||||
id:menu
|
||||
inputItem: control
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluClip{
|
||||
property Item inputItem
|
||||
property int borderWidth: 1
|
||||
id:control
|
||||
radius: [4,4,4,4]
|
||||
Rectangle{
|
||||
radius: 4
|
||||
anchors.fill: parent
|
||||
color: {
|
||||
if(inputItem && inputItem.disabled){
|
||||
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(252/255,252/255,252/255,1)
|
||||
}
|
||||
if(inputItem && inputItem.activeFocus){
|
||||
return FluTheme.dark ? Qt.rgba(36/255,36/255,36/255,1) : Qt.rgba(1,1,1,1)
|
||||
}
|
||||
if(inputItem && inputItem.hovered){
|
||||
return FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(1,1,1,1)
|
||||
}
|
||||
border.width: control.borderWidth
|
||||
border.color: {
|
||||
if(inputItem && inputItem.disabled){
|
||||
return FluTheme.dark ? Qt.rgba(73/255,73/255,73/255,1) : Qt.rgba(237/255,237/255,237/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(76/255,76/255,76/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: inputItem && inputItem.activeFocus ? 2 : 1
|
||||
anchors.bottom: parent.bottom
|
||||
visible: !(inputItem && inputItem.disabled)
|
||||
color: {
|
||||
if(inputItem && inputItem.activeFocus){
|
||||
return FluTheme.primaryColor
|
||||
}
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(166/255,166/255,166/255,1)
|
||||
}else{
|
||||
return Qt.rgba(134/255,134/255,134/255,1)
|
||||
}
|
||||
}
|
||||
Behavior on height{
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation{
|
||||
duration: 83
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
FluMenu{
|
||||
property string cutText : qsTr("Cut")
|
||||
property string copyText : qsTr("Copy")
|
||||
property string pasteText : qsTr("Paste")
|
||||
property string selectAllText : qsTr("Select All")
|
||||
property var inputItem
|
||||
id:menu
|
||||
enableAnimation: false
|
||||
width: 120
|
||||
focus: false
|
||||
onVisibleChanged: {
|
||||
if(inputItem){
|
||||
inputItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: {
|
||||
if(inputItem){
|
||||
return inputItem
|
||||
}
|
||||
return null
|
||||
}
|
||||
function onTextChanged() {
|
||||
menu.close()
|
||||
}
|
||||
function onActiveFocusChanged() {
|
||||
if(!inputItem.activeFocus){
|
||||
menu.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
display: Button.TextOnly
|
||||
text:cutText
|
||||
focus: false
|
||||
padding: 0
|
||||
height: visible ? 36 : 0
|
||||
visible: {
|
||||
if(inputItem){
|
||||
return inputItem.selectedText !== "" && !inputItem.readOnly
|
||||
}
|
||||
return false
|
||||
}
|
||||
onClicked: {
|
||||
inputItem.cut()
|
||||
menu.close()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
display: Button.TextOnly
|
||||
text:copyText
|
||||
focus: false
|
||||
padding: 0
|
||||
height: visible ? 36 : 0
|
||||
visible: {
|
||||
if(inputItem){
|
||||
return inputItem.selectedText !== ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
onClicked: {
|
||||
inputItem.copy()
|
||||
menu.close()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
display: Button.TextOnly
|
||||
text:pasteText
|
||||
focus: false
|
||||
padding: 0
|
||||
visible: {
|
||||
if(inputItem){
|
||||
return !inputItem.readOnly
|
||||
}
|
||||
return false
|
||||
}
|
||||
height: visible ? 36 : 0
|
||||
onClicked: {
|
||||
inputItem.paste()
|
||||
menu.close()
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
display: Button.TextOnly
|
||||
text:selectAllText
|
||||
focus: false
|
||||
padding: 0
|
||||
height: visible ? 36 : 0
|
||||
visible: {
|
||||
if(inputItem){
|
||||
return inputItem.text !== ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
onClicked: {
|
||||
inputItem.selectAll()
|
||||
menu.close()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color normalColor: FluTheme.primaryColor
|
||||
property color hoverColor: FluTheme.dark ? Qt.darker(normalColor,1.15) : Qt.lighter(normalColor,1.15)
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.3) : Qt.lighter(normalColor,1.3)
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
property color backgroundHoverColor: FluTheme.itemHoverColor
|
||||
property color backgroundPressedColor: FluTheme.itemPressColor
|
||||
property color backgroundNormalColor: FluTheme.itemNormalColor
|
||||
property color backgroundDisableColor: FluTheme.itemNormalColor
|
||||
property bool textBold: true
|
||||
property color textColor: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
id: control
|
||||
horizontalPadding:6
|
||||
enabled: !disabled
|
||||
font:FluTextStyle.Body
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
radius: 4
|
||||
color: {
|
||||
if(!enabled){
|
||||
return backgroundDisableColor
|
||||
}
|
||||
if(pressed){
|
||||
return backgroundPressedColor
|
||||
}
|
||||
if(hovered){
|
||||
return backgroundHoverColor
|
||||
}
|
||||
return backgroundNormalColor
|
||||
}
|
||||
FluFocusRectangle{
|
||||
visible: control.visualFocus
|
||||
radius:8
|
||||
}
|
||||
}
|
||||
focusPolicy:Qt.TabFocus
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
contentItem: FluText {
|
||||
id:btn_text
|
||||
text: control.text
|
||||
font: control.font
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: control.textColor
|
||||
}
|
||||
}
|
@ -1,429 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Rectangle {
|
||||
property color dividerColor: FluTheme.dark ? Qt.rgba(77/255,77/255,77/255,1) : Qt.rgba(239/255,239/255,239/255,1)
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(251/255,251/255,251/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(61/255,61/255,61/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
property int hourFormat: FluTimePickerType.H
|
||||
property int isH: hourFormat === FluTimePickerType.H
|
||||
property var current
|
||||
property string amText: "上午"
|
||||
property string pmText: "下午"
|
||||
property string hourText: "时"
|
||||
property string minuteText: "分"
|
||||
property string cancelText: "取消"
|
||||
property string okText: "确定"
|
||||
signal accepted()
|
||||
id:control
|
||||
color: {
|
||||
if(mouse_area.containsMouse){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
height: 30
|
||||
width: 300
|
||||
radius: 4
|
||||
border.width: 1
|
||||
border.color: dividerColor
|
||||
Component.onCompleted: {
|
||||
if(current){
|
||||
var now = current;
|
||||
var hour
|
||||
var ampm;
|
||||
if(isH){
|
||||
hour = now.getHours();
|
||||
if(hour>12){
|
||||
ampm = control.pmText
|
||||
hour = hour-12
|
||||
}else{
|
||||
ampm = control.amText
|
||||
}
|
||||
}else{
|
||||
hour = now.getHours();
|
||||
}
|
||||
hour = text_hour.text === control.hourText ? hour.toString().padStart(2, '0') : text_hour.text
|
||||
var minute = text_minute.text === control.minuteText ? now.getMinutes().toString().padStart(2, '0') : text_minute.text
|
||||
ampm = text_ampm.text === "%1/%2".arg(control.amText).arg(control.pmText) ? ampm : text_ampm.text
|
||||
text_hour.text = hour
|
||||
text_minute.text = minute
|
||||
if(isH){
|
||||
text_ampm.text = ampm
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property var window: Window.window
|
||||
property bool changeFlag: true
|
||||
property var rowData: ["","",""]
|
||||
visible: false
|
||||
|
||||
|
||||
}
|
||||
MouseArea{
|
||||
id: mouse_area
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
popup.showPopup()
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id: divider_1
|
||||
width: 1
|
||||
x: isH ? parent.width/3 : parent.width/2
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
Rectangle{
|
||||
id: divider_2
|
||||
width: 1
|
||||
x: parent.width*2/3
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
visible: isH
|
||||
}
|
||||
FluText{
|
||||
id: text_hour
|
||||
anchors{
|
||||
left: parent.left
|
||||
right: divider_1.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: control.hourText
|
||||
}
|
||||
FluText{
|
||||
id: text_minute
|
||||
anchors{
|
||||
left: divider_1.right
|
||||
right: isH ? divider_2.left : parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: control.minuteText
|
||||
}
|
||||
FluText{
|
||||
id:text_ampm
|
||||
visible: isH
|
||||
anchors{
|
||||
left: divider_2.right
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "%1/%2".arg(control.amText).arg(control.pmText)
|
||||
}
|
||||
Menu{
|
||||
id:popup
|
||||
width: container.width
|
||||
height: container.height
|
||||
modal: true
|
||||
Overlay.modal: Item {}
|
||||
enter: Transition {
|
||||
reversible: true
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:0
|
||||
to:1
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
exit:Transition {
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
from:1
|
||||
to:0
|
||||
duration: FluTheme.enableAnimation ? 83 : 0
|
||||
}
|
||||
}
|
||||
background:Item{
|
||||
FluShadow{
|
||||
radius: 4
|
||||
}
|
||||
}
|
||||
contentItem: Item{
|
||||
clip: true
|
||||
Rectangle{
|
||||
id:container
|
||||
height: 340
|
||||
width: 300
|
||||
radius: 4
|
||||
color: FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(248/255,250/255,253/255,1)
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
}
|
||||
RowLayout{
|
||||
id:layout_content
|
||||
spacing: 0
|
||||
width: parent.width
|
||||
height: 300
|
||||
Component{
|
||||
id:list_delegate
|
||||
Item{
|
||||
height:38
|
||||
width:getListView().width
|
||||
function getListView(){
|
||||
if(type === 0)
|
||||
return list_view_1
|
||||
if(type === 1)
|
||||
return list_view_2
|
||||
if(type === 2)
|
||||
return list_view_3
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 2
|
||||
anchors.bottomMargin: 2
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
color: {
|
||||
if(getListView().currentIndex === position){
|
||||
return item_mouse.containsMouse ? Qt.darker(FluTheme.primaryColor,1.1) : FluTheme.primaryColor
|
||||
}
|
||||
if(item_mouse.containsMouse){
|
||||
return FluTheme.dark ? Qt.rgba(63/255,60/255,61/255,1) : Qt.rgba(237/255,237/255,242/255,1)
|
||||
}
|
||||
return FluTheme.dark ? Qt.rgba(51/255,48/255,48/255,1) : Qt.rgba(0,0,0,0)
|
||||
}
|
||||
radius: 3
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
getListView().currentIndex = position
|
||||
if(type === 0){
|
||||
text_hour.text = model
|
||||
}
|
||||
if(type === 1){
|
||||
text_minute.text = model
|
||||
}
|
||||
if(type === 2){
|
||||
text_ampm.text = model
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
text:model
|
||||
color: {
|
||||
if(getListView().currentIndex === position){
|
||||
if(FluTheme.dark){
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}else{
|
||||
return FluTheme.dark ? "#FFFFFF" : "#1A1A1A"
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ListView{
|
||||
id:list_view_1
|
||||
width: isH ? 100 : 150
|
||||
height: parent.height
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
model: isH ? generateArray(1,12) : generateArray(0,23)
|
||||
clip: true
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:0
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
}
|
||||
ListView{
|
||||
id:list_view_2
|
||||
width: isH ? 100 : 150
|
||||
height: parent.height
|
||||
model: generateArray(0,59)
|
||||
clip: true
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:1
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: dividerColor
|
||||
visible: isH
|
||||
}
|
||||
ListView{
|
||||
id:list_view_3
|
||||
width: 100
|
||||
height: 76
|
||||
model: [control.amText,control.pmText]
|
||||
clip: true
|
||||
visible: isH
|
||||
preferredHighlightBegin: 0
|
||||
preferredHighlightEnd: 0
|
||||
highlightMoveDuration: 0
|
||||
ScrollBar.vertical: FluScrollBar {}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
boundsBehavior:Flickable.StopAtBounds
|
||||
delegate: FluLoader{
|
||||
property var model: modelData
|
||||
property int type:2
|
||||
property int position:index
|
||||
sourceComponent: list_delegate
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.top: layout_content.bottom
|
||||
color: dividerColor
|
||||
}
|
||||
Rectangle{
|
||||
id:layout_actions
|
||||
height: 40
|
||||
radius: 5
|
||||
color: FluTheme.dark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1)
|
||||
anchors{
|
||||
bottom:parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
Item {
|
||||
id:divider
|
||||
width: 1
|
||||
height: parent.height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
FluButton{
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 20
|
||||
rightMargin: 10
|
||||
right: divider.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: control.cancelText
|
||||
onClicked: {
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
FluFilledButton{
|
||||
anchors{
|
||||
right: parent.right
|
||||
left: divider.right
|
||||
rightMargin: 20
|
||||
leftMargin: 10
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
text: control.okText
|
||||
onClicked: {
|
||||
d.changeFlag = false
|
||||
popup.close()
|
||||
const hours = text_hour.text
|
||||
const minutes = text_minute.text
|
||||
const period = text_ampm.text
|
||||
const date = new Date()
|
||||
var hours24 = parseInt(hours);
|
||||
if(control.hourFormat === FluTimePickerType.H){
|
||||
if (hours === "12") {
|
||||
hours24 = (period === control.amText) ? 0 : 12;
|
||||
} else {
|
||||
hours24 = (period === control.pmText) ? hours24 : hours24 + 12;
|
||||
}
|
||||
}
|
||||
date.setHours(hours24);
|
||||
date.setMinutes(parseInt(minutes));
|
||||
date.setSeconds(0);
|
||||
current = date
|
||||
control.accepted()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
y:35
|
||||
function showPopup() {
|
||||
d.changeFlag = true
|
||||
d.rowData[0] = text_hour.text
|
||||
d.rowData[1] = text_minute.text
|
||||
d.rowData[2] = text_ampm.text
|
||||
var now = new Date();
|
||||
var hour
|
||||
var ampm;
|
||||
if(isH){
|
||||
hour = now.getHours();
|
||||
if(hour>12){
|
||||
ampm = control.pmText
|
||||
hour = hour-12
|
||||
}else{
|
||||
ampm = control.amText
|
||||
}
|
||||
}else{
|
||||
hour = now.getHours();
|
||||
}
|
||||
hour = text_hour.text === control.hourText ? hour.toString().padStart(2, '0') : text_hour.text
|
||||
var minute = text_minute.text === control.minuteText ? now.getMinutes().toString().padStart(2, '0') : text_minute.text
|
||||
ampm = text_ampm.text === "%1/%2".arg(control.amText).arg(control.pmText) ? ampm : text_ampm.text
|
||||
list_view_1.currentIndex = list_view_1.model.indexOf(hour);
|
||||
list_view_2.currentIndex = list_view_2.model.indexOf(minute);
|
||||
list_view_3.currentIndex = list_view_3.model.indexOf(ampm);
|
||||
text_hour.text = hour
|
||||
text_minute.text = minute
|
||||
if(isH){
|
||||
text_ampm.text = ampm
|
||||
}
|
||||
var pos = control.mapToItem(null, 0, 0)
|
||||
if(d.window.height>pos.y+control.height+container.height){
|
||||
popup.y = control.height
|
||||
} else if(pos.y>container.height){
|
||||
popup.y = -container.height
|
||||
} else {
|
||||
popup.y = d.window.height-(pos.y+container.height)
|
||||
}
|
||||
popup.open()
|
||||
}
|
||||
onClosed: {
|
||||
if(d.changeFlag){
|
||||
text_hour.text = d.rowData[0]
|
||||
text_minute.text = d.rowData[1]
|
||||
text_ampm.text = d.rowData[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
function generateArray(start, n) {
|
||||
var arr = [];
|
||||
for (var i = start; i <= n; i++) {
|
||||
arr.push(i.toString().padStart(2, '0'));
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
@ -1,309 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import FluentUI
|
||||
|
||||
Item{
|
||||
property int mode: FluTimelineType.Left
|
||||
property alias model: repeater.model
|
||||
property color lineColor: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
|
||||
id:control
|
||||
implicitWidth: 380
|
||||
implicitHeight: layout_column.height
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isLeft: control.mode === FluTimelineType.Left
|
||||
property bool isRight: control.mode === FluTimelineType.Right
|
||||
property bool isAlternate: control.mode === FluTimelineType.Alternate
|
||||
property bool hasLable: {
|
||||
if(!model){
|
||||
return false
|
||||
}
|
||||
for(var i=0;i<model.count;i++){
|
||||
var lable = model.get(i).lable
|
||||
if(lable !== undefined && undefined !== ""){
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
property string stateName : {
|
||||
if(hasLable){
|
||||
return "Center"
|
||||
}
|
||||
if(isRight){
|
||||
return "Right"
|
||||
}
|
||||
if(isAlternate){
|
||||
return "Center"
|
||||
}
|
||||
return "Left"
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
id:rect_line
|
||||
color: control.lineColor
|
||||
height: {
|
||||
if(repeater.count===0){
|
||||
return parent.height
|
||||
}
|
||||
return parent.height - layout_column.children[repeater.count-1].height
|
||||
}
|
||||
width: 2
|
||||
visible: repeater.count!==0
|
||||
state: d.stateName
|
||||
states: [
|
||||
State {
|
||||
name: "Left"
|
||||
AnchorChanges {
|
||||
target: rect_line
|
||||
anchors.left: control.left
|
||||
}
|
||||
PropertyChanges {
|
||||
target: rect_line
|
||||
anchors.leftMargin: 7
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Right"
|
||||
AnchorChanges {
|
||||
target: rect_line
|
||||
anchors.right: control.right
|
||||
}
|
||||
PropertyChanges {
|
||||
target: rect_line
|
||||
anchors.rightMargin: 7
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Center"
|
||||
AnchorChanges {
|
||||
target: rect_line
|
||||
anchors.horizontalCenter: control.horizontalCenter
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Component{
|
||||
id:com_dot
|
||||
Rectangle{
|
||||
width: 16
|
||||
height: 16
|
||||
radius: 8
|
||||
border.width: 4
|
||||
color:FluTheme.dark ? Qt.rgba(0,0,0,1) : Qt.rgba(1,1,1,1)
|
||||
border.color: FluTheme.primaryColor
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_lable
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: {
|
||||
if(modelData.lable){
|
||||
return modelData.lable
|
||||
}
|
||||
return ""
|
||||
}
|
||||
color: FluTheme.primaryColor
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id:com_text
|
||||
FluText{
|
||||
wrapMode: Text.WrapAnywhere
|
||||
horizontalAlignment: isRight ? Qt.AlignRight : Qt.AlignLeft
|
||||
text: modelData.text
|
||||
textFormat: Text.RichText
|
||||
}
|
||||
}
|
||||
|
||||
Column{
|
||||
id:layout_column
|
||||
spacing: 30
|
||||
width: control.width
|
||||
height: repeater.count === 0 ? 1 : childrenRect.height
|
||||
Repeater{
|
||||
id:repeater
|
||||
Item{
|
||||
id:item_layout
|
||||
width: layout_column.width
|
||||
height: loader_text.height
|
||||
FluLoader{
|
||||
id:item_loader
|
||||
state: d.stateName
|
||||
states: [
|
||||
State {
|
||||
name: "Left"
|
||||
AnchorChanges {
|
||||
target: item_loader
|
||||
anchors.left: item_layout.left
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Right"
|
||||
AnchorChanges {
|
||||
target: item_loader
|
||||
anchors.right: item_layout.right
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Center"
|
||||
AnchorChanges {
|
||||
target: item_loader
|
||||
anchors.horizontalCenter: item_layout.horizontalCenter
|
||||
}
|
||||
}
|
||||
]
|
||||
sourceComponent: {
|
||||
if(model.dot)
|
||||
return model.dot()
|
||||
return com_dot
|
||||
}
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
property var modelData: control.model.get(index)
|
||||
property bool isRight: state === "Right"
|
||||
id:loader_lable
|
||||
sourceComponent: {
|
||||
if(!modelData){
|
||||
return undefined
|
||||
}
|
||||
var lableDelegate = model.lableDelegate
|
||||
if(lableDelegate instanceof Function && lableDelegate() instanceof Component){
|
||||
return lableDelegate()
|
||||
}
|
||||
return com_lable
|
||||
}
|
||||
state: {
|
||||
if(d.isRight){
|
||||
return "Left"
|
||||
}
|
||||
if(d.isAlternate){
|
||||
if(index%2===0){
|
||||
return "Right"
|
||||
}else{
|
||||
return "Left"
|
||||
}
|
||||
}
|
||||
return "Right"
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
name: "Left"
|
||||
AnchorChanges {
|
||||
target: loader_lable
|
||||
anchors.left: item_loader.right
|
||||
anchors.right: item_layout.right
|
||||
}
|
||||
PropertyChanges {
|
||||
target: loader_lable
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Right"
|
||||
AnchorChanges {
|
||||
target: loader_lable
|
||||
anchors.right: item_loader.left
|
||||
anchors.left: item_layout.left
|
||||
}
|
||||
PropertyChanges {
|
||||
target: loader_lable
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Center"
|
||||
AnchorChanges {
|
||||
target: loader_lable
|
||||
anchors.right: item_loader.left
|
||||
anchors.left: item_layout.left
|
||||
}
|
||||
PropertyChanges {
|
||||
target: loader_lable
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
id:loader_text
|
||||
property var modelData: control.model.get(index)
|
||||
property bool isRight: state === "Right"
|
||||
state: {
|
||||
if(d.isRight){
|
||||
return "Right"
|
||||
}
|
||||
if(d.isAlternate){
|
||||
if(index%2===0){
|
||||
return "Left"
|
||||
}else{
|
||||
return "Right"
|
||||
}
|
||||
}
|
||||
return "Left"
|
||||
}
|
||||
sourceComponent: {
|
||||
if(!modelData){
|
||||
return undefined
|
||||
}
|
||||
var textDelegate = model.textDelegate
|
||||
if(textDelegate instanceof Function && textDelegate() instanceof Component){
|
||||
return textDelegate()
|
||||
}
|
||||
return com_text
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
name: "Left"
|
||||
AnchorChanges {
|
||||
target: loader_text
|
||||
anchors.left: item_loader.right
|
||||
anchors.right: item_layout.right
|
||||
}
|
||||
PropertyChanges {
|
||||
target: loader_text
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Right"
|
||||
AnchorChanges {
|
||||
target: loader_text
|
||||
anchors.right: item_loader.left
|
||||
anchors.left: item_layout.left
|
||||
}
|
||||
PropertyChanges {
|
||||
target: loader_text
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Center"
|
||||
AnchorChanges {
|
||||
target: loader_text
|
||||
anchors.right: item_loader.left
|
||||
anchors.left: item_layout.left
|
||||
}
|
||||
PropertyChanges {
|
||||
target: loader_text
|
||||
anchors.leftMargin: 14
|
||||
anchors.rightMargin: 14
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color normalColor: {
|
||||
if(checked){
|
||||
return FluTheme.primaryColor
|
||||
}else{
|
||||
return FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(254/255,254/255,254/255,1)
|
||||
}
|
||||
}
|
||||
property color hoverColor: {
|
||||
if(checked){
|
||||
return FluTheme.dark ? Qt.darker(normalColor,1.1) : Qt.lighter(normalColor,1.1)
|
||||
}else{
|
||||
return FluTheme.dark ? Qt.rgba(68/255,68/255,68/255,1) : Qt.rgba(246/255,246/255,246/255,1)
|
||||
}
|
||||
}
|
||||
property color disableColor: {
|
||||
if(checked){
|
||||
return FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(199/255,199/255,199/255,1)
|
||||
}else{
|
||||
return FluTheme.dark ? Qt.rgba(59/255,59/255,59/255,1) : Qt.rgba(244/255,244/255,244/255,1)
|
||||
}
|
||||
}
|
||||
property var clickListener : function(){
|
||||
checked = !checked
|
||||
}
|
||||
property color pressedColor: FluTheme.dark ? Qt.darker(normalColor,1.2) : Qt.lighter(normalColor,1.2)
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
focusPolicy:Qt.TabFocus
|
||||
id: control
|
||||
enabled: !disabled
|
||||
verticalPadding: 0
|
||||
horizontalPadding:12
|
||||
onClicked: clickListener()
|
||||
background: Rectangle{
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
radius: 4
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius:4
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.33; color: control.enabled ? control.normalColor : Qt.rgba(0,0,0,0) }
|
||||
GradientStop { position: 1.0; color: control.enabled ? Qt.darker(control.normalColor,1.3) : Qt.rgba(0,0,0,0) }
|
||||
}
|
||||
Rectangle{
|
||||
radius: parent.radius
|
||||
anchors{
|
||||
fill: parent
|
||||
topMargin: checked && enabled ? 0 : 0
|
||||
leftMargin: checked && enabled ? 1 : 0
|
||||
rightMargin: checked && enabled ? 1 : 0
|
||||
bottomMargin: checked && enabled ? 2 : 0
|
||||
}
|
||||
color:{
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(checked){
|
||||
if(pressed){
|
||||
return pressedColor
|
||||
}
|
||||
}
|
||||
return hovered ? hoverColor :normalColor
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
color:"#00000000"
|
||||
anchors.fill: parent
|
||||
border.color: FluTheme.dark ? "#505050" : "#DFDFDF"
|
||||
border.width: checked ? 0 : 1
|
||||
radius: parent.radius
|
||||
}
|
||||
}
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: {
|
||||
if(checked){
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(173/255,173/255,173/255,1)
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}else{
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}
|
||||
}else{
|
||||
if(FluTheme.dark){
|
||||
if(!enabled){
|
||||
return Qt.rgba(131/255,131/255,131/255,1)
|
||||
}
|
||||
if(!checked){
|
||||
if(pressed){
|
||||
return Qt.rgba(162/255,162/255,162/255,1)
|
||||
}
|
||||
}
|
||||
return Qt.rgba(1,1,1,1)
|
||||
}else{
|
||||
if(!enabled){
|
||||
return Qt.rgba(160/255,160/255,160/255,1)
|
||||
}
|
||||
if(!checked){
|
||||
if(pressed){
|
||||
return Qt.rgba(96/255,96/255,96/255,1)
|
||||
}
|
||||
}
|
||||
return Qt.rgba(0,0,0,1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Button {
|
||||
property bool disabled: false
|
||||
property string contentDescription: ""
|
||||
property color disableColor: FluTheme.dark ? Qt.rgba(82/255,82/255,82/255,1) : Qt.rgba(233/255,233/255,233/255,1)
|
||||
property color checkColor: FluTheme.primaryColor
|
||||
property color hoverColor: FluTheme.dark ? Qt.rgba(62/255,62/255,62/255,1) : Qt.rgba(240/255,240/255,240/255,1)
|
||||
property color normalColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(253/255,253/255,253/255,1)
|
||||
property color borderNormalColor: FluTheme.dark ? Qt.rgba(161/255,161/255,161/255,1) : Qt.rgba(141/255,141/255,141/255,1)
|
||||
property color borderCheckColor: FluTheme.primaryColor
|
||||
property color borderDisableColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(200/255,200/255,200/255,1)
|
||||
property color dotNormalColor: FluTheme.dark ? Qt.rgba(208/255,208/255,208/255,1) : Qt.rgba(93/255,93/255,93/255,1)
|
||||
property color dotCheckColor: FluTheme.dark ? Qt.rgba(0/255,0/255,0/255,1) : Qt.rgba(255/255,255/255,255/255,1)
|
||||
property color dotDisableColor: FluTheme.dark ? Qt.rgba(50/255,50/255,50/255,1) : Qt.rgba(150/255,150/255,150/255,1)
|
||||
property real textSpacing: 6
|
||||
property bool textRight: true
|
||||
property alias textColor: btn_text.textColor
|
||||
property var clickListener : function(){
|
||||
checked = !checked
|
||||
}
|
||||
id: control
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: control.text
|
||||
Accessible.description: contentDescription
|
||||
Accessible.onPressAction: control.clicked()
|
||||
enabled: !disabled
|
||||
focusPolicy:Qt.TabFocus
|
||||
onClicked: clickListener()
|
||||
padding: 0
|
||||
horizontalPadding: 0
|
||||
onCheckableChanged: {
|
||||
if(checkable){
|
||||
checkable = false
|
||||
}
|
||||
}
|
||||
background : Item{
|
||||
implicitHeight: 20
|
||||
implicitWidth: 40
|
||||
}
|
||||
contentItem: RowLayout{
|
||||
spacing: control.textSpacing
|
||||
layoutDirection:control.textRight ? Qt.LeftToRight : Qt.RightToLeft
|
||||
Rectangle {
|
||||
id:control_backgound
|
||||
implicitWidth: background.implicitWidth
|
||||
implicitHeight: background.implicitHeight
|
||||
radius: height / 2
|
||||
FluFocusRectangle{
|
||||
visible: control.activeFocus
|
||||
radius: parent.radius
|
||||
}
|
||||
color: {
|
||||
if(!enabled){
|
||||
return disableColor
|
||||
}
|
||||
if(checked){
|
||||
return checkColor
|
||||
}
|
||||
if(hovered){
|
||||
return hoverColor
|
||||
}
|
||||
return normalColor
|
||||
}
|
||||
border.width: 1
|
||||
border.color: {
|
||||
if(!enabled){
|
||||
return borderDisableColor
|
||||
}
|
||||
if(checked){
|
||||
return borderCheckColor
|
||||
}
|
||||
return borderNormalColor
|
||||
}
|
||||
FluIcon {
|
||||
width: parent.height
|
||||
x:checked ? control_backgound.width-width : 0
|
||||
scale: {
|
||||
if(pressed){
|
||||
return 5/10
|
||||
}
|
||||
return hovered&enabled ? 7/10 : 6/10
|
||||
}
|
||||
iconSource: FluentIcons.FullCircleMask
|
||||
iconSize: 20
|
||||
color: {
|
||||
if(!enabled){
|
||||
return dotDisableColor
|
||||
}
|
||||
if(checked){
|
||||
return dotCheckColor
|
||||
}
|
||||
return dotNormalColor
|
||||
}
|
||||
Behavior on scale{
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
Behavior on x {
|
||||
enabled: FluTheme.enableAnimation
|
||||
NumberAnimation {
|
||||
duration: 167
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
id:btn_text
|
||||
text: control.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: text !== ""
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls.impl
|
||||
import QtQuick.Templates as T
|
||||
import FluentUI
|
||||
|
||||
T.ToolTip {
|
||||
id: control
|
||||
x: parent ? (parent.width - implicitWidth) / 2 : 0
|
||||
y: -implicitHeight - 3
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
contentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
contentHeight + topPadding + bottomPadding)
|
||||
margins: 6
|
||||
padding: 6
|
||||
font: FluTextStyle.Body
|
||||
closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnReleaseOutsideParent
|
||||
contentItem: FluText {
|
||||
text: control.text
|
||||
font: control.font
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
background: Rectangle {
|
||||
color: FluTheme.dark ? Qt.rgba(50/255,49/255,48/255,1) : Qt.rgba(1,1,1,1)
|
||||
radius: 3
|
||||
FluShadow{
|
||||
radius: 3
|
||||
}
|
||||
}
|
||||
}
|
@ -1,250 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Shapes
|
||||
import QtQuick.Window
|
||||
import FluentUI
|
||||
|
||||
Popup{
|
||||
property var steps : []
|
||||
property int targetMargins: 5
|
||||
property Component nextButton: com_next_button
|
||||
property Component prevButton: com_prev_button
|
||||
property int index : 0
|
||||
property string finishText: qsTr("Finish")
|
||||
property string nextText: qsTr("Next")
|
||||
property string previousText: qsTr("Previous")
|
||||
id:control
|
||||
padding: 0
|
||||
parent: Overlay.overlay
|
||||
width: d.parentWidth
|
||||
height: d.parentHeight
|
||||
background: Item{}
|
||||
contentItem: Item{}
|
||||
onVisibleChanged: {
|
||||
if(visible){
|
||||
control.index = 0
|
||||
}
|
||||
}
|
||||
onIndexChanged: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
Component{
|
||||
id: com_next_button
|
||||
FluFilledButton{
|
||||
text: isEnd ? control.finishText : control.nextText
|
||||
onClicked: {
|
||||
if(isEnd){
|
||||
control.close()
|
||||
}else{
|
||||
control.index = control.index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: com_prev_button
|
||||
FluButton{
|
||||
text: control.previousText
|
||||
onClicked: {
|
||||
control.index = control.index - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id:d
|
||||
property var window: Window.window
|
||||
property point pos: Qt.point(0,0)
|
||||
property var step: steps[index]
|
||||
property var target: {
|
||||
if(steps[index]){
|
||||
return steps[index].target()
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
property int parentHeight: {
|
||||
if(control.parent){
|
||||
return control.parent.height
|
||||
}
|
||||
return control.height
|
||||
}
|
||||
property int parentWidth: {
|
||||
if(control.parent){
|
||||
return control.parent.width
|
||||
}
|
||||
return control.width
|
||||
}
|
||||
}
|
||||
Connections{
|
||||
target: d.window
|
||||
function onWidthChanged(){
|
||||
canvas.requestPaint()
|
||||
timer_delay.restart()
|
||||
}
|
||||
function onHeightChanged(){
|
||||
canvas.requestPaint()
|
||||
timer_delay.restart()
|
||||
}
|
||||
}
|
||||
Timer{
|
||||
id: timer_delay
|
||||
interval: 200
|
||||
onTriggered: {
|
||||
canvas.requestPaint()
|
||||
}
|
||||
}
|
||||
Canvas{
|
||||
id: canvas
|
||||
anchors.fill: parent
|
||||
onPaint: {
|
||||
d.pos = d.target.mapToGlobal(0,0)
|
||||
d.pos = Qt.point(d.pos.x-d.window.x,d.pos.y-d.window.y)
|
||||
var ctx = canvas.getContext("2d")
|
||||
ctx.clearRect(0, 0, canvasSize.width, canvasSize.height)
|
||||
ctx.save()
|
||||
ctx.fillStyle = "#88000000"
|
||||
ctx.fillRect(0, 0, canvasSize.width, canvasSize.height)
|
||||
ctx.globalCompositeOperation = 'destination-out'
|
||||
ctx.fillStyle = 'black'
|
||||
var rect = Qt.rect(d.pos.x-control.targetMargins,d.pos.y-control.targetMargins, d.target.width+control.targetMargins*2, d.target.height+control.targetMargins*2)
|
||||
drawRoundedRect(rect,2,ctx)
|
||||
ctx.restore()
|
||||
}
|
||||
function drawRoundedRect(rect, r, ctx) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(rect.x + r, rect.y);
|
||||
ctx.lineTo(rect.x + rect.width - r, rect.y);
|
||||
ctx.arcTo(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + r, r);
|
||||
ctx.lineTo(rect.x + rect.width, rect.y + rect.height - r);
|
||||
ctx.arcTo(rect.x + rect.width, rect.y + rect.height, rect.x + rect.width - r, rect.y + rect.height, r);
|
||||
ctx.lineTo(rect.x + r, rect.y + rect.height);
|
||||
ctx.arcTo(rect.x, rect.y + rect.height, rect.x, rect.y + rect.height - r, r);
|
||||
ctx.lineTo(rect.x, rect.y + r);
|
||||
ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r);
|
||||
ctx.closePath();
|
||||
ctx.fill()
|
||||
}
|
||||
}
|
||||
FluArea{
|
||||
id: layout_panne
|
||||
radius: 5
|
||||
width: 500
|
||||
height: 88 + text_desc.height
|
||||
color: FluTheme.dark ? Qt.rgba(39/255,39/255,39/255,1) : Qt.rgba(251/255,251/255,253/255,1)
|
||||
property int dir : {
|
||||
if(y<d.pos.y)
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
x: {
|
||||
if(d.target){
|
||||
return Math.min(Math.max(0,d.pos.x+d.target.width/2-width/2),control.width-width)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
y: {
|
||||
if(d.target){
|
||||
var ty=d.pos.y+d.target.height+control.targetMargins + 15
|
||||
if((ty+height)>control.height)
|
||||
return d.pos.y-height-control.targetMargins - 15
|
||||
return ty
|
||||
}
|
||||
return 0
|
||||
}
|
||||
border.width: 0
|
||||
FluShadow{
|
||||
radius: 5
|
||||
}
|
||||
FluText{
|
||||
text: {
|
||||
if(d.step){
|
||||
return d.step.title
|
||||
}
|
||||
return ""
|
||||
}
|
||||
font: FluTextStyle.BodyStrong
|
||||
elide: Text.ElideRight
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: 15
|
||||
leftMargin: 15
|
||||
right: parent.right
|
||||
rightMargin: 32
|
||||
}
|
||||
}
|
||||
FluText{
|
||||
id: text_desc
|
||||
font: FluTextStyle.Body
|
||||
wrapMode: Text.WrapAnywhere
|
||||
maximumLineCount: 4
|
||||
elide: Text.ElideRight
|
||||
text: {
|
||||
if(d.step){
|
||||
return d.step.description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
rightMargin: 15
|
||||
topMargin: 42
|
||||
leftMargin: 15
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id: loader_next
|
||||
property bool isEnd: control.index === steps.length-1
|
||||
sourceComponent: com_next_button
|
||||
anchors{
|
||||
top: text_desc.bottom
|
||||
topMargin: 10
|
||||
right: parent.right
|
||||
rightMargin: 15
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id: loader_prev
|
||||
visible: control.index !== 0
|
||||
sourceComponent: com_prev_button
|
||||
anchors{
|
||||
right: loader_next.left
|
||||
top: loader_next.top
|
||||
rightMargin: 14
|
||||
}
|
||||
}
|
||||
FluIconButton{
|
||||
anchors{
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
margins: 10
|
||||
}
|
||||
width: 26
|
||||
height: 26
|
||||
verticalPadding: 0
|
||||
horizontalPadding: 0
|
||||
iconSize: 12
|
||||
iconSource: FluentIcons.ChromeClose
|
||||
onClicked: {
|
||||
control.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
FluIcon{
|
||||
iconSource: layout_panne.dir?FluentIcons.FlickUp:FluentIcons.FlickDown
|
||||
color: layout_panne.color
|
||||
x: {
|
||||
if(d.target){
|
||||
return d.pos.x+d.target.width/2-10
|
||||
}
|
||||
return 0
|
||||
}
|
||||
y: {
|
||||
if(d.target){
|
||||
return d.pos.y+(layout_panne.dir?-height:d.target.height)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
@ -1,440 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Qt.labs.qmlmodels
|
||||
import FluentUI
|
||||
|
||||
Item {
|
||||
property int currentIndex : -1
|
||||
property var dataSource
|
||||
property bool showLine: true
|
||||
property bool draggable: false
|
||||
property int cellHeight: 30
|
||||
property int depthPadding: 30
|
||||
property bool checkable: false
|
||||
property color lineColor: FluTheme.dark ? Qt.rgba(111/255,111/255,111/255,1) : Qt.rgba(217/255,217/255,217/255,1)
|
||||
id:control
|
||||
QtObject {
|
||||
id:d
|
||||
property int dy
|
||||
property var current
|
||||
property int dropIndex: -1
|
||||
property bool isDropTopArea: false
|
||||
property int dragIndex: -1
|
||||
property color hitColor: FluTheme.primaryColor
|
||||
}
|
||||
onDataSourceChanged: {
|
||||
tree_model.setDataSource(dataSource)
|
||||
}
|
||||
FluTreeModel{
|
||||
id:tree_model
|
||||
}
|
||||
ListView{
|
||||
id:table_view
|
||||
ScrollBar.horizontal: FluScrollBar{}
|
||||
ScrollBar.vertical: FluScrollBar{}
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
model: tree_model
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
flickableDirection: Flickable.HorizontalAndVerticalFlick
|
||||
contentWidth: contentItem.childrenRect.width
|
||||
reuseItems: true
|
||||
removeDisplaced : Transition{
|
||||
ParallelAnimation{
|
||||
NumberAnimation {
|
||||
properties: "y"
|
||||
duration: 167
|
||||
from: d.dy + table_view.height
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
duration: 88
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
move: Transition {
|
||||
NumberAnimation { property: "y"; duration: 200 }
|
||||
}
|
||||
add: Transition{
|
||||
ParallelAnimation{
|
||||
NumberAnimation {
|
||||
properties: "y"
|
||||
duration: 167
|
||||
from: d.dy - control.cellHeight
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
duration: 88
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: Item {
|
||||
id:item_control
|
||||
implicitWidth: item_loader_container.width
|
||||
implicitHeight: item_loader_container.height
|
||||
ListView.onReused: {
|
||||
item_loader_container.item.reused()
|
||||
}
|
||||
ListView.onPooled: {
|
||||
item_loader_container.item.pooled()
|
||||
}
|
||||
FluLoader{
|
||||
property var itemControl: item_control
|
||||
property var itemModel: dataModel
|
||||
property int rowIndex: index
|
||||
property bool isItemLoader: true
|
||||
id:item_loader_container
|
||||
sourceComponent: com_item_container
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_container
|
||||
property var itemControl
|
||||
property var itemModel
|
||||
property bool isItemLoader: false
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_item_container
|
||||
Item{
|
||||
signal reused
|
||||
signal pooled
|
||||
onReused: {
|
||||
|
||||
}
|
||||
onPooled: {
|
||||
}
|
||||
property bool isCurrent: d.current === itemModel
|
||||
id:item_container
|
||||
width: {
|
||||
var w = 46 + item_loader_cell.width + control.depthPadding*itemModel.depth
|
||||
if(control.width>w){
|
||||
return control.width
|
||||
}
|
||||
return w
|
||||
}
|
||||
height: control.cellHeight
|
||||
implicitWidth: width
|
||||
implicitHeight: height
|
||||
function toggle(){
|
||||
var pos = FluTools.cursorPos()
|
||||
var viewPos = table_view.mapToGlobal(0,0)
|
||||
d.dy = table_view.contentY + pos.y-viewPos.y
|
||||
if(itemModel.isExpanded){
|
||||
tree_model.collapse(rowIndex)
|
||||
}else{
|
||||
tree_model.expand(rowIndex)
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
width: 3
|
||||
height: 18
|
||||
radius: 1.5
|
||||
color: FluTheme.primaryColor
|
||||
visible: isCurrent
|
||||
anchors{
|
||||
left: parent.left
|
||||
leftMargin: 6
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
id:item_mouse
|
||||
property point clickPos: Qt.point(0,0)
|
||||
anchors.fill: parent
|
||||
drag.target:control.draggable ? loader_container : undefined
|
||||
hoverEnabled: true
|
||||
drag.onActiveChanged: {
|
||||
if(drag.active){
|
||||
if(itemModel.isExpanded && itemModel.hasChildren()){
|
||||
tree_model.collapse(rowIndex)
|
||||
}
|
||||
d.dragIndex = rowIndex
|
||||
loader_container.sourceComponent = com_item_container
|
||||
}
|
||||
}
|
||||
onPressed:
|
||||
(mouse)=>{
|
||||
clickPos = Qt.point(mouse.x,mouse.y)
|
||||
loader_container.itemControl = itemControl
|
||||
loader_container.itemModel = itemModel
|
||||
var cellPosition = item_container.mapToItem(table_view, 0, 0)
|
||||
loader_container.width = item_container.width
|
||||
loader_container.height = item_container.height
|
||||
loader_container.x = 0
|
||||
loader_container.y = cellPosition.y
|
||||
}
|
||||
onClicked: {
|
||||
d.current = itemModel
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if(itemModel.hasChildren()){
|
||||
item_container.toggle()
|
||||
}
|
||||
}
|
||||
onPositionChanged:
|
||||
(mouse)=> {
|
||||
if(!drag.active){
|
||||
return
|
||||
}
|
||||
var cellPosition = item_container.mapToItem(table_view, 0, 0)
|
||||
if(mouse.y+cellPosition.y<0 || mouse.y+cellPosition.y>table_view.height){
|
||||
d.dropIndex = -1
|
||||
return
|
||||
}
|
||||
if((mouse.x-table_view.contentX)>table_view.width || (mouse.x-table_view.contentX)<0){
|
||||
d.dropIndex = -1
|
||||
return
|
||||
}
|
||||
var pos = FluTools.cursorPos()
|
||||
var viewPos = table_view.mapToGlobal(0,0)
|
||||
var y = table_view.contentY + pos.y-viewPos.y
|
||||
var index = Math.floor(y/control.cellHeight)
|
||||
if(index<0 || index>table_view.count-1){
|
||||
d.dropIndex = -1
|
||||
return
|
||||
}
|
||||
if(tree_model.hitHasChildrenExpanded(index) && y>index*control.cellHeight+control.cellHeight/2){
|
||||
d.dropIndex = index + 1
|
||||
d.isDropTopArea = true
|
||||
}else{
|
||||
d.dropIndex = index
|
||||
if(y>index*control.cellHeight+control.cellHeight/2){
|
||||
d.isDropTopArea = false
|
||||
}else{
|
||||
d.isDropTopArea = true
|
||||
}
|
||||
}
|
||||
}
|
||||
onCanceled: {
|
||||
loader_container.sourceComponent = undefined
|
||||
loader_container.x = 0
|
||||
loader_container.y = 0
|
||||
d.dropIndex = -1
|
||||
d.dragIndex = -1
|
||||
}
|
||||
onReleased: {
|
||||
loader_container.sourceComponent = undefined
|
||||
if(d.dropIndex !== -1){
|
||||
tree_model.dragAnddrop(d.dragIndex,d.dropIndex,d.isDropTopArea)
|
||||
}
|
||||
d.dropIndex = -1
|
||||
d.dragIndex = -1
|
||||
loader_container.x = 0
|
||||
loader_container.y = 0
|
||||
}
|
||||
}
|
||||
Drag.active: item_mouse.drag.active
|
||||
Rectangle{
|
||||
id:item_line_drop_tip
|
||||
anchors{
|
||||
left: layout_row.left
|
||||
leftMargin: 26
|
||||
right: parent.right
|
||||
rightMargin: 10
|
||||
bottom: parent.bottom
|
||||
bottomMargin: -1.5
|
||||
top: undefined
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
when:d.isDropTopArea
|
||||
AnchorChanges {
|
||||
target: item_line_drop_tip
|
||||
anchors.top: item_container.top
|
||||
anchors.bottom: undefined
|
||||
}
|
||||
PropertyChanges {
|
||||
target: item_line_drop_tip
|
||||
anchors.topMargin: -1.5
|
||||
}
|
||||
}
|
||||
]
|
||||
height: 3
|
||||
radius: 1.5
|
||||
color: d.hitColor
|
||||
visible: d.dropIndex === rowIndex
|
||||
Rectangle{
|
||||
width: 10
|
||||
height: 10
|
||||
radius: 5
|
||||
border.width: 3
|
||||
border.color: d.hitColor
|
||||
color: FluTheme.dark ? FluColors.Black : FluColors.White
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: -3
|
||||
leftMargin: -5
|
||||
}
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
width: 1
|
||||
color: control.lineColor
|
||||
visible: control.showLine && isItemLoader && itemModel.depth !== 0 && !itemModel.hasChildren()
|
||||
height: itemModel.hideLineFooter() ? parent.height/2 : parent.height
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: item_line_h.left
|
||||
}
|
||||
}
|
||||
FluRectangle{
|
||||
id:item_line_h
|
||||
height: 1
|
||||
color: control.lineColor
|
||||
visible: control.showLine && isItemLoader && itemModel.depth !== 0 && !itemModel.hasChildren()
|
||||
width: depthPadding - 10
|
||||
anchors{
|
||||
right: layout_row.left
|
||||
rightMargin: -24
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
Repeater{
|
||||
model: Math.max(itemModel.depth-1,0)
|
||||
delegate: FluRectangle{
|
||||
required property int index
|
||||
width: 1
|
||||
color: control.lineColor
|
||||
visible: control.showLine && isItemLoader && itemModel.depth !== 0 && itemModel.hasNextNodeByIndex(index)
|
||||
anchors{
|
||||
top:parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
leftMargin: control.depthPadding*(index+1) + 24
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
anchors.fill: parent
|
||||
radius: 4
|
||||
anchors.leftMargin: 6
|
||||
anchors.rightMargin: 6
|
||||
border.color: d.hitColor
|
||||
border.width: d.dragIndex === rowIndex ? 1 : 0
|
||||
color: {
|
||||
if(isCurrent){
|
||||
return FluTheme.itemCheckColor
|
||||
}
|
||||
if(item_mouse.containsMouse || item_check_box.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
if(item_loader_expand.item && item_loader_expand.item.hovered){
|
||||
return FluTheme.itemHoverColor
|
||||
}
|
||||
return FluTheme.itemNormalColor
|
||||
}
|
||||
}
|
||||
RowLayout{
|
||||
id:layout_row
|
||||
height: parent.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
spacing: 0
|
||||
anchors.leftMargin: 14 + control.depthPadding*itemModel.depth
|
||||
Component{
|
||||
id:com_icon_btn
|
||||
FluIconButton{
|
||||
opacity: itemModel.hasChildren()
|
||||
onClicked: {
|
||||
item_container.toggle()
|
||||
}
|
||||
contentItem:FluIcon{
|
||||
rotation: itemModel.isExpanded?0:-90
|
||||
iconSource:FluentIcons.ChevronDown
|
||||
iconSize: 16
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FluLoader{
|
||||
id:item_loader_expand
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 20
|
||||
sourceComponent: itemModel.hasChildren() ? com_icon_btn : undefined
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
FluCheckBox{
|
||||
id:item_check_box
|
||||
Layout.preferredWidth: 18
|
||||
Layout.preferredHeight: 18
|
||||
Layout.leftMargin: 5
|
||||
horizontalPadding:0
|
||||
verticalPadding: 0
|
||||
checked: itemModel.checked
|
||||
enableAnimation:false
|
||||
visible: control.checkable
|
||||
padding: 0
|
||||
clickListener: function(){
|
||||
tree_model.checkRow(rowIndex,!itemModel.checked)
|
||||
}
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
FluLoader{
|
||||
property var dataModel: itemModel
|
||||
property var itemMouse: item_mouse
|
||||
id:item_loader_cell
|
||||
Layout.leftMargin: 10
|
||||
Layout.preferredWidth: {
|
||||
if(item){
|
||||
return item.width
|
||||
}
|
||||
return 0
|
||||
}
|
||||
Layout.fillHeight: true
|
||||
sourceComponent:com_item_text
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_item_text
|
||||
Item{
|
||||
width: item_text.width
|
||||
FluText {
|
||||
id:item_text
|
||||
text: dataModel.title
|
||||
rightPadding: 14
|
||||
anchors.centerIn: parent
|
||||
color:{
|
||||
if(itemMouse.pressed){
|
||||
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
|
||||
}
|
||||
return FluTheme.dark ? FluColors.White : FluColors.Grey220
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function selectionModel(){
|
||||
return tree_model.selectionModel
|
||||
}
|
||||
function count(){
|
||||
return tree_model.dataSourceSize
|
||||
}
|
||||
function visibleCount(){
|
||||
return table_view.count
|
||||
}
|
||||
function collapse(rowIndex){
|
||||
tree_model.collapse(rowIndex)
|
||||
}
|
||||
function expand(rowIndex){
|
||||
tree_model.expand(rowIndex)
|
||||
}
|
||||
function allExpand(){
|
||||
tree_model.allExpand()
|
||||
}
|
||||
function allCollapse(){
|
||||
tree_model.allCollapse()
|
||||
}
|
||||
}
|
@ -1,320 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
Window {
|
||||
default property alias contentData : layout_content.data
|
||||
property string windowIcon: FluApp.windowIcon
|
||||
property int launchMode: FluWindowType.Standard
|
||||
property var argument:({})
|
||||
property var background : com_background
|
||||
property bool fixSize: false
|
||||
property Component loadingItem: com_loading
|
||||
property bool fitsAppBarWindows: false
|
||||
property Item appBar: FluAppBar {
|
||||
title: window.title
|
||||
height: 30
|
||||
showDark: window.showDark
|
||||
showClose: window.showClose
|
||||
showMinimize: window.showMinimize
|
||||
showMaximize: window.showMaximize
|
||||
showStayTop: window.showStayTop
|
||||
icon: window.windowIcon
|
||||
}
|
||||
property color backgroundColor: {
|
||||
if(active){
|
||||
return FluTheme.windowActiveBackgroundColor
|
||||
}
|
||||
return FluTheme.windowBackgroundColor
|
||||
}
|
||||
property bool stayTop: false
|
||||
property bool showDark: false
|
||||
property bool showClose: true
|
||||
property bool showMinimize: true
|
||||
property bool showMaximize: true
|
||||
property bool showStayTop: false
|
||||
property bool autoMaximize: false
|
||||
property bool autoVisible: true
|
||||
property bool autoCenter: true
|
||||
property bool autoDestory: true
|
||||
property bool useSystemAppBar
|
||||
property color resizeBorderColor: {
|
||||
if(window.active){
|
||||
return FluTheme.dark ? "#333333" : "#6E6E6E"
|
||||
}
|
||||
return FluTheme.dark ? "#3D3D3E" : "#A7A7A7"
|
||||
}
|
||||
property int resizeBorderWidth: 1
|
||||
property var closeListener: function(event){
|
||||
if(autoDestory){
|
||||
destoryOnClose()
|
||||
}else{
|
||||
visible = false
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
signal showSystemMenu
|
||||
signal initArgument(var argument)
|
||||
signal firstVisible()
|
||||
property int _realHeight
|
||||
property int _realWidth
|
||||
property int _appBarHeight: appBar.height
|
||||
property var _windowRegister
|
||||
property string _route
|
||||
id:window
|
||||
color:"transparent"
|
||||
Component.onCompleted: {
|
||||
_realHeight = height
|
||||
_realWidth = width
|
||||
useSystemAppBar = FluApp.useSystemAppBar
|
||||
if(useSystemAppBar && autoCenter){
|
||||
moveWindowToDesktopCenter()
|
||||
}
|
||||
fixWindowSize()
|
||||
lifecycle.onCompleted(window)
|
||||
initArgument(argument)
|
||||
if(!useSystemAppBar){
|
||||
loader_frameless_helper.sourceComponent = com_frameless_helper
|
||||
}
|
||||
if(window.autoVisible){
|
||||
if(window.autoMaximize){
|
||||
window.showMaximized()
|
||||
}else{
|
||||
window.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onDestruction: {
|
||||
lifecycle.onDestruction()
|
||||
}
|
||||
onShowSystemMenu: {
|
||||
if(loader_frameless_helper.item){
|
||||
loader_frameless_helper.item.showSystemMenu()
|
||||
}
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if(visible && d.isFirstVisible){
|
||||
window.firstVisible()
|
||||
d.isFirstVisible = false
|
||||
}
|
||||
lifecycle.onVisible(visible)
|
||||
}
|
||||
onWidthChanged: {
|
||||
window.appBar.width = width
|
||||
}
|
||||
QtObject{
|
||||
id:d
|
||||
property bool isFirstVisible: true
|
||||
}
|
||||
Connections{
|
||||
target: window
|
||||
function onClosing(event){closeListener(event)}
|
||||
}
|
||||
Component{
|
||||
id:com_frameless_helper
|
||||
FluFramelessHelper{
|
||||
onLoadCompleted:{
|
||||
if(autoCenter){
|
||||
window.moveWindowToDesktopCenter()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_background
|
||||
Rectangle{
|
||||
color: window.backgroundColor
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_app_bar
|
||||
Item{
|
||||
data: window.appBar
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_loading
|
||||
Popup{
|
||||
id:popup_loading
|
||||
focus: true
|
||||
width: window.width
|
||||
height: window.height
|
||||
anchors.centerIn: Overlay.overlay
|
||||
closePolicy: {
|
||||
if(cancel){
|
||||
return Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
}
|
||||
return Popup.NoAutoClose
|
||||
}
|
||||
Overlay.modal: Item {}
|
||||
onVisibleChanged: {
|
||||
if(!visible){
|
||||
loader_loading.sourceComponent = undefined
|
||||
}
|
||||
}
|
||||
padding: 0
|
||||
opacity: 0
|
||||
visible:true
|
||||
Behavior on opacity {
|
||||
SequentialAnimation {
|
||||
PauseAnimation {
|
||||
duration: 88
|
||||
}
|
||||
NumberAnimation{
|
||||
duration: 167
|
||||
}
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
opacity = 1
|
||||
}
|
||||
background: Rectangle{
|
||||
color:"#44000000"
|
||||
}
|
||||
contentItem: Item{
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (cancel){
|
||||
popup_loading.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
spacing: 8
|
||||
anchors.centerIn: parent
|
||||
FluProgressRing{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
FluText{
|
||||
text:loadingText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id:com_border
|
||||
Rectangle{
|
||||
color:"transparent"
|
||||
border.width: window.resizeBorderWidth
|
||||
border.color: window.resizeBorderColor
|
||||
}
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_frameless_helper
|
||||
}
|
||||
FluLoader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_app_bar
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
height: {
|
||||
if(window.useSystemAppBar){
|
||||
return 0
|
||||
}
|
||||
return window.fitsAppBarWindows ? 0 : window.appBar.height
|
||||
}
|
||||
sourceComponent: window.useSystemAppBar ? undefined : com_app_bar
|
||||
}
|
||||
Item{
|
||||
id:layout_content
|
||||
anchors{
|
||||
top: loader_app_bar.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
clip: true
|
||||
}
|
||||
FluLoader{
|
||||
property string loadingText
|
||||
property bool cancel: false
|
||||
id:loader_loading
|
||||
anchors.fill: parent
|
||||
}
|
||||
FluInfoBar{
|
||||
id:info_bar
|
||||
root: window
|
||||
}
|
||||
FluWindowLifecycle{
|
||||
id:lifecycle
|
||||
}
|
||||
FluLoader{
|
||||
id:loader_border
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(window.useSystemAppBar){
|
||||
return undefined
|
||||
}
|
||||
if(FluTools.isWindows10OrGreater()){
|
||||
return undefined
|
||||
}
|
||||
if(window.visibility === Window.Maximized || window.visibility === Window.FullScreen){
|
||||
return undefined
|
||||
}
|
||||
return com_border
|
||||
}
|
||||
}
|
||||
function destoryOnClose(){
|
||||
lifecycle.onDestoryOnClose()
|
||||
}
|
||||
function showLoading(text = qsTr("Loading..."),cancel = true){
|
||||
loader_loading.loadingText = text
|
||||
loader_loading.cancel = cancel
|
||||
loader_loading.sourceComponent = com_loading
|
||||
}
|
||||
function hideLoading(){
|
||||
loader_loading.sourceComponent = undefined
|
||||
}
|
||||
function showSuccess(text,duration,moremsg){
|
||||
info_bar.showSuccess(text,duration,moremsg)
|
||||
}
|
||||
function showInfo(text,duration,moremsg){
|
||||
info_bar.showInfo(text,duration,moremsg)
|
||||
}
|
||||
function showWarning(text,duration,moremsg){
|
||||
info_bar.showWarning(text,duration,moremsg)
|
||||
}
|
||||
function showError(text,duration,moremsg){
|
||||
info_bar.showError(text,duration,moremsg)
|
||||
}
|
||||
function moveWindowToDesktopCenter(){
|
||||
screen = Qt.application.screens[FluTools.cursorScreenIndex()]
|
||||
var availableGeometry = FluTools.desktopAvailableGeometry(window)
|
||||
window.setGeometry((availableGeometry.width-window.width)/2+Screen.virtualX,(availableGeometry.height-window.height)/2+Screen.virtualY,window.width,window.height)
|
||||
}
|
||||
function fixWindowSize(){
|
||||
if(fixSize){
|
||||
window.maximumWidth = window.width
|
||||
window.maximumHeight = window.height
|
||||
window.minimumWidth = window.width
|
||||
window.minimumHeight = window.height
|
||||
}
|
||||
}
|
||||
function registerForWindowResult(path){
|
||||
return FluApp.createWindowRegister(window,path)
|
||||
}
|
||||
function onResult(data){
|
||||
if(_windowRegister){
|
||||
_windowRegister.onResult(data)
|
||||
}
|
||||
}
|
||||
function showMaximized(){
|
||||
if(FluTools.isWin()){
|
||||
if(loader_frameless_helper.item){
|
||||
loader_frameless_helper.item.showMaximized()
|
||||
}
|
||||
}else{
|
||||
window.visibility = Qt.WindowMaximized
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import FluentUI
|
||||
|
||||
FluWindow {
|
||||
id:control
|
||||
property Component contentDelegate
|
||||
autoVisible: false
|
||||
autoCenter: false
|
||||
autoDestory: true
|
||||
fixSize: true
|
||||
Loader{
|
||||
anchors.fill: parent
|
||||
sourceComponent: {
|
||||
if(control.autoDestory){
|
||||
return control.visible ? control.contentDelegate : undefined
|
||||
}
|
||||
return control.contentDelegate
|
||||
}
|
||||
}
|
||||
closeListener: function(event){
|
||||
visible = false
|
||||
event.accepted = false
|
||||
}
|
||||
function showDialog(){
|
||||
var x = transientParent.x + (transientParent.width - width)/2
|
||||
var y = transientParent.y + (transientParent.height - height)/2
|
||||
setGeometry(x,y,width,height)
|
||||
visible = true
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 266 KiB |