This commit is contained in:
朱子楚\zhuzi 2024-03-24 10:17:20 +08:00
parent e0254f2f80
commit 07a43825d1
109 changed files with 12 additions and 35947 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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
}
}
}

View File

@ -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+"+"
}
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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()
}
}
}

View File

@ -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()
}
}
}

View File

@ -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();
}
}
}

View File

@ -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 !== ""
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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
}
}
}
}
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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()
}
}
}
}
}
}
}
}
}

View File

@ -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
}
}
}

View File

@ -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()
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}
]
}
}
}

View File

@ -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
}
}

View File

@ -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)
}
}
}

View File

@ -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
}
}

View File

@ -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"
}
}

View File

@ -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
}
}

View File

@ -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()
}
}
}
}

View File

@ -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
}
}
}

View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -1,5 +0,0 @@
import QtQuick
Loader {
Component.onDestruction: sourceComponent = undefined
}

View File

@ -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
}
}
}
}

View File

@ -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)
}
}

View File

@ -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
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}
}

View File

@ -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)
}
}

View File

@ -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
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
import QtQuick
import QtQuick.Controls
import FluentUI
QtObject {
default property list<QtObject> children
id:control
}

View File

@ -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()
}
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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
}
}
}
}

View File

@ -1,9 +0,0 @@
import QtQuick
import QtQuick.Controls
import FluentUI
QtObject {
property string title
property Component contentItem
property var argument
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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)
}
}
}
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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
}
}
}
]
}
}

View File

@ -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
}
}
}
]
}
}

View File

@ -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
}
}
}
}

View File

@ -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
}
}
}

View File

@ -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()
}
}

View File

@ -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
}
}

View File

@ -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)
}
}
}

View File

@ -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
}
}
}

View File

@ -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()
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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
}
}
}
}

View File

@ -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()
}
}
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -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
}
}
]
}
}
}
}
}

View File

@ -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)
}
}
}
}
}

View File

@ -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 !== ""
}
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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()
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB

Some files were not shown because too many files have changed in this diff Show More