diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d65981db..b237c175 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/FluApp.cpp b/src/FluApp.cpp index 2eecabff..abdc2b76 100644 --- a/src/FluApp.cpp +++ b/src/FluApp.cpp @@ -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(); diff --git a/src/FluentUI/Controls/FluAcrylic.qml b/src/FluentUI/Controls/FluAcrylic.qml deleted file mode 100644 index 035fe423..00000000 --- a/src/FluentUI/Controls/FluAcrylic.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluAppBar.qml b/src/FluentUI/Controls/FluAppBar.qml deleted file mode 100644 index 8a62854b..00000000 --- a/src/FluentUI/Controls/FluAppBar.qml +++ /dev/null @@ -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) - } -} diff --git a/src/FluentUI/Controls/FluArea.qml b/src/FluentUI/Controls/FluArea.qml deleted file mode 100644 index 81a08036..00000000 --- a/src/FluentUI/Controls/FluArea.qml +++ /dev/null @@ -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) - } -} diff --git a/src/FluentUI/Controls/FluAutoSuggestBox.qml b/src/FluentUI/Controls/FluAutoSuggestBox.qml deleted file mode 100644 index 0aaa8e03..00000000 --- a/src/FluentUI/Controls/FluAutoSuggestBox.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluBadge.qml b/src/FluentUI/Controls/FluBadge.qml deleted file mode 100644 index d265891a..00000000 --- a/src/FluentUI/Controls/FluBadge.qml +++ /dev/null @@ -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+"+" - } - } -} diff --git a/src/FluentUI/Controls/FluBreadcrumbBar.qml b/src/FluentUI/Controls/FluBreadcrumbBar.qml deleted file mode 100644 index 02d1e3a2..00000000 --- a/src/FluentUI/Controls/FluBreadcrumbBar.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluButton.qml b/src/FluentUI/Controls/FluButton.qml deleted file mode 100644 index dffe4d61..00000000 --- a/src/FluentUI/Controls/FluButton.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluCalendarPicker.qml b/src/FluentUI/Controls/FluCalendarPicker.qml deleted file mode 100644 index dbd9d503..00000000 --- a/src/FluentUI/Controls/FluCalendarPicker.qml +++ /dev/null @@ -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() - } - } -} diff --git a/src/FluentUI/Controls/FluCarousel.qml b/src/FluentUI/Controls/FluCarousel.qml deleted file mode 100644 index 844b8d9d..00000000 --- a/src/FluentUI/Controls/FluCarousel.qml +++ /dev/null @@ -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() - } - } -} diff --git a/src/FluentUI/Controls/FluChart.qml b/src/FluentUI/Controls/FluChart.qml deleted file mode 100644 index ebc70b15..00000000 --- a/src/FluentUI/Controls/FluChart.qml +++ /dev/null @@ -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(); - } - } -} diff --git a/src/FluentUI/Controls/FluCheckBox.qml b/src/FluentUI/Controls/FluCheckBox.qml deleted file mode 100644 index 47c95ee1..00000000 --- a/src/FluentUI/Controls/FluCheckBox.qml +++ /dev/null @@ -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 !== "" - } - } -} diff --git a/src/FluentUI/Controls/FluClip.qml b/src/FluentUI/Controls/FluClip.qml deleted file mode 100644 index 486b9365..00000000 --- a/src/FluentUI/Controls/FluClip.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluColorPicker.qml b/src/FluentUI/Controls/FluColorPicker.qml deleted file mode 100644 index 72728a56..00000000 --- a/src/FluentUI/Controls/FluColorPicker.qml +++ /dev/null @@ -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 - } - } - } - } - } - } -} diff --git a/src/FluentUI/Controls/FluComboBox.qml b/src/FluentUI/Controls/FluComboBox.qml deleted file mode 100644 index fb7a1665..00000000 --- a/src/FluentUI/Controls/FluComboBox.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluContentDialog.qml b/src/FluentUI/Controls/FluContentDialog.qml deleted file mode 100644 index 6c4ae127..00000000 --- a/src/FluentUI/Controls/FluContentDialog.qml +++ /dev/null @@ -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() - } - } - } - } - } - } - } - } -} diff --git a/src/FluentUI/Controls/FluContentPage.qml b/src/FluentUI/Controls/FluContentPage.qml deleted file mode 100644 index 02815fab..00000000 --- a/src/FluentUI/Controls/FluContentPage.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluControl.qml b/src/FluentUI/Controls/FluControl.qml deleted file mode 100644 index 50f672e4..00000000 --- a/src/FluentUI/Controls/FluControl.qml +++ /dev/null @@ -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() -} diff --git a/src/FluentUI/Controls/FluCopyableText.qml b/src/FluentUI/Controls/FluCopyableText.qml deleted file mode 100644 index 34c1fc7f..00000000 --- a/src/FluentUI/Controls/FluCopyableText.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluDatePicker.qml b/src/FluentUI/Controls/FluDatePicker.qml deleted file mode 100644 index abfcf47d..00000000 --- a/src/FluentUI/Controls/FluDatePicker.qml +++ /dev/null @@ -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; - } -} diff --git a/src/FluentUI/Controls/FluDivider.qml b/src/FluentUI/Controls/FluDivider.qml deleted file mode 100644 index 3c6748a1..00000000 --- a/src/FluentUI/Controls/FluDivider.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluDropDownButton.qml b/src/FluentUI/Controls/FluDropDownButton.qml deleted file mode 100644 index 5e9f8c3d..00000000 --- a/src/FluentUI/Controls/FluDropDownButton.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluExpander.qml b/src/FluentUI/Controls/FluExpander.qml deleted file mode 100644 index b2230a70..00000000 --- a/src/FluentUI/Controls/FluExpander.qml +++ /dev/null @@ -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 - } - } - ] - } - } -} diff --git a/src/FluentUI/Controls/FluFilledButton.qml b/src/FluentUI/Controls/FluFilledButton.qml deleted file mode 100644 index b83505cf..00000000 --- a/src/FluentUI/Controls/FluFilledButton.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluFlipView.qml b/src/FluentUI/Controls/FluFlipView.qml deleted file mode 100644 index 1f3012a8..00000000 --- a/src/FluentUI/Controls/FluFlipView.qml +++ /dev/null @@ -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) - } - } -} diff --git a/src/FluentUI/Controls/FluFocusRectangle.qml b/src/FluentUI/Controls/FluFocusRectangle.qml deleted file mode 100644 index 5c6c9596..00000000 --- a/src/FluentUI/Controls/FluFocusRectangle.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluIcon.qml b/src/FluentUI/Controls/FluIcon.qml deleted file mode 100644 index edf17b61..00000000 --- a/src/FluentUI/Controls/FluIcon.qml +++ /dev/null @@ -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" - } -} diff --git a/src/FluentUI/Controls/FluIconButton.qml b/src/FluentUI/Controls/FluIconButton.qml deleted file mode 100644 index b52dcff6..00000000 --- a/src/FluentUI/Controls/FluIconButton.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluImage.qml b/src/FluentUI/Controls/FluImage.qml deleted file mode 100644 index dcdc3fc1..00000000 --- a/src/FluentUI/Controls/FluImage.qml +++ /dev/null @@ -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() - } - } - } -} diff --git a/src/FluentUI/Controls/FluImageButton.qml b/src/FluentUI/Controls/FluImageButton.qml deleted file mode 100644 index b028eee4..00000000 --- a/src/FluentUI/Controls/FluImageButton.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluInfoBar.qml b/src/FluentUI/Controls/FluInfoBar.qml deleted file mode 100644 index 4eaa185c..00000000 --- a/src/FluentUI/Controls/FluInfoBar.qml +++ /dev/null @@ -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); - } -} diff --git a/src/FluentUI/Controls/FluItemDelegate.qml b/src/FluentUI/Controls/FluItemDelegate.qml deleted file mode 100644 index 265bc3cc..00000000 --- a/src/FluentUI/Controls/FluItemDelegate.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluLoader.qml b/src/FluentUI/Controls/FluLoader.qml deleted file mode 100644 index fcf5dae5..00000000 --- a/src/FluentUI/Controls/FluLoader.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick - -Loader { - Component.onDestruction: sourceComponent = undefined -} diff --git a/src/FluentUI/Controls/FluLoadingButton.qml b/src/FluentUI/Controls/FluLoadingButton.qml deleted file mode 100644 index 5b91a281..00000000 --- a/src/FluentUI/Controls/FluLoadingButton.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluMenu.qml b/src/FluentUI/Controls/FluMenu.qml deleted file mode 100644 index 5090f3ac..00000000 --- a/src/FluentUI/Controls/FluMenu.qml +++ /dev/null @@ -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) - } -} diff --git a/src/FluentUI/Controls/FluMenuBar.qml b/src/FluentUI/Controls/FluMenuBar.qml deleted file mode 100644 index 9c76ec42..00000000 --- a/src/FluentUI/Controls/FluMenuBar.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluMenuBarItem.qml b/src/FluentUI/Controls/FluMenuBarItem.qml deleted file mode 100644 index b7e9e175..00000000 --- a/src/FluentUI/Controls/FluMenuBarItem.qml +++ /dev/null @@ -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 - } - } -} - diff --git a/src/FluentUI/Controls/FluMenuItem.qml b/src/FluentUI/Controls/FluMenuItem.qml deleted file mode 100644 index a1577c6b..00000000 --- a/src/FluentUI/Controls/FluMenuItem.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluMenuSeparator.qml b/src/FluentUI/Controls/FluMenuSeparator.qml deleted file mode 100644 index a687e30a..00000000 --- a/src/FluentUI/Controls/FluMenuSeparator.qml +++ /dev/null @@ -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) - } -} diff --git a/src/FluentUI/Controls/FluMultilineTextBox.qml b/src/FluentUI/Controls/FluMultilineTextBox.qml deleted file mode 100644 index 6d1c3649..00000000 --- a/src/FluentUI/Controls/FluMultilineTextBox.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluNavigationView.qml b/src/FluentUI/Controls/FluNavigationView.qml deleted file mode 100644 index a44027a7..00000000 --- a/src/FluentUI/Controls/FluNavigationView.qml +++ /dev/null @@ -1,1344 +0,0 @@ -import QtQuick -import QtQuick.Window -import QtQuick.Controls -import QtQuick.Controls.Basic -import QtQuick.Layouts -import FluentUI - -Item { - property url logo - property string title: "" - property FluObject items - property FluObject footerItems - property int displayMode: FluNavigationViewType.Auto - property Component autoSuggestBox - property Component actionItem - property int topPadding: 0 - property int pageMode: FluNavigationViewType.Stack - property FluMenu navItemRightMenu - property FluMenu navItemExpanderRightMenu - property int navCompactWidth: 50 - property int navTopMargin: 0 - property int cellHeight: 38 - property int cellWidth: 300 - property bool hideNavAppBar: false - property alias buttonMenu: btn_menu - property alias buttonBack: btn_back - property alias imageLogo: image_logo - signal logoClicked - id:control - Item{ - id:d - property bool animDisabled:false - property var stackItems: [] - property int displayMode: control.displayMode - property bool enableNavigationPanel: false - property bool isCompact: d.displayMode === FluNavigationViewType.Compact - property bool isMinimal: d.displayMode === FluNavigationViewType.Minimal - property bool isCompactAndPanel: d.displayMode === FluNavigationViewType.Compact && d.enableNavigationPanel - property bool isCompactAndNotPanel:d.displayMode === FluNavigationViewType.Compact && !d.enableNavigationPanel - property bool isMinimalAndPanel: d.displayMode === FluNavigationViewType.Minimal && d.enableNavigationPanel - property color itemDisableColor: FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1) - onIsCompactAndNotPanelChanged: { - collapseAll() - } - function handleItems(){ - var _idx = 0 - var data = [] - var comEmpty = Qt.createComponent("FluPaneItemEmpty.qml"); - if(items){ - for(var i=0;i{ - if (mouse.button === Qt.RightButton) { - if(model.menuDelegate){ - loader_item_menu.sourceComponent = model.menuDelegate - connection_item_menu.target = loader_item_menu.item - loader_item_menu.modelData = model - loader_item_menu.item.popup(); - } - } - } - z:-100 - } - onClicked: { - if(d.isCompactAndNotPanel && model.children.length > 0){ - let h = 38*Math.min(Math.max(model.children.length,1),8) - let y = mapToItem(control,0,0).y - if(h+y>control.height){ - y = control.height - h - } - control_popup.showPopup(Qt.point(control.navCompactWidth,y),h,model.children) - return - } - model.isExpand = !model.isExpand - } - Rectangle{ - color:Qt.rgba(255/255,77/255,79/255,1) - width: 10 - height: 10 - radius: 5 - border.width: 1 - border.color: Qt.rgba(1,1,1,1) - anchors{ - right: parent.right - verticalCenter: parent.verticalCenter - rightMargin: 3 - verticalCenterOffset: -8 - } - visible: { - if(!model){ - return false - } - if(!model.isExpand){ - for(var i=0;i{ - if (mouse.button === Qt.RightButton) { - if(model.menuDelegate){ - loader_item_menu.sourceComponent = model.menuDelegate - connection_item_menu.target = loader_item_menu.item - loader_item_menu.modelData = model - loader_item_menu.item.popup(); - } - }else{ - item_control.clicked() - } - } - } - Rectangle{ - radius: 4 - anchors.fill: parent - color: { - if(!item_control.enabled){ - return FluTheme.itemNormalColor - } - if(type===0){ - if(nav_list.currentIndex === _idx){ - return FluTheme.itemCheckColor - } - }else{ - if(nav_list.currentIndex === (nav_list.count-layout_footer.count+_idx)){ - return FluTheme.itemCheckColor - } - } - if(item_control.hovered){ - return FluTheme.itemHoverColor - } - return FluTheme.itemNormalColor - } - Component{ - id:com_icon - FluIcon{ - iconSource: { - if(model&&model.icon){ - return model.icon - } - return 0 - } - color: { - if(!item_control.enabled){ - return d.itemDisableColor - } - return FluTheme.dark ? "#FFFFFF" : "#000000" - } - iconSize: 15 - } - } - Item{ - id:item_icon - height: 30 - width: visible ? 30 : 8 - visible: { - if(model){ - return model.iconVisible - } - return true - } - anchors{ - left:parent.left - verticalCenter: parent.verticalCenter - leftMargin: d.isCompactAndNotPanel ? (parent.width - 30)/2 : 3 - } - FluLoader{ - anchors.centerIn: parent - sourceComponent: { - if(model&&model.iconDelegate){ - return model.iconDelegate - } - return com_icon - } - } - } - FluText{ - id:item_title - text:{ - if(model){ - if(!item_icon.visible && d.isCompactAndNotPanel){ - return model.title[0] - } - return model.title - } - return "" - } - visible: { - if(d.isCompactAndNotPanel){ - if(item_icon.visible){ - return false - } - return true - } - return true - } - elide: Text.ElideRight - color:{ - if(!item_control.enabled){ - return d.itemDisableColor - } - if(item_mouse.pressed){ - return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120 - } - return FluTheme.dark ? FluColors.White : FluColors.Grey220 - } - anchors{ - verticalCenter: parent.verticalCenter - left:item_icon.right - right: item_dot_loader.left - } - } - FluLoader{ - id:item_edit_loader - anchors{ - top: parent.top - bottom: parent.bottom - left: item_title.left - right: item_title.right - rightMargin: 8 - } - sourceComponent: { - if(d.isCompact){ - return undefined - } - if(!model){ - return undefined - } - return model.showEdit ? model.editDelegate : undefined - } - onStatusChanged: { - if(status === FluLoader.Ready){ - item.forceActiveFocus() - item_connection_edit_focus.target = item - } - } - Connections{ - id:item_connection_edit_focus - ignoreUnknownSignals:true - function onActiveFocusChanged(focus){ - if(focus === false){ - model.showEdit = false - } - } - function onCommit(text){ - model.title = text - model.showEdit = false - } - } - } - FluLoader{ - id:item_dot_loader - property bool isDot: (item_dot_loader.item&&item_dot_loader.item.isDot) - anchors{ - right: parent.right - verticalCenter: parent.verticalCenter - rightMargin: isDot ? 3 : 10 - verticalCenterOffset: isDot ? -8 : 0 - } - sourceComponent: { - if(model&&model.infoBadge){ - return model.infoBadge - } - return undefined - } - Connections{ - target: d - function onIsCompactAndNotPanelChanged(){ - if(item_dot_loader.item){ - item_dot_loader.item.isDot = d.isCompactAndNotPanel - } - } - } - } - } - } - } - } - Item { - id:nav_app_bar - width: parent.width - height: visible ? 40 : 0 - anchors{ - top: parent.top - topMargin: control.topPadding - } - visible: !control.hideNavAppBar - z:999 - RowLayout{ - height:parent.height - spacing: 0 - FluIconButton{ - id:btn_back - iconSource: FluentIcons.ChromeBack - Layout.leftMargin: 5 - Layout.alignment: Qt.AlignVCenter - disabled: { - return d.stackItems.length <= 1 - } - iconSize: 13 - onClicked: { - d.stackItems = d.stackItems.slice(0, -1) - var item = d.stackItems[d.stackItems.length-1] - if(item._idx<(nav_list.count - layout_footer.count)){ - layout_footer.currentIndex = -1 - }else{ - layout_footer.currentIndex = item._idx-(nav_list.count-layout_footer.count) - } - nav_list.currentIndex = item._idx - if(pageMode === FluNavigationViewType.Stack){ - var nav_stack = loader_content.item.navStack() - var nav_stack2 = loader_content.item.navStack2() - nav_stack.pop() - if(nav_stack.currentItem.launchMode === FluPageType.SingleInstance){ - var url = nav_stack.currentItem.url - var pageIndex = -1 - for(var i=0;i children - id:control -} diff --git a/src/FluentUI/Controls/FluPage.qml b/src/FluentUI/Controls/FluPage.qml deleted file mode 100644 index 87420acd..00000000 --- a/src/FluentUI/Controls/FluPage.qml +++ /dev/null @@ -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() - } - } -} diff --git a/src/FluentUI/Controls/FluPagination.qml b/src/FluentUI/Controls/FluPagination.qml deleted file mode 100644 index 37f6807d..00000000 --- a/src/FluentUI/Controls/FluPagination.qml +++ /dev/null @@ -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("") - 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) - } -} diff --git a/src/FluentUI/Controls/FluPaneItem.qml b/src/FluentUI/Controls/FluPaneItem.qml deleted file mode 100644 index d2214015..00000000 --- a/src/FluentUI/Controls/FluPaneItem.qml +++ /dev/null @@ -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 -} diff --git a/src/FluentUI/Controls/FluPaneItemEmpty.qml b/src/FluentUI/Controls/FluPaneItemEmpty.qml deleted file mode 100644 index 0f12e384..00000000 --- a/src/FluentUI/Controls/FluPaneItemEmpty.qml +++ /dev/null @@ -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 -} diff --git a/src/FluentUI/Controls/FluPaneItemExpander.qml b/src/FluentUI/Controls/FluPaneItemExpander.qml deleted file mode 100644 index 93c2e648..00000000 --- a/src/FluentUI/Controls/FluPaneItemExpander.qml +++ /dev/null @@ -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 -} diff --git a/src/FluentUI/Controls/FluPaneItemHeader.qml b/src/FluentUI/Controls/FluPaneItemHeader.qml deleted file mode 100644 index 6918097f..00000000 --- a/src/FluentUI/Controls/FluPaneItemHeader.qml +++ /dev/null @@ -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 -} diff --git a/src/FluentUI/Controls/FluPaneItemSeparator.qml b/src/FluentUI/Controls/FluPaneItemSeparator.qml deleted file mode 100644 index 23433b68..00000000 --- a/src/FluentUI/Controls/FluPaneItemSeparator.qml +++ /dev/null @@ -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 -} diff --git a/src/FluentUI/Controls/FluPasswordBox.qml b/src/FluentUI/Controls/FluPasswordBox.qml deleted file mode 100644 index e493a95c..00000000 --- a/src/FluentUI/Controls/FluPasswordBox.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluPivot.qml b/src/FluentUI/Controls/FluPivot.qml deleted file mode 100644 index df0374ca..00000000 --- a/src/FluentUI/Controls/FluPivot.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluPivotItem.qml b/src/FluentUI/Controls/FluPivotItem.qml deleted file mode 100644 index b241dc44..00000000 --- a/src/FluentUI/Controls/FluPivotItem.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick -import QtQuick.Controls -import FluentUI - -QtObject { - property string title - property Component contentItem - property var argument -} diff --git a/src/FluentUI/Controls/FluPopup.qml b/src/FluentUI/Controls/FluPopup.qml deleted file mode 100644 index 78d9d5bb..00000000 --- a/src/FluentUI/Controls/FluPopup.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluProgressBar.qml b/src/FluentUI/Controls/FluProgressBar.qml deleted file mode 100644 index bca37cea..00000000 --- a/src/FluentUI/Controls/FluProgressBar.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluProgressButton.qml b/src/FluentUI/Controls/FluProgressButton.qml deleted file mode 100644 index 1c21c78e..00000000 --- a/src/FluentUI/Controls/FluProgressButton.qml +++ /dev/null @@ -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) - } - } - } - } -} diff --git a/src/FluentUI/Controls/FluProgressRing.qml b/src/FluentUI/Controls/FluProgressRing.qml deleted file mode 100644 index 480aee9d..00000000 --- a/src/FluentUI/Controls/FluProgressRing.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluQRCode.qml b/src/FluentUI/Controls/FluQRCode.qml deleted file mode 100644 index 9a6428b4..00000000 --- a/src/FluentUI/Controls/FluQRCode.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluRadioButton.qml b/src/FluentUI/Controls/FluRadioButton.qml deleted file mode 100644 index ac67b5ee..00000000 --- a/src/FluentUI/Controls/FluRadioButton.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluRadioButtons.qml b/src/FluentUI/Controls/FluRadioButtons.qml deleted file mode 100644 index eb8c817d..00000000 --- a/src/FluentUI/Controls/FluRadioButtons.qml +++ /dev/null @@ -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{ - d.mouseValue = Number(mouse.x / d.itemSize)+1 - } - onExited: { - d.mouseValue = 0 - } - onClicked: (mouse)=>{ - control.value = Number(mouse.x / d.itemSize)+1 - } - } -} diff --git a/src/FluentUI/Controls/FluRemoteLoader.qml b/src/FluentUI/Controls/FluRemoteLoader.qml deleted file mode 100644 index 13c7142d..00000000 --- a/src/FluentUI/Controls/FluRemoteLoader.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluScrollBar.qml b/src/FluentUI/Controls/FluScrollBar.qml deleted file mode 100644 index 0d66e6a8..00000000 --- a/src/FluentUI/Controls/FluScrollBar.qml +++ /dev/null @@ -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 - } - } - } - ] - } -} diff --git a/src/FluentUI/Controls/FluScrollIndicator.qml b/src/FluentUI/Controls/FluScrollIndicator.qml deleted file mode 100644 index 3e4b1685..00000000 --- a/src/FluentUI/Controls/FluScrollIndicator.qml +++ /dev/null @@ -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 - } - } - } - ] - } -} diff --git a/src/FluentUI/Controls/FluScrollablePage.qml b/src/FluentUI/Controls/FluScrollablePage.qml deleted file mode 100644 index 6aafc0c9..00000000 --- a/src/FluentUI/Controls/FluScrollablePage.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluShadow.qml b/src/FluentUI/Controls/FluShadow.qml deleted file mode 100644 index af236e1e..00000000 --- a/src/FluentUI/Controls/FluShadow.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluShortcutPicker.qml b/src/FluentUI/Controls/FluShortcutPicker.qml deleted file mode 100644 index f3a592b8..00000000 --- a/src/FluentUI/Controls/FluShortcutPicker.qml +++ /dev/null @@ -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() - } -} diff --git a/src/FluentUI/Controls/FluSlider.qml b/src/FluentUI/Controls/FluSlider.qml deleted file mode 100644 index 7b0be429..00000000 --- a/src/FluentUI/Controls/FluSlider.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluSpinBox.qml b/src/FluentUI/Controls/FluSpinBox.qml deleted file mode 100644 index c3265efa..00000000 --- a/src/FluentUI/Controls/FluSpinBox.qml +++ /dev/null @@ -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) - } - } -} diff --git a/src/FluentUI/Controls/FluSplitLayout.qml b/src/FluentUI/Controls/FluSplitLayout.qml deleted file mode 100644 index f13673a8..00000000 --- a/src/FluentUI/Controls/FluSplitLayout.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluStaggeredLayout.qml b/src/FluentUI/Controls/FluStaggeredLayout.qml deleted file mode 100644 index 9f0da327..00000000 --- a/src/FluentUI/Controls/FluStaggeredLayout.qml +++ /dev/null @@ -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 { - d.addToFall(index, item) - d.itemsInRep.push(item) - } - } - function clear(){ - d.maxHeight = 0 - d.colsHeightArr = [] - d.itemsInRep = [] - model.clear() - } -} diff --git a/src/FluentUI/Controls/FluStatusLayout.qml b/src/FluentUI/Controls/FluStatusLayout.qml deleted file mode 100644 index ab82ba21..00000000 --- a/src/FluentUI/Controls/FluStatusLayout.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluTabView.qml b/src/FluentUI/Controls/FluTabView.qml deleted file mode 100644 index dab42f31..00000000 --- a/src/FluentUI/Controls/FluTabView.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluTableView.qml b/src/FluentUI/Controls/FluTableView.qml deleted file mode 100644 index 2acda1f5..00000000 --- a/src/FluentUI/Controls/FluTableView.qml +++ /dev/null @@ -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=0 && rowIndex=0 && rowIndex 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 - } -} diff --git a/src/FluentUI/Controls/FluTextBoxBackground.qml b/src/FluentUI/Controls/FluTextBoxBackground.qml deleted file mode 100644 index 3ec71baf..00000000 --- a/src/FluentUI/Controls/FluTextBoxBackground.qml +++ /dev/null @@ -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 - } - } - } -} diff --git a/src/FluentUI/Controls/FluTextBoxMenu.qml b/src/FluentUI/Controls/FluTextBoxMenu.qml deleted file mode 100644 index 3be0c1b2..00000000 --- a/src/FluentUI/Controls/FluTextBoxMenu.qml +++ /dev/null @@ -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() - } - } -} diff --git a/src/FluentUI/Controls/FluTextButton.qml b/src/FluentUI/Controls/FluTextButton.qml deleted file mode 100644 index 68d98129..00000000 --- a/src/FluentUI/Controls/FluTextButton.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Controls/FluTimePicker.qml b/src/FluentUI/Controls/FluTimePicker.qml deleted file mode 100644 index f34b6dd6..00000000 --- a/src/FluentUI/Controls/FluTimePicker.qml +++ /dev/null @@ -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; - } -} diff --git a/src/FluentUI/Controls/FluTimeline.qml b/src/FluentUI/Controls/FluTimeline.qml deleted file mode 100644 index 4477e00e..00000000 --- a/src/FluentUI/Controls/FluTimeline.qml +++ /dev/null @@ -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;icontrol.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 - } - } -} diff --git a/src/FluentUI/Controls/FluTreeView.qml b/src/FluentUI/Controls/FluTreeView.qml deleted file mode 100644 index 12ef0a60..00000000 --- a/src/FluentUI/Controls/FluTreeView.qml +++ /dev/null @@ -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() - } -} diff --git a/src/FluentUI/Controls/FluWindow.qml b/src/FluentUI/Controls/FluWindow.qml deleted file mode 100644 index 8d43c129..00000000 --- a/src/FluentUI/Controls/FluWindow.qml +++ /dev/null @@ -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 - } - } -} diff --git a/src/FluentUI/Controls/FluWindowDialog.qml b/src/FluentUI/Controls/FluWindowDialog.qml deleted file mode 100644 index 60a40d21..00000000 --- a/src/FluentUI/Controls/FluWindowDialog.qml +++ /dev/null @@ -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 - } -} diff --git a/src/FluentUI/Font/Segoe_Fluent_Icons.ttf b/src/FluentUI/Font/Segoe_Fluent_Icons.ttf deleted file mode 100644 index 8f05a4bb..00000000 Binary files a/src/FluentUI/Font/Segoe_Fluent_Icons.ttf and /dev/null differ diff --git a/src/FluentUI/Image/btn_close_hovered.png b/src/FluentUI/Image/btn_close_hovered.png deleted file mode 100644 index afd646f3..00000000 Binary files a/src/FluentUI/Image/btn_close_hovered.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_close_normal.png b/src/FluentUI/Image/btn_close_normal.png deleted file mode 100644 index de922d4b..00000000 Binary files a/src/FluentUI/Image/btn_close_normal.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_close_pushed.png b/src/FluentUI/Image/btn_close_pushed.png deleted file mode 100644 index 4c722ba2..00000000 Binary files a/src/FluentUI/Image/btn_close_pushed.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_max_hovered.png b/src/FluentUI/Image/btn_max_hovered.png deleted file mode 100644 index 22ba4ca6..00000000 Binary files a/src/FluentUI/Image/btn_max_hovered.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_max_normal.png b/src/FluentUI/Image/btn_max_normal.png deleted file mode 100644 index 4c1bc629..00000000 Binary files a/src/FluentUI/Image/btn_max_normal.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_max_pushed.png b/src/FluentUI/Image/btn_max_pushed.png deleted file mode 100644 index 22fc333e..00000000 Binary files a/src/FluentUI/Image/btn_max_pushed.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_min_hovered.png b/src/FluentUI/Image/btn_min_hovered.png deleted file mode 100644 index 41e9395e..00000000 Binary files a/src/FluentUI/Image/btn_min_hovered.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_min_normal.png b/src/FluentUI/Image/btn_min_normal.png deleted file mode 100644 index 25fcf5f4..00000000 Binary files a/src/FluentUI/Image/btn_min_normal.png and /dev/null differ diff --git a/src/FluentUI/Image/btn_min_pushed.png b/src/FluentUI/Image/btn_min_pushed.png deleted file mode 100644 index 57f7211a..00000000 Binary files a/src/FluentUI/Image/btn_min_pushed.png and /dev/null differ diff --git a/src/FluentUI/Image/noise.png b/src/FluentUI/Image/noise.png deleted file mode 100644 index a78e8296..00000000 Binary files a/src/FluentUI/Image/noise.png and /dev/null differ diff --git a/src/FluentUI/JS/Chart.js b/src/FluentUI/JS/Chart.js deleted file mode 100644 index cce4f915..00000000 --- a/src/FluentUI/JS/Chart.js +++ /dev/null @@ -1,20822 +0,0 @@ -/*! - * Chart.js v2.9.4 - * https://www.chartjs.org - * (c) 2020 Chart.js Contributors - * Released under the MIT License - */ - - /*! - * adaptions by Elypson (Michael A. Voelkel) to get it working for QML: - * 1) changed overall library structure with UMD and global function build - * 2) animations are triggered via QML animator - * 3) tooltips do not use DOM events but QML events that are injected via bindEvents now - * 4) many smaller modifications because Chart.js relied on and used the DOM that is not available in QML in the same way - * 5) some fixes that occured in QML like setting dashed line to solid - * 6) personal customization, where we assumed that it leads to better looks - * - * also note that modifications are inspired by Shuirna (github.com/shuirna) and their changes were inspired by Julien Wintz - * - * (c) 2020 ChartJs2QML contributors (starting with Elypson, Michael A. Voelkel, https://github.com/Elypson) - * those customizations are also licensed under MIT for all matters and purposes - */ - -function UMD(global, factory) { -typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : -typeof define === 'function' && define.amd ? define(factory) : -(global = global || self, global.Chart = factory()); -}; - -function Chart (item, config) { 'use strict'; - -var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof _window !== 'undefined' ? _window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function commonjsRequire () { - throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); -} - -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; -} - -function getCjsExportFromNamespace (n) { - return n && n['default'] || n; -} - -var colorName = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -var conversions = createCommonjsModule(function (module) { -/* MIT license */ - - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -var reverseKeywords = {}; -for (var key in colorName) { - if (colorName.hasOwnProperty(key)) { - reverseKeywords[colorName[key]] = key; - } -} - -var convert = module.exports = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -// hide .channels and .labels properties -for (var model in convert) { - if (convert.hasOwnProperty(model)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - var channels = convert[model].channels; - var labels = convert[model].labels; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); - } -} - -convert.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert.rgb.hsv = function (rgb) { - var rdif; - var gdif; - var bdif; - var h; - var s; - - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var v = Math.max(r, g, b); - var diff = v - Math.min(r, g, b); - var diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; - - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ -function comparativeDistance(x, y) { - return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) - ); -} - -convert.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } - - var currentClosestDistance = Infinity; - var currentClosestKeyword; - - for (var keyword in colorName) { - if (colorName.hasOwnProperty(keyword)) { - var value = colorName[keyword]; - - // Compute comparative distance - var distance = comparativeDistance(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - } - - return currentClosestKeyword; -}; - -convert.keyword.rgb = function (keyword) { - return colorName[keyword]; -}; - -convert.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert.rgb.lab = function (rgb) { - var xyz = convert.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; - - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; - - l = (2 - s) * v; - lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - n = wh + f * (v - wh); // linear interpolation - - var r; - var g; - var b; - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -}; - -convert.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - var ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; - -convert.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - - // we use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - var ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert.ansi16.rgb = function (args) { - var color = args % 10; - - // handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert.ansi256.rgb = function (args) { - // handle greyscale - if (args >= 232) { - var c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - var colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { - return char + char; - }).join(''); - } - - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; - - return [r, g, b]; -}; - -convert.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma + 4; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; - - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } - - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; - - var c = s * v; - var f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; - - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var v = c + g * (1.0 - c); - var f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert.gray.hsl = convert.gray.hsv = function (args) { - return [0, 0, args[0]]; -}; - -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; -}); -var conversions_1 = conversions.rgb; -var conversions_2 = conversions.hsl; -var conversions_3 = conversions.hsv; -var conversions_4 = conversions.hwb; -var conversions_5 = conversions.cmyk; -var conversions_6 = conversions.xyz; -var conversions_7 = conversions.lab; -var conversions_8 = conversions.lch; -var conversions_9 = conversions.hex; -var conversions_10 = conversions.keyword; -var conversions_11 = conversions.ansi16; -var conversions_12 = conversions.ansi256; -var conversions_13 = conversions.hcg; -var conversions_14 = conversions.apple; -var conversions_15 = conversions.gray; - -/* - this function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph() { - var graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions); - - for (var len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions[current]); - - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions[graph[toModel].parent][toModel]; - - var cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -var route = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; - - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; - - if (node.parent === null) { - // no possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion(toModel, graph); - } - - return conversion; -}; - -var convert = {}; - -var models = Object.keys(conversions); - -function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - return fn(args); - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - var result = fn(args); - - // we're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models.forEach(function (fromModel) { - convert[fromModel] = {}; - - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - - var routes = route(fromModel); - var routeModels = Object.keys(routes); - - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; - - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -var colorConvert = convert; - -var colorName$1 = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -/* MIT license */ - - -var colorString = { - getRgba: getRgba, - getHsla: getHsla, - getRgb: getRgb, - getHsl: getHsl, - getHwb: getHwb, - getAlpha: getAlpha, - - hexString: hexString, - rgbString: rgbString, - rgbaString: rgbaString, - percentString: percentString, - percentaString: percentaString, - hslString: hslString, - hslaString: hslaString, - hwbString: hwbString, - keyword: keyword -}; - -function getRgba(string) { - if (!string) { - return; - } - var abbr = /^#([a-fA-F0-9]{3,4})$/i, - hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i, - rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, - per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, - keyword = /(\w+)/; - - var rgb = [0, 0, 0], - a = 1, - match = string.match(abbr), - hexAlpha = ""; - if (match) { - match = match[1]; - hexAlpha = match[3]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i] + match[i], 16); - } - if (hexAlpha) { - a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100; - } - } - else if (match = string.match(hex)) { - hexAlpha = match[2]; - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); - } - if (hexAlpha) { - a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100; - } - } - else if (match = string.match(rgba)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i + 1]); - } - a = parseFloat(match[4]); - } - else if (match = string.match(per)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); - } - a = parseFloat(match[4]); - } - else if (match = string.match(keyword)) { - if (match[1] == "transparent") { - return [0, 0, 0, 0]; - } - rgb = colorName$1[match[1]]; - if (!rgb) { - return; - } - } - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = scale(rgb[i], 0, 255); - } - if (!a && a != 0) { - a = 1; - } - else { - a = scale(a, 0, 1); - } - rgb[3] = a; - return rgb; -} - -function getHsla(string) { - if (!string) { - return; - } - var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hsl); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - s = scale(parseFloat(match[2]), 0, 100), - l = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, s, l, a]; - } -} - -function getHwb(string) { - if (!string) { - return; - } - var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hwb); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - w = scale(parseFloat(match[2]), 0, 100), - b = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, w, b, a]; - } -} - -function getRgb(string) { - var rgba = getRgba(string); - return rgba && rgba.slice(0, 3); -} - -function getHsl(string) { - var hsla = getHsla(string); - return hsla && hsla.slice(0, 3); -} - -function getAlpha(string) { - var vals = getRgba(string); - if (vals) { - return vals[3]; - } - else if (vals = getHsla(string)) { - return vals[3]; - } - else if (vals = getHwb(string)) { - return vals[3]; - } -} - -// generators -function hexString(rgba, a) { - var a = (a !== undefined && rgba.length === 3) ? a : rgba[3]; - return "#" + hexDouble(rgba[0]) - + hexDouble(rgba[1]) - + hexDouble(rgba[2]) - + ( - (a >= 0 && a < 1) - ? hexDouble(Math.round(a * 255)) - : "" - ); -} - -function rgbString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return rgbaString(rgba, alpha); - } - return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; -} - -function rgbaString(rgba, alpha) { - if (alpha === undefined) { - alpha = (rgba[3] !== undefined ? rgba[3] : 1); - } - return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] - + ", " + alpha + ")"; -} - -function percentString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return percentaString(rgba, alpha); - } - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - - return "rgb(" + r + "%, " + g + "%, " + b + "%)"; -} - -function percentaString(rgba, alpha) { - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; -} - -function hslString(hsla, alpha) { - if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { - return hslaString(hsla, alpha); - } - return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; -} - -function hslaString(hsla, alpha) { - if (alpha === undefined) { - alpha = (hsla[3] !== undefined ? hsla[3] : 1); - } - return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " - + alpha + ")"; -} - -// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax -// (hwb have alpha optional & 1 is default value) -function hwbString(hwb, alpha) { - if (alpha === undefined) { - alpha = (hwb[3] !== undefined ? hwb[3] : 1); - } - return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" - + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; -} - -// helpers -function scale(num, min, max) { - return Math.min(Math.max(min, num), max); -} - -function hexDouble(num) { - var str = num.toString(16).toUpperCase(); - return (str.length < 2) ? "0" + str : str; -} - -//create a list of reverse color names -var reverseNames = {}; -for (var name in colorName$1) { - reverseNames[colorName$1[name]] = name; -} - -function keyword(rgb) { - return reverseNames[rgb.slice(0, 3)]; -} - -/* MIT license */ - - - -var Color = function (obj) { - if (obj instanceof Color) { - return obj; - } - if (!(this instanceof Color)) { - return new Color(obj); - } - - this.valid = false; - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - }; - - // parse Color() argument - var vals; - if (typeof obj === 'string') { - vals = colorString.getRgba(obj); - if (vals) { - this.setValues('rgb', vals); - } else if (vals = colorString.getHsla(obj)) { - this.setValues('hsl', vals); - } else if (vals = colorString.getHwb(obj)) { - this.setValues('hwb', vals); - } - } else if (typeof obj === 'object') { - vals = obj; - if (vals.r !== undefined || vals.red !== undefined) { - this.setValues('rgb', vals); - } else if (vals.l !== undefined || vals.lightness !== undefined) { - this.setValues('hsl', vals); - } else if (vals.v !== undefined || vals.value !== undefined) { - this.setValues('hsv', vals); - } else if (vals.w !== undefined || vals.whiteness !== undefined) { - this.setValues('hwb', vals); - } else if (vals.c !== undefined || vals.cyan !== undefined) { - this.setValues('cmyk', vals); - } - } -}; - -Color.prototype = { - isValid: function () { - return this.valid; - }, - rgb: function () { - return this.setSpace('rgb', arguments); - }, - hsl: function () { - return this.setSpace('hsl', arguments); - }, - hsv: function () { - return this.setSpace('hsv', arguments); - }, - hwb: function () { - return this.setSpace('hwb', arguments); - }, - cmyk: function () { - return this.setSpace('cmyk', arguments); - }, - - rgbArray: function () { - return this.values.rgb; - }, - hslArray: function () { - return this.values.hsl; - }, - hsvArray: function () { - return this.values.hsv; - }, - hwbArray: function () { - var values = this.values; - if (values.alpha !== 1) { - return values.hwb.concat([values.alpha]); - } - return values.hwb; - }, - cmykArray: function () { - return this.values.cmyk; - }, - rgbaArray: function () { - var values = this.values; - return values.rgb.concat([values.alpha]); - }, - hslaArray: function () { - var values = this.values; - return values.hsl.concat([values.alpha]); - }, - alpha: function (val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues('alpha', val); - return this; - }, - - red: function (val) { - return this.setChannel('rgb', 0, val); - }, - green: function (val) { - return this.setChannel('rgb', 1, val); - }, - blue: function (val) { - return this.setChannel('rgb', 2, val); - }, - hue: function (val) { - if (val) { - val %= 360; - val = val < 0 ? 360 + val : val; - } - return this.setChannel('hsl', 0, val); - }, - saturation: function (val) { - return this.setChannel('hsl', 1, val); - }, - lightness: function (val) { - return this.setChannel('hsl', 2, val); - }, - saturationv: function (val) { - return this.setChannel('hsv', 1, val); - }, - whiteness: function (val) { - return this.setChannel('hwb', 1, val); - }, - blackness: function (val) { - return this.setChannel('hwb', 2, val); - }, - value: function (val) { - return this.setChannel('hsv', 2, val); - }, - cyan: function (val) { - return this.setChannel('cmyk', 0, val); - }, - magenta: function (val) { - return this.setChannel('cmyk', 1, val); - }, - yellow: function (val) { - return this.setChannel('cmyk', 2, val); - }, - black: function (val) { - return this.setChannel('cmyk', 3, val); - }, - - hexString: function () { - return colorString.hexString(this.values.rgb); - }, - rgbString: function () { - return colorString.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function () { - return colorString.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function () { - return colorString.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function () { - return colorString.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function () { - return colorString.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function () { - return colorString.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function () { - return colorString.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function () { - var rgb = this.values.rgb; - return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; - }, - - luminosity: function () { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function (color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05); - } - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function (color2) { - var contrastRatio = this.contrast(color2); - if (contrastRatio >= 7.1) { - return 'AAA'; - } - - return (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function () { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb; - var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function () { - return !this.dark(); - }, - - negate: function () { - var rgb = []; - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues('rgb', rgb); - return this; - }, - - lighten: function (ratio) { - var hsl = this.values.hsl; - hsl[2] += hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - darken: function (ratio) { - var hsl = this.values.hsl; - hsl[2] -= hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - saturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] += hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - desaturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] -= hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - whiten: function (ratio) { - var hwb = this.values.hwb; - hwb[1] += hwb[1] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - blacken: function (ratio) { - var hwb = this.values.hwb; - hwb[2] += hwb[2] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - greyscale: function () { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues('rgb', [val, val, val]); - return this; - }, - - clearer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha - (alpha * ratio)); - return this; - }, - - opaquer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha + (alpha * ratio)); - return this; - }, - - rotate: function (degrees) { - var hsl = this.values.hsl; - var hue = (hsl[0] + degrees) % 360; - hsl[0] = hue < 0 ? 360 + hue : hue; - this.setValues('hsl', hsl); - return this; - }, - - /** - * Ported from sass implementation in C - * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 - */ - mix: function (mixinColor, weight) { - var color1 = this; - var color2 = mixinColor; - var p = weight === undefined ? 0.5 : weight; - - var w = 2 * p - 1; - var a = color1.alpha() - color2.alpha(); - - var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - return this - .rgb( - w1 * color1.red() + w2 * color2.red(), - w1 * color1.green() + w2 * color2.green(), - w1 * color1.blue() + w2 * color2.blue() - ) - .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); - }, - - toJSON: function () { - return this.rgb(); - }, - - clone: function () { - // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, - // making the final build way to big to embed in Chart.js. So let's do it manually, - // assuming that values to clone are 1 dimension arrays containing only numbers, - // except 'alpha' which is a number. - var result = new Color(); - var source = this.values; - var target = result.values; - var value, type; - - for (var prop in source) { - if (source.hasOwnProperty(prop)) { - value = source[prop]; - type = ({}).toString.call(value); - if (type === '[object Array]') { - target[prop] = value.slice(0); - } else if (type === '[object Number]') { - target[prop] = value; - } else { - console.error('unexpected color value:', value); - } - } - } - - return result; - } -}; - -Color.prototype.spaces = { - rgb: ['red', 'green', 'blue'], - hsl: ['hue', 'saturation', 'lightness'], - hsv: ['hue', 'saturation', 'value'], - hwb: ['hue', 'whiteness', 'blackness'], - cmyk: ['cyan', 'magenta', 'yellow', 'black'] -}; - -Color.prototype.maxes = { - rgb: [255, 255, 255], - hsl: [360, 100, 100], - hsv: [360, 100, 100], - hwb: [360, 100, 100], - cmyk: [100, 100, 100, 100] -}; - -Color.prototype.getValues = function (space) { - var values = this.values; - var vals = {}; - - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = values[space][i]; - } - - if (values.alpha !== 1) { - vals.a = values.alpha; - } - - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; -}; - -Color.prototype.setValues = function (space, vals) { - var values = this.values; - var spaces = this.spaces; - var maxes = this.maxes; - var alpha = 1; - var i; - - this.valid = true; - - if (space === 'alpha') { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (i = 0; i < space.length; i++) { - values[space][i] = vals[space.charAt(i)]; - } - - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - - for (i = 0; i < space.length; i++) { - values[space][i] = vals[chans[i]]; - } - - alpha = vals.alpha; - } - - values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); - - if (space === 'alpha') { - return false; - } - - var capped; - - // cap values of the space prior converting all values - for (i = 0; i < space.length; i++) { - capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); - values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname !== space) { - values[sname] = colorConvert[space][sname](values[space]); - } - } - - return true; -}; - -Color.prototype.setSpace = function (space, args) { - var vals = args[0]; - - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - - // color.rgb(10, 10, 10) - if (typeof vals === 'number') { - vals = Array.prototype.slice.call(args); - } - - this.setValues(space, vals); - return this; -}; - -Color.prototype.setChannel = function (space, index, val) { - var svalues = this.values[space]; - if (val === undefined) { - // color.red() - return svalues[index]; - } else if (val === svalues[index]) { - // color.red(color.red()) - return this; - } - - // color.red(100) - svalues[index] = val; - this.setValues(space, svalues); - - return this; -}; - -if (typeof _window !== 'undefined') { - console.debug(_window) - _window.Color = Color; -} - -var chartjsColor = Color; - -function isValidKey(key) { - return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1; -} - -/** - * @namespace Chart.helpers - */ -var helpers = { - /** - * An empty function that can be used, for example, for optional callback. - */ - noop: function() {}, - - /** - * Returns a unique id, sequentially generated from a global variable. - * @returns {number} - * @function - */ - uid: (function() { - var id = 0; - return function() { - return id++; - }; - }()), - - /** - * Returns true if `value` is neither null nor undefined, else returns false. - * @param {*} value - The value to test. - * @returns {boolean} - * @since 2.7.0 - */ - isNullOrUndef: function(value) { - return value === null || typeof value === 'undefined'; - }, - - /** - * Returns true if `value` is an array (including typed arrays), else returns false. - * @param {*} value - The value to test. - * @returns {boolean} - * @function - */ - isArray: function(value) { - if (Array.isArray && Array.isArray(value)) { - return true; - } - var type = Object.prototype.toString.call(value); - if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') { - return true; - } - return false; - }, - - /** - * Returns true if `value` is an object (excluding null), else returns false. - * @param {*} value - The value to test. - * @returns {boolean} - * @since 2.7.0 - */ - isObject: function(value) { - return value !== null && Object.prototype.toString.call(value) === '[object Object]'; - }, - - /** - * Returns true if `value` is a finite number, else returns false - * @param {*} value - The value to test. - * @returns {boolean} - */ - isFinite: function(value) { - return (typeof value === 'number' || value instanceof Number) && isFinite(value); - }, - - /** - * Returns `value` if defined, else returns `defaultValue`. - * @param {*} value - The value to return if defined. - * @param {*} defaultValue - The value to return if `value` is undefined. - * @returns {*} - */ - valueOrDefault: function(value, defaultValue) { - return typeof value === 'undefined' ? defaultValue : value; - }, - - /** - * Returns value at the given `index` in array if defined, else returns `defaultValue`. - * @param {Array} value - The array to lookup for value at `index`. - * @param {number} index - The index in `value` to lookup for value. - * @param {*} defaultValue - The value to return if `value[index]` is undefined. - * @returns {*} - */ - valueAtIndexOrDefault: function(value, index, defaultValue) { - return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue); - }, - - /** - * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the - * value returned by `fn`. If `fn` is not a function, this method returns undefined. - * @param {function} fn - The function to call. - * @param {Array|undefined|null} args - The arguments with which `fn` should be called. - * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. - * @returns {*} - */ - callback: function(fn, args, thisArg) { - if (fn && typeof fn.call === 'function') { - return fn.apply(thisArg, args); - } - }, - - /** - * Note(SB) for performance sake, this method should only be used when loopable type - * is unknown or in none intensive code (not called often and small loopable). Else - * it's preferable to use a regular for() loop and save extra function calls. - * @param {object|Array} loopable - The object or array to be iterated. - * @param {function} fn - The function to call for each item. - * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. - * @param {boolean} [reverse] - If true, iterates backward on the loopable. - */ - each: function(loopable, fn, thisArg, reverse) { - var i, len, keys; - if (helpers.isArray(loopable)) { - len = loopable.length; - if (reverse) { - for (i = len - 1; i >= 0; i--) { - fn.call(thisArg, loopable[i], i); - } - } else { - for (i = 0; i < len; i++) { - fn.call(thisArg, loopable[i], i); - } - } - } else if (helpers.isObject(loopable)) { - keys = Object.keys(loopable); - len = keys.length; - for (i = 0; i < len; i++) { - fn.call(thisArg, loopable[keys[i]], keys[i]); - } - } - }, - - /** - * Returns true if the `a0` and `a1` arrays have the same content, else returns false. - * @see https://stackoverflow.com/a/14853974 - * @param {Array} a0 - The array to compare - * @param {Array} a1 - The array to compare - * @returns {boolean} - */ - arrayEquals: function(a0, a1) { - var i, ilen, v0, v1; - - if (!a0 || !a1 || a0.length !== a1.length) { - return false; - } - - for (i = 0, ilen = a0.length; i < ilen; ++i) { - v0 = a0[i]; - v1 = a1[i]; - - if (v0 instanceof Array && v1 instanceof Array) { - if (!helpers.arrayEquals(v0, v1)) { - return false; - } - } else if (v0 !== v1) { - // NOTE: two different object instances will never be equal: {x:20} != {x:20} - return false; - } - } - - return true; - }, - - /** - * Returns a deep copy of `source` without keeping references on objects and arrays. - * @param {*} source - The value to clone. - * @returns {*} - */ - clone: function(source) { - if (helpers.isArray(source)) { - return source.map(helpers.clone); - } - - if (helpers.isObject(source)) { - var target = Object.create(source); - var keys = Object.keys(source); - var klen = keys.length; - var k = 0; - - for (; k < klen; ++k) { - target[keys[k]] = helpers.clone(source[keys[k]]); - } - - return target; - } - - return source; - }, - - /** - * The default merger when Chart.helpers.merge is called without merger option. - * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback. - * @private - */ - _merger: function(key, target, source, options) { - if (!isValidKey(key)) { - // We want to ensure we do not copy prototypes over - // as this can pollute global namespaces - return; - } - - var tval = target[key]; - var sval = source[key]; - - if (helpers.isObject(tval) && helpers.isObject(sval)) { - helpers.merge(tval, sval, options); - } else { - target[key] = helpers.clone(sval); - } - }, - - /** - * Merges source[key] in target[key] only if target[key] is undefined. - * @private - */ - _mergerIf: function(key, target, source) { - if (!isValidKey(key)) { - // We want to ensure we do not copy prototypes over - // as this can pollute global namespaces - return; - } - - var tval = target[key]; - var sval = source[key]; - - if (helpers.isObject(tval) && helpers.isObject(sval)) { - helpers.mergeIf(tval, sval); - } else if (!target.hasOwnProperty(key)) { - target[key] = helpers.clone(sval); - } - }, - - /** - * Recursively deep copies `source` properties into `target` with the given `options`. - * IMPORTANT: `target` is not cloned and will be updated with `source` properties. - * @param {object} target - The target object in which all sources are merged into. - * @param {object|object[]} source - Object(s) to merge into `target`. - * @param {object} [options] - Merging options: - * @param {function} [options.merger] - The merge method (key, target, source, options) - * @returns {object} The `target` object. - */ - merge: function(target, source, options) { - var sources = helpers.isArray(source) ? source : [source]; - var ilen = sources.length; - var merge, i, keys, klen, k; - - if (!helpers.isObject(target)) { - return target; - } - - options = options || {}; - merge = options.merger || helpers._merger; - - for (i = 0; i < ilen; ++i) { - source = sources[i]; - if (!helpers.isObject(source)) { - continue; - } - - keys = Object.keys(source); - for (k = 0, klen = keys.length; k < klen; ++k) { - merge(keys[k], target, source, options); - } - } - - return target; - }, - - /** - * Recursively deep copies `source` properties into `target` *only* if not defined in target. - * IMPORTANT: `target` is not cloned and will be updated with `source` properties. - * @param {object} target - The target object in which all sources are merged into. - * @param {object|object[]} source - Object(s) to merge into `target`. - * @returns {object} The `target` object. - */ - mergeIf: function(target, source) { - return helpers.merge(target, source, {merger: helpers._mergerIf}); - }, - - /** - * Applies the contents of two or more objects together into the first object. - * @param {object} target - The target object in which all objects are merged into. - * @param {object} arg1 - Object containing additional properties to merge in target. - * @param {object} argN - Additional objects containing properties to merge in target. - * @returns {object} The `target` object. - */ - extend: Object.assign || function(target) { - return helpers.merge(target, [].slice.call(arguments, 1), { - merger: function(key, dst, src) { - dst[key] = src[key]; - } - }); - }, - - /** - * Basic javascript inheritance based on the model created in Backbone.js - */ - inherits: function(extensions) { - var me = this; - var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() { - return me.apply(this, arguments); - }; - - var Surrogate = function() { - this.constructor = ChartElement; - }; - - Surrogate.prototype = me.prototype; - ChartElement.prototype = new Surrogate(); - ChartElement.extend = helpers.inherits; - - if (extensions) { - helpers.extend(ChartElement.prototype, extensions); - } - - ChartElement.__super__ = me.prototype; - return ChartElement; - }, - - _deprecated: function(scope, value, previous, current) { - if (value !== undefined) { - console.warn(scope + ': "' + previous + - '" is deprecated. Please use "' + current + '" instead'); - } - } -}; - -var helpers_core = helpers; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.callback instead. - * @function Chart.helpers.callCallback - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ -helpers.callCallback = helpers.callback; - -/** - * Provided for backward compatibility, use Array.prototype.indexOf instead. - * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+ - * @function Chart.helpers.indexOf - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.indexOf = function(array, item, fromIndex) { - return Array.prototype.indexOf.call(array, item, fromIndex); -}; - -/** - * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead. - * @function Chart.helpers.getValueOrDefault - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.getValueOrDefault = helpers.valueOrDefault; - -/** - * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead. - * @function Chart.helpers.getValueAtIndexOrDefault - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault; - -/** - * Easing functions adapted from Robert Penner's easing equations. - * @namespace Chart.helpers.easingEffects - * @see http://www.robertpenner.com/easing/ - */ -var effects = { - linear: function(t) { - return t; - }, - - easeInQuad: function(t) { - return t * t; - }, - - easeOutQuad: function(t) { - return -t * (t - 2); - }, - - easeInOutQuad: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t; - } - return -0.5 * ((--t) * (t - 2) - 1); - }, - - easeInCubic: function(t) { - return t * t * t; - }, - - easeOutCubic: function(t) { - return (t = t - 1) * t * t + 1; - }, - - easeInOutCubic: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t; - } - return 0.5 * ((t -= 2) * t * t + 2); - }, - - easeInQuart: function(t) { - return t * t * t * t; - }, - - easeOutQuart: function(t) { - return -((t = t - 1) * t * t * t - 1); - }, - - easeInOutQuart: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t * t; - } - return -0.5 * ((t -= 2) * t * t * t - 2); - }, - - easeInQuint: function(t) { - return t * t * t * t * t; - }, - - easeOutQuint: function(t) { - return (t = t - 1) * t * t * t * t + 1; - }, - - easeInOutQuint: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t * t * t; - } - return 0.5 * ((t -= 2) * t * t * t * t + 2); - }, - - easeInSine: function(t) { - return -Math.cos(t * (Math.PI / 2)) + 1; - }, - - easeOutSine: function(t) { - return Math.sin(t * (Math.PI / 2)); - }, - - easeInOutSine: function(t) { - return -0.5 * (Math.cos(Math.PI * t) - 1); - }, - - easeInExpo: function(t) { - return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); - }, - - easeOutExpo: function(t) { - return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; - }, - - easeInOutExpo: function(t) { - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if ((t /= 0.5) < 1) { - return 0.5 * Math.pow(2, 10 * (t - 1)); - } - return 0.5 * (-Math.pow(2, -10 * --t) + 2); - }, - - easeInCirc: function(t) { - if (t >= 1) { - return t; - } - return -(Math.sqrt(1 - t * t) - 1); - }, - - easeOutCirc: function(t) { - return Math.sqrt(1 - (t = t - 1) * t); - }, - - easeInOutCirc: function(t) { - if ((t /= 0.5) < 1) { - return -0.5 * (Math.sqrt(1 - t * t) - 1); - } - return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); - }, - - easeInElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if (!p) { - p = 0.3; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); - }, - - easeOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if (!p) { - p = 0.3; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1; - }, - - easeInOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 0.5) === 2) { - return 1; - } - if (!p) { - p = 0.45; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - if (t < 1) { - return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); - } - return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; - }, - easeInBack: function(t) { - var s = 1.70158; - return t * t * ((s + 1) * t - s); - }, - - easeOutBack: function(t) { - var s = 1.70158; - return (t = t - 1) * t * ((s + 1) * t + s) + 1; - }, - - easeInOutBack: function(t) { - var s = 1.70158; - if ((t /= 0.5) < 1) { - return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); - } - return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - }, - - easeInBounce: function(t) { - return 1 - effects.easeOutBounce(1 - t); - }, - - easeOutBounce: function(t) { - if (t < (1 / 2.75)) { - return 7.5625 * t * t; - } - if (t < (2 / 2.75)) { - return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; - } - if (t < (2.5 / 2.75)) { - return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; - } - return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; - }, - - easeInOutBounce: function(t) { - if (t < 0.5) { - return effects.easeInBounce(t * 2) * 0.5; - } - return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; - } -}; - -var helpers_easing = { - effects: effects -}; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.easing.effects instead. - * @function Chart.helpers.easingEffects - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers_core.easingEffects = effects; - -var PI = Math.PI; -var RAD_PER_DEG = PI / 180; -var DOUBLE_PI = PI * 2; -var HALF_PI = PI / 2; -var QUARTER_PI = PI / 4; -var TWO_THIRDS_PI = PI * 2 / 3; - -/** - * @namespace Chart.helpers.canvas - */ -var exports$1 = { - /** - * Clears the entire canvas associated to the given `chart`. - * @param {Chart} chart - The chart for which to clear the canvas. - */ - clear: function(chart) { - chart.ctx.clearRect(0, 0, chart.width, chart.height); - }, - - /** - * Creates a "path" for a rectangle with rounded corners at position (x, y) with a - * given size (width, height) and the same `radius` for all corners. - * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context. - * @param {number} x - The x axis of the coordinate for the rectangle starting point. - * @param {number} y - The y axis of the coordinate for the rectangle starting point. - * @param {number} width - The rectangle's width. - * @param {number} height - The rectangle's height. - * @param {number} radius - The rounded amount (in pixels) for the four corners. - * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object? - */ - roundedRect: function(ctx, x, y, width, height, radius) { - if (radius) { - var r = Math.min(radius, height / 2, width / 2); - var left = x + r; - var top = y + r; - var right = x + width - r; - var bottom = y + height - r; - - ctx.moveTo(x, top); - if (left < right && top < bottom) { - ctx.arc(left, top, r, -PI, -HALF_PI); - ctx.arc(right, top, r, -HALF_PI, 0); - ctx.arc(right, bottom, r, 0, HALF_PI); - ctx.arc(left, bottom, r, HALF_PI, PI); - } else if (left < right) { - ctx.moveTo(left, y); - ctx.arc(right, top, r, -HALF_PI, HALF_PI); - ctx.arc(left, top, r, HALF_PI, PI + HALF_PI); - } else if (top < bottom) { - ctx.arc(left, top, r, -PI, 0); - ctx.arc(left, bottom, r, 0, PI); - } else { - ctx.arc(left, top, r, -PI, PI); - } - ctx.closePath(); - ctx.moveTo(x, y); - } else { - ctx.rect(x, y, width, height); - } - }, - - drawPoint: function(ctx, style, radius, x, y, rotation) { - var type, xOffset, yOffset, size, cornerRadius; - var rad = (rotation || 0) * RAD_PER_DEG; - - if (style && typeof style === 'object') { - type = style.toString(); - if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { - ctx.save(); - ctx.translate(x, y); - ctx.rotate(rad); - ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); - ctx.restore(); - return; - } - } - - if (isNaN(radius) || radius <= 0) { - return; - } - - ctx.beginPath(); - - switch (style) { - // Default includes circle - default: - ctx.arc(x, y, radius, 0, DOUBLE_PI); - ctx.closePath(); - break; - case 'triangle': - ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); - rad += TWO_THIRDS_PI; - ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); - rad += TWO_THIRDS_PI; - ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); - ctx.closePath(); - break; - case 'rectRounded': - // NOTE: the rounded rect implementation changed to use `arc` instead of - // `quadraticCurveTo` since it generates better results when rect is - // almost a circle. 0.516 (instead of 0.5) produces results with visually - // closer proportion to the previous impl and it is inscribed in the - // circle with `radius`. For more details, see the following PRs: - // https://github.com/chartjs/Chart.js/issues/5597 - // https://github.com/chartjs/Chart.js/issues/5858 - cornerRadius = radius * 0.516; - size = radius - cornerRadius; - xOffset = Math.cos(rad + QUARTER_PI) * size; - yOffset = Math.sin(rad + QUARTER_PI) * size; - ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); - ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad); - ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI); - ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); - ctx.closePath(); - break; - case 'rect': - if (!rotation) { - size = Math.SQRT1_2 * radius; - ctx.rect(x - size, y - size, 2 * size, 2 * size); - break; - } - rad += QUARTER_PI; - /* falls through */ - case 'rectRot': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + yOffset, y - xOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.lineTo(x - yOffset, y + xOffset); - ctx.closePath(); - break; - case 'crossRot': - rad += QUARTER_PI; - /* falls through */ - case 'cross': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.moveTo(x + yOffset, y - xOffset); - ctx.lineTo(x - yOffset, y + xOffset); - break; - case 'star': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.moveTo(x + yOffset, y - xOffset); - ctx.lineTo(x - yOffset, y + xOffset); - rad += QUARTER_PI; - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.moveTo(x + yOffset, y - xOffset); - ctx.lineTo(x - yOffset, y + xOffset); - break; - case 'line': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - break; - case 'dash': - ctx.moveTo(x, y); - ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius); - break; - } - - ctx.fill(); - ctx.stroke(); - }, - - /** - * Returns true if the point is inside the rectangle - * @param {object} point - The point to test - * @param {object} area - The rectangle - * @returns {boolean} - * @private - */ - _isPointInArea: function(point, area) { - var epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error. - - return point.x > area.left - epsilon && point.x < area.right + epsilon && - point.y > area.top - epsilon && point.y < area.bottom + epsilon; - }, - - clipArea: function(ctx, area) { - ctx.save(); - ctx.beginPath(); - ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); - ctx.clip(); - }, - - unclipArea: function(ctx) { - ctx.restore(); - }, - - lineTo: function(ctx, previous, target, flip) { - var stepped = target.steppedLine; - if (stepped) { - if (stepped === 'middle') { - var midpoint = (previous.x + target.x) / 2.0; - ctx.lineTo(midpoint, flip ? target.y : previous.y); - ctx.lineTo(midpoint, flip ? previous.y : target.y); - } else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) { - ctx.lineTo(previous.x, target.y); - } else { - ctx.lineTo(target.x, previous.y); - } - ctx.lineTo(target.x, target.y); - return; - } - - if (!target.tension) { - ctx.lineTo(target.x, target.y); - return; - } - - ctx.bezierCurveTo( - flip ? previous.controlPointPreviousX : previous.controlPointNextX, - flip ? previous.controlPointPreviousY : previous.controlPointNextY, - flip ? target.controlPointNextX : target.controlPointPreviousX, - flip ? target.controlPointNextY : target.controlPointPreviousY, - target.x, - target.y); - } -}; - -var helpers_canvas = exports$1; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.canvas.clear instead. - * @namespace Chart.helpers.clear - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers_core.clear = exports$1.clear; - -/** - * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead. - * @namespace Chart.helpers.drawRoundedRectangle - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers_core.drawRoundedRectangle = function(ctx) { - ctx.beginPath(); - exports$1.roundedRect.apply(exports$1, arguments); -}; - -var defaults = { - /** - * @private - */ - _set: function(scope, values) { - return helpers_core.merge(this[scope] || (this[scope] = {}), values); - } -}; - -// TODO(v3): remove 'global' from namespace. all default are global and -// there's inconsistency around which options are under 'global' -defaults._set('global', { - defaultColor: 'rgba(0,0,0,0.1)', - defaultFontColor: '#666', - defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", - defaultFontSize: 12, - defaultFontStyle: 'normal', - defaultLineHeight: 1.2, - showLines: true -}); - -var core_defaults = defaults; - -var valueOrDefault = helpers_core.valueOrDefault; - -/** - * Converts the given font object into a CSS font string. - * @param {object} font - A font object. - * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font - * @private - */ -function toFontString(font) { - if (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) { - return null; - } - - return (font.style ? font.style + ' ' : '') - + (font.weight ? font.weight + ' ' : '') - + font.size + 'px ' - + font.family; -} - -/** - * @alias Chart.helpers.options - * @namespace - */ -var helpers_options = { - /** - * Converts the given line height `value` in pixels for a specific font `size`. - * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). - * @param {number} size - The font size (in pixels) used to resolve relative `value`. - * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid). - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height - * @since 2.7.0 - */ - toLineHeight: function(value, size) { - var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); - if (!matches || matches[1] === 'normal') { - return size * 1.2; - } - - value = +matches[2]; - - switch (matches[3]) { - case 'px': - return value; - case '%': - value /= 100; - break; - } - - return size * value; - }, - - /** - * Converts the given value into a padding object with pre-computed width/height. - * @param {number|object} value - If a number, set the value to all TRBL component, - * else, if and object, use defined properties and sets undefined ones to 0. - * @returns {object} The padding values (top, right, bottom, left, width, height) - * @since 2.7.0 - */ - toPadding: function(value) { - var t, r, b, l; - - if (helpers_core.isObject(value)) { - t = +value.top || 0; - r = +value.right || 0; - b = +value.bottom || 0; - l = +value.left || 0; - } else { - t = r = b = l = +value || 0; - } - - return { - top: t, - right: r, - bottom: b, - left: l, - height: t + b, - width: l + r - }; - }, - - /** - * Parses font options and returns the font object. - * @param {object} options - A object that contains font options to be parsed. - * @return {object} The font object. - * @todo Support font.* options and renamed to toFont(). - * @private - */ - _parseFont: function(options) { - var globalDefaults = core_defaults.global; - var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize); - var font = { - family: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily), - lineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size), - size: size, - style: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle), - weight: null, - string: '' - }; - - font.string = toFontString(font); - return font; - }, - - /** - * Evaluates the given `inputs` sequentially and returns the first defined value. - * @param {Array} inputs - An array of values, falling back to the last value. - * @param {object} [context] - If defined and the current value is a function, the value - * is called with `context` as first argument and the result becomes the new input. - * @param {number} [index] - If defined and the current value is an array, the value - * at `index` become the new input. - * @param {object} [info] - object to return information about resolution in - * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable. - * @since 2.7.0 - */ - resolve: function(inputs, context, index, info) { - var cacheable = true; - var i, ilen, value; - - for (i = 0, ilen = inputs.length; i < ilen; ++i) { - value = inputs[i]; - if (value === undefined) { - continue; - } - if (context !== undefined && typeof value === 'function') { - value = value(context); - cacheable = false; - } - if (index !== undefined && helpers_core.isArray(value)) { - value = value[index]; - cacheable = false; - } - if (value !== undefined) { - if (info && !cacheable) { - info.cacheable = false; - } - return value; - } - } - } -}; - -/** - * @alias Chart.helpers.math - * @namespace - */ -var exports$2 = { - /** - * Returns an array of factors sorted from 1 to sqrt(value) - * @private - */ - _factorize: function(value) { - var result = []; - var sqrt = Math.sqrt(value); - var i; - - for (i = 1; i < sqrt; i++) { - if (value % i === 0) { - result.push(i); - result.push(value / i); - } - } - if (sqrt === (sqrt | 0)) { // if value is a square number - result.push(sqrt); - } - - result.sort(function(a, b) { - return a - b; - }).pop(); - return result; - }, - - log10: Math.log10 || function(x) { - var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. - // Check for whole powers of 10, - // which due to floating point rounding error should be corrected. - var powerOf10 = Math.round(exponent); - var isPowerOf10 = x === Math.pow(10, powerOf10); - - return isPowerOf10 ? powerOf10 : exponent; - } -}; - -var helpers_math = exports$2; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.math.log10 instead. - * @namespace Chart.helpers.log10 - * @deprecated since version 2.9.0 - * @todo remove at version 3 - * @private - */ -helpers_core.log10 = exports$2.log10; - -var getRtlAdapter = function(rectX, width) { - return { - x: function(x) { - return rectX + rectX + width - x; - }, - setWidth: function(w) { - width = w; - }, - textAlign: function(align) { - if (align === 'center') { - return align; - } - return align === 'right' ? 'left' : 'right'; - }, - xPlus: function(x, value) { - return x - value; - }, - leftForLtr: function(x, itemWidth) { - return x - itemWidth; - }, - }; -}; - -var getLtrAdapter = function() { - return { - x: function(x) { - return x; - }, - setWidth: function(w) { // eslint-disable-line no-unused-vars - }, - textAlign: function(align) { - return align; - }, - xPlus: function(x, value) { - return x + value; - }, - leftForLtr: function(x, _itemWidth) { // eslint-disable-line no-unused-vars - return x; - }, - }; -}; - -var getAdapter = function(rtl, rectX, width) { - return rtl ? getRtlAdapter(rectX, width) : getLtrAdapter(); -}; - -var overrideTextDirection = function(ctx, direction) { - var style, original; - if (direction === 'ltr' || direction === 'rtl') { - style = ctx.canvas.style; - original = [ - style.getPropertyValue('direction'), - style.getPropertyPriority('direction'), - ]; - - style.setProperty('direction', direction, 'important'); - ctx.prevTextDirection = original; - } -}; - -var restoreTextDirection = function(ctx) { - var original = ctx.prevTextDirection; - if (original !== undefined) { - delete ctx.prevTextDirection; - ctx.canvas.style.setProperty('direction', original[0], original[1]); - } -}; - -var helpers_rtl = { - getRtlAdapter: getAdapter, - overrideTextDirection: overrideTextDirection, - restoreTextDirection: restoreTextDirection, -}; - -var helpers$1 = helpers_core; -var easing = helpers_easing; -var canvas = helpers_canvas; -var options = helpers_options; -var math = helpers_math; -var rtl = helpers_rtl; -helpers$1.easing = easing; -helpers$1.canvas = canvas; -helpers$1.options = options; -helpers$1.math = math; -helpers$1.rtl = rtl; - -function interpolate(start, view, model, ease) { - var keys = Object.keys(model); - var i, ilen, key, actual, origin, target, type, c0, c1; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - - target = model[key]; - - // if a value is added to the model after pivot() has been called, the view - // doesn't contain it, so let's initialize the view to the target value. - if (!view.hasOwnProperty(key)) { - view[key] = target; - } - - actual = view[key]; - - if (actual === target || key[0] === '_') { - continue; - } - - if (!start.hasOwnProperty(key)) { - start[key] = actual; - } - - origin = start[key]; - - type = typeof target; - - if (type === typeof origin) { - if (type === 'string') { - c0 = chartjsColor(origin); - if (c0.valid) { - c1 = chartjsColor(target); - if (c1.valid) { - view[key] = c1.mix(c0, ease).rgbString(); - continue; - } - } - } else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) { - view[key] = origin + (target - origin) * ease; - continue; - } - } - - view[key] = target; - } -} - -var Element = function(configuration) { - helpers$1.extend(this, configuration); - this.initialize.apply(this, arguments); -}; - -helpers$1.extend(Element.prototype, { - _type: undefined, - - initialize: function() { - this.hidden = false; - }, - - pivot: function() { - var me = this; - if (!me._view) { - me._view = helpers$1.extend({}, me._model); - } - me._start = {}; - return me; - }, - - transition: function(ease) { - var me = this; - var model = me._model; - var start = me._start; - var view = me._view; - - // No animation -> No Transition - if (!model || ease === 1) { - me._view = helpers$1.extend({}, model); - me._start = null; - return me; - } - - if (!view) { - view = me._view = {}; - } - - if (!start) { - start = me._start = {}; - } - - interpolate(start, view, model, ease); - - return me; - }, - - tooltipPosition: function() { - return { - x: this._model.x, - y: this._model.y - }; - }, - - hasValue: function() { - return helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y); - } -}); - -Element.extend = helpers$1.inherits; - -var core_element = Element; - -var exports$3 = core_element.extend({ - chart: null, // the animation associated chart instance - currentStep: 0, // the current animation step - numSteps: 60, // default number of steps - easing: '', // the easing to use for this animation - render: null, // render function used by the animation service - - onAnimationProgress: null, // user specified callback to fire on each step of the animation - onAnimationComplete: null, // user specified callback to fire when the animation finishes -}); - -var core_animation = exports$3; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.Animation instead - * @prop Chart.Animation#animationObject - * @deprecated since version 2.6.0 - * @todo remove at version 3 - */ -Object.defineProperty(exports$3.prototype, 'animationObject', { - get: function() { - return this; - } -}); - -/** - * Provided for backward compatibility, use Chart.Animation#chart instead - * @prop Chart.Animation#chartInstance - * @deprecated since version 2.6.0 - * @todo remove at version 3 - */ -Object.defineProperty(exports$3.prototype, 'chartInstance', { - get: function() { - return this.chart; - }, - set: function(value) { - this.chart = value; - } -}); - -core_defaults._set('global', { - animation: { - duration: 1000, - easing: 'easeOutQuart', - onProgress: helpers$1.noop, - onComplete: helpers$1.noop - } -}); - -var core_animations = { - animations: [], - request: null, - - /** - * @param {Chart} chart - The chart to animate. - * @param {Chart.Animation} animation - The animation that we will animate. - * @param {number} duration - The animation duration in ms. - * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions - */ - addAnimation: function(chart, animation, duration, lazy) { - var animations = this.animations; - var i, ilen; - - animation.chart = chart; - animation.startTime = Date.now(); - animation.duration = duration; - - if (!lazy) { - chart.animating = true; - } - - for (i = 0, ilen = animations.length; i < ilen; ++i) { - if (animations[i].chart === chart) { - animations[i] = animation; - return; - } - } - - animations.push(animation); - - // If there are no animations queued, manually kickstart a digest, for lack of a better word - if (animations.length === 1) { - this.requestAnimationFrame(); - } - }, - - cancelAnimation: function(chart) { - var index = helpers$1.findIndex(this.animations, function(animation) { - return animation.chart === chart; - }); - - if (index !== -1) { - this.animations.splice(index, 1); - chart.animating = false; - } - }, - - requestAnimationFrame: function() { - var me = this; - if (me.request === null) { - return; - // TBD: animation should work somehow; what is startDigest? - - // Skip animation frame requests until the active one is executed. - // This can happen when processing mouse events, e.g. 'mousemove' - // and 'mouseout' events will trigger multiple renders. - me.request = helpers$1.requestAnimFrame.call(undefined, function() { - me.request = null; - me.startDigest(); - }); - } - }, - - /** - * @private - */ - startDigest: function() { - var me = this; - - me.advance(); - - // Do we have more stuff to animate? - if (me.animations.length > 0) { - me.requestAnimationFrame(); - } - }, - - /** - * @private - */ - advance: function() { - var animations = this.animations; - var animation, chart, numSteps, nextStep; - var i = 0; - - // 1 animation per chart, so we are looping charts here - while (i < animations.length) { - animation = animations[i]; - chart = animation.chart; - numSteps = animation.numSteps; - - // Make sure that currentStep starts at 1 - // https://github.com/chartjs/Chart.js/issues/6104 - nextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1; - animation.currentStep = Math.min(nextStep, numSteps); - - helpers$1.callback(animation.render, [chart, animation], chart); - helpers$1.callback(animation.onAnimationProgress, [animation], chart); - - if (animation.currentStep >= numSteps) { - helpers$1.callback(animation.onAnimationComplete, [animation], chart); - chart.animating = false; - animations.splice(i, 1); - } else { - ++i; - } - } - } -}; - -var resolve = helpers$1.options.resolve; - -var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; - -/** - * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', - * 'unshift') and notify the listener AFTER the array has been altered. Listeners are - * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments. - */ -function listenArrayEvents(array, listener) { - if (array._chartjs) { - array._chartjs.listeners.push(listener); - return; - } - - Object.defineProperty(array, '_chartjs', { - configurable: true, - enumerable: false, - value: { - listeners: [listener] - } - }); - - arrayEvents.forEach(function(key) { - var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1); - var base = array[key]; - - Object.defineProperty(array, key, { - configurable: true, - enumerable: false, - value: function() { - var args = Array.prototype.slice.call(arguments); - var res = base.apply(this, args); - - helpers$1.each(array._chartjs.listeners, function(object) { - if (typeof object[method] === 'function') { - object[method].apply(object, args); - } - }); - - return res; - } - }); - }); -} - -/** - * Removes the given array event listener and cleanup extra attached properties (such as - * the _chartjs stub and overridden methods) if array doesn't have any more listeners. - */ -function unlistenArrayEvents(array, listener) { - var stub = array._chartjs; - if (!stub) { - return; - } - - var listeners = stub.listeners; - var index = listeners.indexOf(listener); - if (index !== -1) { - listeners.splice(index, 1); - } - - if (listeners.length > 0) { - return; - } - - arrayEvents.forEach(function(key) { - delete array[key]; - }); - - delete array._chartjs; -} - -// Base class for all dataset controllers (line, bar, etc) -var DatasetController = function(chart, datasetIndex) { - this.initialize(chart, datasetIndex); -}; - -helpers$1.extend(DatasetController.prototype, { - - /** - * Element type used to generate a meta dataset (e.g. Chart.element.Line). - * @type {Chart.core.element} - */ - datasetElementType: null, - - /** - * Element type used to generate a meta data (e.g. Chart.element.Point). - * @type {Chart.core.element} - */ - dataElementType: null, - - /** - * Dataset element option keys to be resolved in _resolveDatasetElementOptions. - * A derived controller may override this to resolve controller-specific options. - * The keys defined here are for backward compatibility for legend styles. - * @private - */ - _datasetElementOptions: [ - 'backgroundColor', - 'borderCapStyle', - 'borderColor', - 'borderDash', - 'borderDashOffset', - 'borderJoinStyle', - 'borderWidth' - ], - - /** - * Data element option keys to be resolved in _resolveDataElementOptions. - * A derived controller may override this to resolve controller-specific options. - * The keys defined here are for backward compatibility for legend styles. - * @private - */ - _dataElementOptions: [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'pointStyle' - ], - - initialize: function(chart, datasetIndex) { - var me = this; - me.chart = chart; - me.index = datasetIndex; - me.linkScales(); - me.addElements(); - me._type = me.getMeta().type; - }, - - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - - linkScales: function() { - var me = this; - var meta = me.getMeta(); - var chart = me.chart; - var scales = chart.scales; - var dataset = me.getDataset(); - var scalesOpts = chart.options.scales; - - if (meta.xAxisID === null || !(meta.xAxisID in scales) || dataset.xAxisID) { - meta.xAxisID = dataset.xAxisID || scalesOpts.xAxes[0].id; - } - if (meta.yAxisID === null || !(meta.yAxisID in scales) || dataset.yAxisID) { - meta.yAxisID = dataset.yAxisID || scalesOpts.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getMeta: function() { - return this.chart.getDatasetMeta(this.index); - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - - /** - * @private - */ - _getValueScaleId: function() { - return this.getMeta().yAxisID; - }, - - /** - * @private - */ - _getIndexScaleId: function() { - return this.getMeta().xAxisID; - }, - - /** - * @private - */ - _getValueScale: function() { - return this.getScaleForId(this._getValueScaleId()); - }, - - /** - * @private - */ - _getIndexScale: function() { - return this.getScaleForId(this._getIndexScaleId()); - }, - - reset: function() { - this._update(true); - }, - - /** - * @private - */ - destroy: function() { - if (this._data) { - unlistenArrayEvents(this._data, this); - } - }, - - createMetaDataset: function() { - var me = this; - var type = me.datasetElementType; - return type && new type({ - _chart: me.chart, - _datasetIndex: me.index - }); - }, - - createMetaData: function(index) { - var me = this; - var type = me.dataElementType; - return type && new type({ - _chart: me.chart, - _datasetIndex: me.index, - _index: index - }); - }, - - addElements: function() { - var me = this; - var meta = me.getMeta(); - var data = me.getDataset().data || []; - var metaData = meta.data; - var i, ilen; - - for (i = 0, ilen = data.length; i < ilen; ++i) { - metaData[i] = metaData[i] || me.createMetaData(i); - } - - meta.dataset = meta.dataset || me.createMetaDataset(); - }, - - addElementAndReset: function(index) { - var element = this.createMetaData(index); - this.getMeta().data.splice(index, 0, element); - this.updateElement(element, index, true); - }, - - buildOrUpdateElements: function() { - var me = this; - var dataset = me.getDataset(); - var data = dataset.data || (dataset.data = []); - - // In order to correctly handle data addition/deletion animation (an thus simulate - // real-time charts), we need to monitor these data modifications and synchronize - // the internal meta data accordingly. - if (me._data !== data) { - if (me._data) { - // This case happens when the user replaced the data array instance. - unlistenArrayEvents(me._data, me); - } - - if (data && Object.isExtensible(data)) { - listenArrayEvents(data, me); - } - me._data = data; - } - - // Re-sync meta data in case the user replaced the data array or if we missed - // any updates and so make sure that we handle number of datapoints changing. - me.resyncElements(); - }, - - /** - * Returns the merged user-supplied and default dataset-level options - * @private - */ - _configure: function() { - var me = this; - me._config = helpers$1.merge(Object.create(null), [ - me.chart.options.datasets[me._type], - me.getDataset(), - ], { - merger: function(key, target, source) { - if (key !== '_meta' && key !== 'data') { - helpers$1._merger(key, target, source); - } - } - }); - }, - - _update: function(reset) { - var me = this; - me._configure(); - me._cachedDataOpts = null; - me.update(reset); - }, - - update: helpers$1.noop, - - transition: function(easingValue) { - var meta = this.getMeta(); - var elements = meta.data || []; - var ilen = elements.length; - var i = 0; - - for (; i < ilen; ++i) { - elements[i].transition(easingValue); - } - - if (meta.dataset) { - meta.dataset.transition(easingValue); - } - }, - - draw: function() { - var meta = this.getMeta(); - var elements = meta.data || []; - var ilen = elements.length; - var i = 0; - - if (meta.dataset) { - meta.dataset.draw(); - } - - for (; i < ilen; ++i) { - elements[i].draw(); - } - }, - - /** - * Returns a set of predefined style properties that should be used to represent the dataset - * or the data if the index is specified - * @param {number} index - data index - * @return {IStyleInterface} style object - */ - getStyle: function(index) { - var me = this; - var meta = me.getMeta(); - var dataset = meta.dataset; - var style; - - me._configure(); - if (dataset && index === undefined) { - style = me._resolveDatasetElementOptions(dataset || {}); - } else { - index = index || 0; - style = me._resolveDataElementOptions(meta.data[index] || {}, index); - } - - if (style.fill === false || style.fill === null) { - style.backgroundColor = style.borderColor; - } - - return style; - }, - - /** - * @private - */ - _resolveDatasetElementOptions: function(element, hover) { - var me = this; - var chart = me.chart; - var datasetOpts = me._config; - var custom = element.custom || {}; - var options = chart.options.elements[me.datasetElementType.prototype._type] || {}; - var elementOptions = me._datasetElementOptions; - var values = {}; - var i, ilen, key, readKey; - - // Scriptable options - var context = { - chart: chart, - dataset: me.getDataset(), - datasetIndex: me.index, - hover: hover - }; - - for (i = 0, ilen = elementOptions.length; i < ilen; ++i) { - key = elementOptions[i]; - readKey = hover ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key; - values[key] = resolve([ - custom[readKey], - datasetOpts[readKey], - options[readKey] - ], context); - } - - return values; - }, - - /** - * @private - */ - _resolveDataElementOptions: function(element, index) { - var me = this; - var custom = element && element.custom; - var cached = me._cachedDataOpts; - if (cached && !custom) { - return cached; - } - var chart = me.chart; - var datasetOpts = me._config; - var options = chart.options.elements[me.dataElementType.prototype._type] || {}; - var elementOptions = me._dataElementOptions; - var values = {}; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: me.getDataset(), - datasetIndex: me.index - }; - - // `resolve` sets cacheable to `false` if any option is indexed or scripted - var info = {cacheable: !custom}; - - var keys, i, ilen, key; - - custom = custom || {}; - - if (helpers$1.isArray(elementOptions)) { - for (i = 0, ilen = elementOptions.length; i < ilen; ++i) { - key = elementOptions[i]; - values[key] = resolve([ - custom[key], - datasetOpts[key], - options[key] - ], context, index, info); - } - } else { - keys = Object.keys(elementOptions); - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve([ - custom[key], - datasetOpts[elementOptions[key]], - datasetOpts[key], - options[key] - ], context, index, info); - } - } - - if (info.cacheable) { - me._cachedDataOpts = Object.freeze(values); - } - - return values; - }, - - removeHoverStyle: function(element) { - helpers$1.merge(element._model, element.$previousStyle || {}); - delete element.$previousStyle; - }, - - setHoverStyle: function(element) { - var dataset = this.chart.data.datasets[element._datasetIndex]; - var index = element._index; - var custom = element.custom || {}; - var model = element._model; - var getHoverColor = helpers$1.getHoverColor; - - element.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth - }; - - model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index); - model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index); - model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index); - }, - - /** - * @private - */ - _removeDatasetHoverStyle: function() { - var element = this.getMeta().dataset; - - if (element) { - this.removeHoverStyle(element); - } - }, - - /** - * @private - */ - _setDatasetHoverStyle: function() { - var element = this.getMeta().dataset; - var prev = {}; - var i, ilen, key, keys, hoverOptions, model; - - if (!element) { - return; - } - - model = element._model; - hoverOptions = this._resolveDatasetElementOptions(element, true); - - keys = Object.keys(hoverOptions); - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - prev[key] = model[key]; - model[key] = hoverOptions[key]; - } - - element.$previousStyle = prev; - }, - - /** - * @private - */ - resyncElements: function() { - var me = this; - var meta = me.getMeta(); - var data = me.getDataset().data; - var numMeta = meta.data.length; - var numData = data.length; - - if (numData < numMeta) { - meta.data.splice(numData, numMeta - numData); - } else if (numData > numMeta) { - me.insertElements(numMeta, numData - numMeta); - } - }, - - /** - * @private - */ - insertElements: function(start, count) { - for (var i = 0; i < count; ++i) { - this.addElementAndReset(start + i); - } - }, - - /** - * @private - */ - onDataPush: function() { - var count = arguments.length; - this.insertElements(this.getDataset().data.length - count, count); - }, - - /** - * @private - */ - onDataPop: function() { - this.getMeta().data.pop(); - }, - - /** - * @private - */ - onDataShift: function() { - this.getMeta().data.shift(); - }, - - /** - * @private - */ - onDataSplice: function(start, count) { - this.getMeta().data.splice(start, count); - this.insertElements(start, arguments.length - 2); - }, - - /** - * @private - */ - onDataUnshift: function() { - this.insertElements(0, arguments.length); - } -}); - -DatasetController.extend = helpers$1.inherits; - -var core_datasetController = DatasetController; - -var TAU = Math.PI * 2; - -core_defaults._set('global', { - elements: { - arc: { - backgroundColor: core_defaults.global.defaultColor, - borderColor: '#fff', - borderWidth: 2, - borderAlign: 'center' - } - } -}); - -function clipArc(ctx, arc) { - var startAngle = arc.startAngle; - var endAngle = arc.endAngle; - var pixelMargin = arc.pixelMargin; - var angleMargin = pixelMargin / arc.outerRadius; - var x = arc.x; - var y = arc.y; - - // Draw an inner border by cliping the arc and drawing a double-width border - // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders - ctx.beginPath(); - ctx.arc(x, y, arc.outerRadius, startAngle - angleMargin, endAngle + angleMargin); - if (arc.innerRadius > pixelMargin) { - angleMargin = pixelMargin / arc.innerRadius; - ctx.arc(x, y, arc.innerRadius - pixelMargin, endAngle + angleMargin, startAngle - angleMargin, true); - } else { - ctx.arc(x, y, pixelMargin, endAngle + Math.PI / 2, startAngle - Math.PI / 2); - } - ctx.closePath(); - ctx.clip(); -} - -function drawFullCircleBorders(ctx, vm, arc, inner) { - var endAngle = arc.endAngle; - var i; - - if (inner) { - arc.endAngle = arc.startAngle + TAU; - clipArc(ctx, arc); - arc.endAngle = endAngle; - if (arc.endAngle === arc.startAngle && arc.fullCircles) { - arc.endAngle += TAU; - arc.fullCircles--; - } - } - - ctx.beginPath(); - ctx.arc(arc.x, arc.y, arc.innerRadius, arc.startAngle + TAU, arc.startAngle, true); - for (i = 0; i < arc.fullCircles; ++i) { - ctx.stroke(); - } - - ctx.beginPath(); - ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.startAngle + TAU); - for (i = 0; i < arc.fullCircles; ++i) { - ctx.stroke(); - } -} - -function drawBorder(ctx, vm, arc) { - var inner = vm.borderAlign === 'inner'; - - if (inner) { - ctx.lineWidth = vm.borderWidth * 2; - ctx.lineJoin = 'round'; - } else { - ctx.lineWidth = vm.borderWidth; - ctx.lineJoin = 'bevel'; - } - - if (arc.fullCircles) { - drawFullCircleBorders(ctx, vm, arc, inner); - } - - if (inner) { - clipArc(ctx, arc); - } - - ctx.beginPath(); - ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.endAngle); - ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); - ctx.closePath(); - ctx.stroke(); -} - -var element_arc = core_element.extend({ - _type: 'arc', - - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); - } - return false; - }, - - inRange: function(chartX, chartY) { - var vm = this._view; - - if (vm) { - var pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY}); - var angle = pointRelativePosition.angle; - var distance = pointRelativePosition.distance; - - // Sanitise angle range - var startAngle = vm.startAngle; - var endAngle = vm.endAngle; - while (endAngle < startAngle) { - endAngle += TAU; - } - while (angle > endAngle) { - angle -= TAU; - } - while (angle < startAngle) { - angle += TAU; - } - - // Check if within the range of the open/close angle - var betweenAngles = (angle >= startAngle && angle <= endAngle); - var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); - - return (betweenAngles && withinRadius); - } - return false; - }, - - getCenterPoint: function() { - var vm = this._view; - var halfAngle = (vm.startAngle + vm.endAngle) / 2; - var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; - return { - x: vm.x + Math.cos(halfAngle) * halfRadius, - y: vm.y + Math.sin(halfAngle) * halfRadius - }; - }, - - getArea: function() { - var vm = this._view; - return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); - }, - - tooltipPosition: function() { - var vm = this._view; - var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2); - var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; - - return { - x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), - y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) - }; - }, - - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0; - var arc = { - x: vm.x, - y: vm.y, - innerRadius: vm.innerRadius, - outerRadius: Math.max(vm.outerRadius - pixelMargin, 0), - pixelMargin: pixelMargin, - startAngle: vm.startAngle, - endAngle: vm.endAngle, - fullCircles: Math.floor(vm.circumference / TAU) - }; - var i; - - ctx.save(); - - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - - if (arc.fullCircles) { - arc.endAngle = arc.startAngle + TAU; - ctx.beginPath(); - ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle); - ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); - ctx.closePath(); - for (i = 0; i < arc.fullCircles; ++i) { - ctx.fill(); - } - arc.endAngle = arc.startAngle + vm.circumference % TAU; - } - - ctx.beginPath(); - ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle); - ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); - ctx.closePath(); - ctx.fill(); - - if (vm.borderWidth) { - drawBorder(ctx, vm, arc); - } - - ctx.restore(); - } -}); - -var valueOrDefault$1 = helpers$1.valueOrDefault; - -var defaultColor = core_defaults.global.defaultColor; - -core_defaults._set('global', { - elements: { - line: { - tension: 0.4, - backgroundColor: defaultColor, - borderWidth: 3, - borderColor: defaultColor, - borderCapStyle: 'butt', - borderDash: [], - borderDashOffset: 0.0, - borderJoinStyle: 'miter', - capBezierPoints: true, - fill: true, // do we fill in the area between the line and its base axis - } - } -}); - -var element_line = core_element.extend({ - _type: 'line', - - draw: function() { - var me = this; - var vm = me._view; - var ctx = me._chart.ctx; - var spanGaps = vm.spanGaps; - var points = me._children.slice(); // clone array - var globalDefaults = core_defaults.global; - var globalOptionLineElements = globalDefaults.elements.line; - var lastDrawnIndex = -1; - var closePath = me._loop; - var index, previous, currentVM; - - if (!points.length) { - return; - } - - if (me._loop) { - for (index = 0; index < points.length; ++index) { - previous = helpers$1.previousItem(points, index); - // If the line has an open path, shift the point array - if (!points[index]._view.skip && previous._view.skip) { - points = points.slice(index).concat(points.slice(0, index)); - closePath = spanGaps; - break; - } - } - // If the line has a close path, add the first point again - if (closePath) { - points.push(points[0]); - } - } - - ctx.save(); - - // Stroke Line Options - ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; - - // IE 9 and 10 do not support line dash - if (ctx.setLineDash) { - ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); - } - - // line dash fix for QML - if(ctx.getLineDash && ctx.getLineDash().length === 0) { - ctx.setLineDash([99999]); - } - - ctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset); - ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; - ctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth); - ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; - - // Stroke Line - ctx.beginPath(); - - // First point moves to it's starting position no matter what - currentVM = points[0]._view; - if (!currentVM.skip) { - ctx.moveTo(currentVM.x, currentVM.y); - lastDrawnIndex = 0; - } - - for (index = 1; index < points.length; ++index) { - currentVM = points[index]._view; - previous = lastDrawnIndex === -1 ? helpers$1.previousItem(points, index) : points[lastDrawnIndex]; - - if (!currentVM.skip) { - if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { - // There was a gap and this is the first point after the gap - ctx.moveTo(currentVM.x, currentVM.y); - } else { - // Line to next point - helpers$1.canvas.lineTo(ctx, previous._view, currentVM); - } - lastDrawnIndex = index; - } - } - - if (closePath) { - ctx.closePath(); - } - - ctx.stroke(); - ctx.restore(); - } -}); - -var valueOrDefault$2 = helpers$1.valueOrDefault; - -var defaultColor$1 = core_defaults.global.defaultColor; - -core_defaults._set('global', { - elements: { - point: { - radius: 3, - pointStyle: 'circle', - backgroundColor: defaultColor$1, - borderColor: defaultColor$1, - borderWidth: 1, - // Hover - hitRadius: 1, - hoverRadius: 4, - hoverBorderWidth: 1 - } - } -}); - -function xRange(mouseX) { - var vm = this._view; - return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false; -} - -function yRange(mouseY) { - var vm = this._view; - return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false; -} - -var element_point = core_element.extend({ - _type: 'point', - - inRange: function(mouseX, mouseY) { - var vm = this._view; - return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; - }, - - inLabelRange: xRange, - inXRange: xRange, - inYRange: yRange, - - getCenterPoint: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - }, - - getArea: function() { - return Math.PI * Math.pow(this._view.radius, 2); - }, - - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y, - padding: vm.radius + vm.borderWidth - }; - }, - - draw: function(chartArea) { - var vm = this._view; - var ctx = this._chart.ctx; - var pointStyle = vm.pointStyle; - var rotation = vm.rotation; - var radius = vm.radius; - var x = vm.x; - var y = vm.y; - var globalDefaults = core_defaults.global; - var defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow - - if (vm.skip) { - return; - } - - // Clipping for Points. - if (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) { - ctx.strokeStyle = vm.borderColor || defaultColor; - ctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth); - ctx.fillStyle = vm.backgroundColor || defaultColor; - helpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation); - } - } -}); - -var defaultColor$2 = core_defaults.global.defaultColor; - -core_defaults._set('global', { - elements: { - rectangle: { - backgroundColor: defaultColor$2, - borderColor: defaultColor$2, - borderSkipped: 'bottom', - borderWidth: 0 - } - } -}); - -function isVertical(vm) { - return vm && vm.width !== undefined; -} - -/** - * Helper function to get the bounds of the bar regardless of the orientation - * @param bar {Chart.Element.Rectangle} the bar - * @return {Bounds} bounds of the bar - * @private - */ -function getBarBounds(vm) { - var x1, x2, y1, y2, half; - - if (isVertical(vm)) { - half = vm.width / 2; - x1 = vm.x - half; - x2 = vm.x + half; - y1 = Math.min(vm.y, vm.base); - y2 = Math.max(vm.y, vm.base); - } else { - half = vm.height / 2; - x1 = Math.min(vm.x, vm.base); - x2 = Math.max(vm.x, vm.base); - y1 = vm.y - half; - y2 = vm.y + half; - } - - return { - left: x1, - top: y1, - right: x2, - bottom: y2 - }; -} - -function swap(orig, v1, v2) { - return orig === v1 ? v2 : orig === v2 ? v1 : orig; -} - -function parseBorderSkipped(vm) { - var edge = vm.borderSkipped; - var res = {}; - - if (!edge) { - return res; - } - - if (vm.horizontal) { - if (vm.base > vm.x) { - edge = swap(edge, 'left', 'right'); - } - } else if (vm.base < vm.y) { - edge = swap(edge, 'bottom', 'top'); - } - - res[edge] = true; - return res; -} - -function parseBorderWidth(vm, maxW, maxH) { - var value = vm.borderWidth; - var skip = parseBorderSkipped(vm); - var t, r, b, l; - - if (helpers$1.isObject(value)) { - t = +value.top || 0; - r = +value.right || 0; - b = +value.bottom || 0; - l = +value.left || 0; - } else { - t = r = b = l = +value || 0; - } - - return { - t: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t, - r: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r, - b: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b, - l: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l - }; -} - -function boundingRects(vm) { - var bounds = getBarBounds(vm); - var width = bounds.right - bounds.left; - var height = bounds.bottom - bounds.top; - var border = parseBorderWidth(vm, width / 2, height / 2); - - return { - outer: { - x: bounds.left, - y: bounds.top, - w: width, - h: height - }, - inner: { - x: bounds.left + border.l, - y: bounds.top + border.t, - w: width - border.l - border.r, - h: height - border.t - border.b - } - }; -} - -function inRange(vm, x, y) { - var skipX = x === null; - var skipY = y === null; - var bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm); - - return bounds - && (skipX || x >= bounds.left && x <= bounds.right) - && (skipY || y >= bounds.top && y <= bounds.bottom); -} - -var element_rectangle = core_element.extend({ - _type: 'rectangle', - - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var rects = boundingRects(vm); - var outer = rects.outer; - var inner = rects.inner; - - ctx.save(); - - if (outer.w !== inner.w || outer.h !== inner.h) { - ctx.beginPath(); - ctx.strokeStyle = vm.borderColor; - ctx.strokeRect(inner.x, inner.y, inner.w, inner.h); - ctx.fill('evenodd'); - } - - ctx.fillStyle = vm.backgroundColor; - ctx.fillRect(inner.x, inner.y, inner.w, inner.h); - - ctx.restore(); - }, - - height: function() { - var vm = this._view; - return vm.base - vm.y; - }, - - inRange: function(mouseX, mouseY) { - return inRange(this._view, mouseX, mouseY); - }, - - inLabelRange: function(mouseX, mouseY) { - var vm = this._view; - return isVertical(vm) - ? inRange(vm, mouseX, null) - : inRange(vm, null, mouseY); - }, - - inXRange: function(mouseX) { - return inRange(this._view, mouseX, null); - }, - - inYRange: function(mouseY) { - return inRange(this._view, null, mouseY); - }, - - getCenterPoint: function() { - var vm = this._view; - var x, y; - if (isVertical(vm)) { - x = vm.x; - y = (vm.y + vm.base) / 2; - } else { - x = (vm.x + vm.base) / 2; - y = vm.y; - } - - return {x: x, y: y}; - }, - - getArea: function() { - var vm = this._view; - - return isVertical(vm) - ? vm.width * Math.abs(vm.y - vm.base) - : vm.height * Math.abs(vm.x - vm.base); - }, - - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - } -}); - -var elements = {}; -var Arc = element_arc; -var Line = element_line; -var Point = element_point; -var Rectangle = element_rectangle; -elements.Arc = Arc; -elements.Line = Line; -elements.Point = Point; -elements.Rectangle = Rectangle; - -var deprecated = helpers$1._deprecated; -var valueOrDefault$3 = helpers$1.valueOrDefault; - -core_defaults._set('bar', { - hover: { - mode: 'label' - }, - - scales: { - xAxes: [{ - type: 'category', - offset: true, - gridLines: { - offsetGridLines: true - } - }], - - yAxes: [{ - type: 'linear' - }] - } -}); - -core_defaults._set('global', { - datasets: { - bar: { - categoryPercentage: 0.8, - barPercentage: 0.9 - } - } -}); - -/** - * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. - * @private - */ -function computeMinSampleSize(scale, pixels) { - var min = scale._length; - var prev, curr, i, ilen; - - for (i = 1, ilen = pixels.length; i < ilen; ++i) { - min = Math.min(min, Math.abs(pixels[i] - pixels[i - 1])); - } - - for (i = 0, ilen = scale.getTicks().length; i < ilen; ++i) { - curr = scale.getPixelForTick(i); - min = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min; - prev = curr; - } - - return min; -} - -/** - * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null, - * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This - * mode currently always generates bars equally sized (until we introduce scriptable options?). - * @private - */ -function computeFitCategoryTraits(index, ruler, options) { - var thickness = options.barThickness; - var count = ruler.stackCount; - var curr = ruler.pixels[index]; - var min = helpers$1.isNullOrUndef(thickness) - ? computeMinSampleSize(ruler.scale, ruler.pixels) - : -1; - var size, ratio; - - if (helpers$1.isNullOrUndef(thickness)) { - size = min * options.categoryPercentage; - ratio = options.barPercentage; - } else { - // When bar thickness is enforced, category and bar percentages are ignored. - // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%') - // and deprecate barPercentage since this value is ignored when thickness is absolute. - size = thickness * count; - ratio = 1; - } - - return { - chunk: size / count, - ratio: ratio, - start: curr - (size / 2) - }; -} - -/** - * Computes an "optimal" category that globally arranges bars side by side (no gap when - * percentage options are 1), based on the previous and following categories. This mode - * generates bars with different widths when data are not evenly spaced. - * @private - */ -function computeFlexCategoryTraits(index, ruler, options) { - var pixels = ruler.pixels; - var curr = pixels[index]; - var prev = index > 0 ? pixels[index - 1] : null; - var next = index < pixels.length - 1 ? pixels[index + 1] : null; - var percent = options.categoryPercentage; - var start, size; - - if (prev === null) { - // first data: its size is double based on the next point or, - // if it's also the last data, we use the scale size. - prev = curr - (next === null ? ruler.end - ruler.start : next - curr); - } - - if (next === null) { - // last data: its size is also double based on the previous point. - next = curr + curr - prev; - } - - start = curr - (curr - Math.min(prev, next)) / 2 * percent; - size = Math.abs(next - prev) / 2 * percent; - - return { - chunk: size / ruler.stackCount, - ratio: options.barPercentage, - start: start - }; -} - -var controller_bar = core_datasetController.extend({ - - dataElementType: elements.Rectangle, - - /** - * @private - */ - _dataElementOptions: [ - 'backgroundColor', - 'borderColor', - 'borderSkipped', - 'borderWidth', - 'barPercentage', - 'barThickness', - 'categoryPercentage', - 'maxBarThickness', - 'minBarLength' - ], - - initialize: function() { - var me = this; - var meta, scaleOpts; - - core_datasetController.prototype.initialize.apply(me, arguments); - - meta = me.getMeta(); - meta.stack = me.getDataset().stack; - meta.bar = true; - - scaleOpts = me._getIndexScale().options; - deprecated('bar chart', scaleOpts.barPercentage, 'scales.[x/y]Axes.barPercentage', 'dataset.barPercentage'); - deprecated('bar chart', scaleOpts.barThickness, 'scales.[x/y]Axes.barThickness', 'dataset.barThickness'); - deprecated('bar chart', scaleOpts.categoryPercentage, 'scales.[x/y]Axes.categoryPercentage', 'dataset.categoryPercentage'); - deprecated('bar chart', me._getValueScale().options.minBarLength, 'scales.[x/y]Axes.minBarLength', 'dataset.minBarLength'); - deprecated('bar chart', scaleOpts.maxBarThickness, 'scales.[x/y]Axes.maxBarThickness', 'dataset.maxBarThickness'); - }, - - update: function(reset) { - var me = this; - var rects = me.getMeta().data; - var i, ilen; - - me._ruler = me.getRuler(); - - for (i = 0, ilen = rects.length; i < ilen; ++i) { - me.updateElement(rects[i], i, reset); - } - }, - - updateElement: function(rectangle, index, reset) { - var me = this; - var meta = me.getMeta(); - var dataset = me.getDataset(); - var options = me._resolveDataElementOptions(rectangle, index); - - rectangle._xScale = me.getScaleForId(meta.xAxisID); - rectangle._yScale = me.getScaleForId(meta.yAxisID); - rectangle._datasetIndex = me.index; - rectangle._index = index; - rectangle._model = { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderSkipped: options.borderSkipped, - borderWidth: options.borderWidth, - datasetLabel: dataset.label, - label: me.chart.data.labels[index] - }; - - if (helpers$1.isArray(dataset.data[index])) { - rectangle._model.borderSkipped = null; - } - - me._updateElementGeometry(rectangle, index, reset, options); - - rectangle.pivot(); - }, - - /** - * @private - */ - _updateElementGeometry: function(rectangle, index, reset, options) { - var me = this; - var model = rectangle._model; - var vscale = me._getValueScale(); - var base = vscale.getBasePixel(); - var horizontal = vscale.isHorizontal(); - var ruler = me._ruler || me.getRuler(); - var vpixels = me.calculateBarValuePixels(me.index, index, options); - var ipixels = me.calculateBarIndexPixels(me.index, index, ruler, options); - - model.horizontal = horizontal; - model.base = reset ? base : vpixels.base; - model.x = horizontal ? reset ? base : vpixels.head : ipixels.center; - model.y = horizontal ? ipixels.center : reset ? base : vpixels.head; - model.height = horizontal ? ipixels.size : undefined; - model.width = horizontal ? undefined : ipixels.size; - }, - - /** - * Returns the stacks based on groups and bar visibility. - * @param {number} [last] - The dataset index - * @returns {string[]} The list of stack IDs - * @private - */ - _getStacks: function(last) { - var me = this; - var scale = me._getIndexScale(); - var metasets = scale._getMatchingVisibleMetas(me._type); - var stacked = scale.options.stacked; - var ilen = metasets.length; - var stacks = []; - var i, meta; - - for (i = 0; i < ilen; ++i) { - meta = metasets[i]; - // stacked | meta.stack - // | found | not found | undefined - // false | x | x | x - // true | | x | - // undefined | | x | x - if (stacked === false || stacks.indexOf(meta.stack) === -1 || - (stacked === undefined && meta.stack === undefined)) { - stacks.push(meta.stack); - } - if (meta.index === last) { - break; - } - } - - return stacks; - }, - - /** - * Returns the effective number of stacks based on groups and bar visibility. - * @private - */ - getStackCount: function() { - return this._getStacks().length; - }, - - /** - * Returns the stack index for the given dataset based on groups and bar visibility. - * @param {number} [datasetIndex] - The dataset index - * @param {string} [name] - The stack name to find - * @returns {number} The stack index - * @private - */ - getStackIndex: function(datasetIndex, name) { - var stacks = this._getStacks(datasetIndex); - var index = (name !== undefined) - ? stacks.indexOf(name) - : -1; // indexOf returns -1 if element is not present - - return (index === -1) - ? stacks.length - 1 - : index; - }, - - /** - * @private - */ - getRuler: function() { - var me = this; - var scale = me._getIndexScale(); - var pixels = []; - var i, ilen; - - for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) { - pixels.push(scale.getPixelForValue(null, i, me.index)); - } - - return { - pixels: pixels, - start: scale._startPixel, - end: scale._endPixel, - stackCount: me.getStackCount(), - scale: scale - }; - }, - - /** - * Note: pixel values are not clamped to the scale area. - * @private - */ - calculateBarValuePixels: function(datasetIndex, index, options) { - var me = this; - var chart = me.chart; - var scale = me._getValueScale(); - var isHorizontal = scale.isHorizontal(); - var datasets = chart.data.datasets; - var metasets = scale._getMatchingVisibleMetas(me._type); - var value = scale._parseValue(datasets[datasetIndex].data[index]); - var minBarLength = options.minBarLength; - var stacked = scale.options.stacked; - var stack = me.getMeta().stack; - var start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max; - var length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max; - var ilen = metasets.length; - var i, imeta, ivalue, base, head, size, stackLength; - - if (stacked || (stacked === undefined && stack !== undefined)) { - for (i = 0; i < ilen; ++i) { - imeta = metasets[i]; - - if (imeta.index === datasetIndex) { - break; - } - - if (imeta.stack === stack) { - stackLength = scale._parseValue(datasets[imeta.index].data[index]); - ivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min; - - if ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) { - start += ivalue; - } - } - } - } - - base = scale.getPixelForValue(start); - head = scale.getPixelForValue(start + length); - size = head - base; - - if (minBarLength !== undefined && Math.abs(size) < minBarLength) { - size = minBarLength; - if (length >= 0 && !isHorizontal || length < 0 && isHorizontal) { - head = base - minBarLength; - } else { - head = base + minBarLength; - } - } - - return { - size: size, - base: base, - head: head, - center: head + size / 2 - }; - }, - - /** - * @private - */ - calculateBarIndexPixels: function(datasetIndex, index, ruler, options) { - var me = this; - var range = options.barThickness === 'flex' - ? computeFlexCategoryTraits(index, ruler, options) - : computeFitCategoryTraits(index, ruler, options); - - var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack); - var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); - var size = Math.min( - valueOrDefault$3(options.maxBarThickness, Infinity), - range.chunk * range.ratio); - - return { - base: center - size / 2, - head: center + size / 2, - center: center, - size: size - }; - }, - - draw: function() { - var me = this; - var chart = me.chart; - var scale = me._getValueScale(); - var rects = me.getMeta().data; - var dataset = me.getDataset(); - var ilen = rects.length; - var i = 0; - - helpers$1.canvas.clipArea(chart.ctx, chart.chartArea); - - for (; i < ilen; ++i) { - var val = scale._parseValue(dataset.data[i]); - if (!isNaN(val.min) && !isNaN(val.max)) { - rects[i].draw(); - } - } - - helpers$1.canvas.unclipArea(chart.ctx); - }, - - /** - * @private - */ - _resolveDataElementOptions: function() { - var me = this; - var values = helpers$1.extend({}, core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments)); - var indexOpts = me._getIndexScale().options; - var valueOpts = me._getValueScale().options; - - values.barPercentage = valueOrDefault$3(indexOpts.barPercentage, values.barPercentage); - values.barThickness = valueOrDefault$3(indexOpts.barThickness, values.barThickness); - values.categoryPercentage = valueOrDefault$3(indexOpts.categoryPercentage, values.categoryPercentage); - values.maxBarThickness = valueOrDefault$3(indexOpts.maxBarThickness, values.maxBarThickness); - values.minBarLength = valueOrDefault$3(valueOpts.minBarLength, values.minBarLength); - - return values; - } - -}); - -var valueOrDefault$4 = helpers$1.valueOrDefault; -var resolve$1 = helpers$1.options.resolve; - -core_defaults._set('bubble', { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - type: 'linear', // bubble should probably use a linear scale by default - position: 'bottom', - id: 'x-axis-0' // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: 'linear', - position: 'left', - id: 'y-axis-0' - }] - }, - - tooltips: { - callbacks: { - title: function() { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(item, data) { - var datasetLabel = data.datasets[item.datasetIndex].label || ''; - var dataPoint = data.datasets[item.datasetIndex].data[item.index]; - return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')'; - } - } - } -}); - -var controller_bubble = core_datasetController.extend({ - /** - * @protected - */ - dataElementType: elements.Point, - - /** - * @private - */ - _dataElementOptions: [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - 'hoverRadius', - 'hitRadius', - 'pointStyle', - 'rotation' - ], - - /** - * @protected - */ - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var points = meta.data; - - // Update Points - helpers$1.each(points, function(point, index) { - me.updateElement(point, index, reset); - }); - }, - - /** - * @protected - */ - updateElement: function(point, index, reset) { - var me = this; - var meta = me.getMeta(); - var custom = point.custom || {}; - var xScale = me.getScaleForId(meta.xAxisID); - var yScale = me.getScaleForId(meta.yAxisID); - var options = me._resolveDataElementOptions(point, index); - var data = me.getDataset().data[index]; - var dsIndex = me.index; - - var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex); - var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex); - - point._xScale = xScale; - point._yScale = yScale; - point._options = options; - point._datasetIndex = dsIndex; - point._index = index; - point._model = { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - hitRadius: options.hitRadius, - pointStyle: options.pointStyle, - rotation: options.rotation, - radius: reset ? 0 : options.radius, - skip: custom.skip || isNaN(x) || isNaN(y), - x: x, - y: y, - }; - - point.pivot(); - }, - - /** - * @protected - */ - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - var getHoverColor = helpers$1.getHoverColor; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth); - model.radius = options.radius + options.hoverRadius; - }, - - /** - * @private - */ - _resolveDataElementOptions: function(point, index) { - var me = this; - var chart = me.chart; - var dataset = me.getDataset(); - var custom = point.custom || {}; - var data = dataset.data[index] || {}; - var values = core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments); - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - // In case values were cached (and thus frozen), we need to clone the values - if (me._cachedDataOpts === values) { - values = helpers$1.extend({}, values); - } - - // Custom radius resolution - values.radius = resolve$1([ - custom.radius, - data.r, - me._config.radius, - chart.options.elements.point.radius - ], context, index); - - return values; - } -}); - -var valueOrDefault$5 = helpers$1.valueOrDefault; - -var PI$1 = Math.PI; -var DOUBLE_PI$1 = PI$1 * 2; -var HALF_PI$1 = PI$1 / 2; - -core_defaults._set('doughnut', { - animation: { - // Boolean - Whether we animate the rotation of the Doughnut - animateRotate: true, - // Boolean - Whether we animate scaling the Doughnut from the centre - animateScale: false - }, - hover: { - mode: 'single' - }, - legendCallback: function(chart) { - var list = document.createElement('ul'); - var data = chart.data; - var datasets = data.datasets; - var labels = data.labels; - var i, ilen, listItem, listItemSpan; - - list.setAttribute('class', chart.id + '-legend'); - if (datasets.length) { - for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) { - listItem = list.appendChild(document.createElement('li')); - listItemSpan = listItem.appendChild(document.createElement('span')); - listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i]; - if (labels[i]) { - listItem.appendChild(document.createTextNode(labels[i])); - } - } - } - - return list.outerHTML; - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var style = meta.controller.getStyle(i); - - return { - text: label, - fillStyle: style.backgroundColor, - strokeStyle: style.borderColor, - lineWidth: style.borderWidth, - hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }); - } - return []; - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - // toggle visibility of index if exists - if (meta.data[index]) { - meta.data[index].hidden = !meta.data[index].hidden; - } - } - - chart.update(); - } - }, - - // The percentage of the chart that we cut out of the middle. - cutoutPercentage: 50, - - // The rotation of the chart, where the first data arc begins. - rotation: -HALF_PI$1, - - // The total circumference of the chart. - circumference: DOUBLE_PI$1, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - var dataLabel = data.labels[tooltipItem.index]; - var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - - if (helpers$1.isArray(dataLabel)) { - // show value on first line of multiline label - // need to clone because we are changing the value - dataLabel = dataLabel.slice(); - dataLabel[0] += value; - } else { - dataLabel += value; - } - - return dataLabel; - } - } - } -}); - -var controller_doughnut = core_datasetController.extend({ - - dataElementType: elements.Arc, - - linkScales: helpers$1.noop, - - /** - * @private - */ - _dataElementOptions: [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'borderAlign', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - ], - - // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly - getRingIndex: function(datasetIndex) { - var ringIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (this.chart.isDatasetVisible(j)) { - ++ringIndex; - } - } - - return ringIndex; - }, - - update: function(reset) { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var ratioX = 1; - var ratioY = 1; - var offsetX = 0; - var offsetY = 0; - var meta = me.getMeta(); - var arcs = meta.data; - var cutout = opts.cutoutPercentage / 100 || 0; - var circumference = opts.circumference; - var chartWeight = me._getRingWeight(me.index); - var maxWidth, maxHeight, i, ilen; - - // If the chart's circumference isn't a full circle, calculate size as a ratio of the width/height of the arc - if (circumference < DOUBLE_PI$1) { - var startAngle = opts.rotation % DOUBLE_PI$1; - startAngle += startAngle >= PI$1 ? -DOUBLE_PI$1 : startAngle < -PI$1 ? DOUBLE_PI$1 : 0; - var endAngle = startAngle + circumference; - var startX = Math.cos(startAngle); - var startY = Math.sin(startAngle); - var endX = Math.cos(endAngle); - var endY = Math.sin(endAngle); - var contains0 = (startAngle <= 0 && endAngle >= 0) || endAngle >= DOUBLE_PI$1; - var contains90 = (startAngle <= HALF_PI$1 && endAngle >= HALF_PI$1) || endAngle >= DOUBLE_PI$1 + HALF_PI$1; - var contains180 = startAngle === -PI$1 || endAngle >= PI$1; - var contains270 = (startAngle <= -HALF_PI$1 && endAngle >= -HALF_PI$1) || endAngle >= PI$1 + HALF_PI$1; - var minX = contains180 ? -1 : Math.min(startX, startX * cutout, endX, endX * cutout); - var minY = contains270 ? -1 : Math.min(startY, startY * cutout, endY, endY * cutout); - var maxX = contains0 ? 1 : Math.max(startX, startX * cutout, endX, endX * cutout); - var maxY = contains90 ? 1 : Math.max(startY, startY * cutout, endY, endY * cutout); - ratioX = (maxX - minX) / 2; - ratioY = (maxY - minY) / 2; - offsetX = -(maxX + minX) / 2; - offsetY = -(maxY + minY) / 2; - } - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - arcs[i]._options = me._resolveDataElementOptions(arcs[i], i); - } - - chart.borderWidth = me.getMaxBorderWidth(); - maxWidth = (chartArea.right - chartArea.left - chart.borderWidth) / ratioX; - maxHeight = (chartArea.bottom - chartArea.top - chart.borderWidth) / ratioY; - chart.outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); - chart.innerRadius = Math.max(chart.outerRadius * cutout, 0); - chart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1); - chart.offsetX = offsetX * chart.outerRadius; - chart.offsetY = offsetY * chart.outerRadius; - - meta.total = me.calculateTotal(); - - me.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index); - me.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0); - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - me.updateElement(arcs[i], i, reset); - } - }, - - updateElement: function(arc, index, reset) { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var animationOpts = opts.animation; - var centerX = (chartArea.left + chartArea.right) / 2; - var centerY = (chartArea.top + chartArea.bottom) / 2; - var startAngle = opts.rotation; // non reset case handled later - var endAngle = opts.rotation; // non reset case handled later - var dataset = me.getDataset(); - var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI$1); - var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius; - var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius; - var options = arc._options || {}; - - helpers$1.extend(arc, { - // Utility - _datasetIndex: me.index, - _index: index, - - // Desired view properties - _model: { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - borderAlign: options.borderAlign, - x: centerX + chart.offsetX, - y: centerY + chart.offsetY, - startAngle: startAngle, - endAngle: endAngle, - circumference: circumference, - outerRadius: outerRadius, - innerRadius: innerRadius, - label: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) - } - }); - - var model = arc._model; - - // Set correct angles if not resetting - if (!reset || !animationOpts.animateRotate) { - if (index === 0) { - model.startAngle = opts.rotation; - } else { - model.startAngle = me.getMeta().data[index - 1]._model.endAngle; - } - - model.endAngle = model.startAngle + model.circumference; - } - - arc.pivot(); - }, - - calculateTotal: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var total = 0; - var value; - - helpers$1.each(meta.data, function(element, index) { - value = dataset.data[index]; - if (!isNaN(value) && !element.hidden) { - total += Math.abs(value); - } - }); - - /* if (total === 0) { - total = NaN; - }*/ - - return total; - }, - - calculateCircumference: function(value) { - var total = this.getMeta().total; - if (total > 0 && !isNaN(value)) { - return DOUBLE_PI$1 * (Math.abs(value) / total); - } - return 0; - }, - - // gets the max border or hover width to properly scale pie charts - getMaxBorderWidth: function(arcs) { - var me = this; - var max = 0; - var chart = me.chart; - var i, ilen, meta, arc, controller, options, borderWidth, hoverWidth; - - if (!arcs) { - // Find the outmost visible dataset - for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) { - if (chart.isDatasetVisible(i)) { - meta = chart.getDatasetMeta(i); - arcs = meta.data; - if (i !== me.index) { - controller = meta.controller; - } - break; - } - } - } - - if (!arcs) { - return 0; - } - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - arc = arcs[i]; - if (controller) { - controller._configure(); - options = controller._resolveDataElementOptions(arc, i); - } else { - options = arc._options; - } - if (options.borderAlign !== 'inner') { - borderWidth = options.borderWidth; - hoverWidth = options.hoverBorderWidth; - - max = borderWidth > max ? borderWidth : max; - max = hoverWidth > max ? hoverWidth : max; - } - } - return max; - }, - - /** - * @protected - */ - setHoverStyle: function(arc) { - var model = arc._model; - var options = arc._options; - var getHoverColor = helpers$1.getHoverColor; - - arc.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - }; - - model.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth); - }, - - /** - * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly - * @private - */ - _getRingWeightOffset: function(datasetIndex) { - var ringWeightOffset = 0; - - for (var i = 0; i < datasetIndex; ++i) { - if (this.chart.isDatasetVisible(i)) { - ringWeightOffset += this._getRingWeight(i); - } - } - - return ringWeightOffset; - }, - - /** - * @private - */ - _getRingWeight: function(dataSetIndex) { - return Math.max(valueOrDefault$5(this.chart.data.datasets[dataSetIndex].weight, 1), 0); - }, - - /** - * Returns the sum of all visibile data set weights. This value can be 0. - * @private - */ - _getVisibleDatasetWeightTotal: function() { - return this._getRingWeightOffset(this.chart.data.datasets.length); - } -}); - -core_defaults._set('horizontalBar', { - hover: { - mode: 'index', - axis: 'y' - }, - - scales: { - xAxes: [{ - type: 'linear', - position: 'bottom' - }], - - yAxes: [{ - type: 'category', - position: 'left', - offset: true, - gridLines: { - offsetGridLines: true - } - }] - }, - - elements: { - rectangle: { - borderSkipped: 'left' - } - }, - - tooltips: { - mode: 'index', - axis: 'y' - } -}); - -core_defaults._set('global', { - datasets: { - horizontalBar: { - categoryPercentage: 0.8, - barPercentage: 0.9 - } - } -}); - -var controller_horizontalBar = controller_bar.extend({ - /** - * @private - */ - _getValueScaleId: function() { - return this.getMeta().xAxisID; - }, - - /** - * @private - */ - _getIndexScaleId: function() { - return this.getMeta().yAxisID; - } -}); - -var valueOrDefault$6 = helpers$1.valueOrDefault; -var resolve$2 = helpers$1.options.resolve; -var isPointInArea = helpers$1.canvas._isPointInArea; - -core_defaults._set('line', { - showLines: true, - spanGaps: false, - - hover: { - mode: 'label' - }, - - scales: { - xAxes: [{ - type: 'category', - id: 'x-axis-0' - }], - yAxes: [{ - type: 'linear', - id: 'y-axis-0' - }] - } -}); - -function scaleClip(scale, halfBorderWidth) { - var tickOpts = scale && scale.options.ticks || {}; - var reverse = tickOpts.reverse; - var min = tickOpts.min === undefined ? halfBorderWidth : 0; - var max = tickOpts.max === undefined ? halfBorderWidth : 0; - return { - start: reverse ? max : min, - end: reverse ? min : max - }; -} - -function defaultClip(xScale, yScale, borderWidth) { - var halfBorderWidth = borderWidth / 2; - var x = scaleClip(xScale, halfBorderWidth); - var y = scaleClip(yScale, halfBorderWidth); - - return { - top: y.end, - right: x.end, - bottom: y.start, - left: x.start - }; -} - -function toClip(value) { - var t, r, b, l; - - if (helpers$1.isObject(value)) { - t = value.top; - r = value.right; - b = value.bottom; - l = value.left; - } else { - t = r = b = l = value; - } - - return { - top: t, - right: r, - bottom: b, - left: l - }; -} - - -var controller_line = core_datasetController.extend({ - - datasetElementType: elements.Line, - - dataElementType: elements.Point, - - /** - * @private - */ - _datasetElementOptions: [ - 'backgroundColor', - 'borderCapStyle', - 'borderColor', - 'borderDash', - 'borderDashOffset', - 'borderJoinStyle', - 'borderWidth', - 'cubicInterpolationMode', - 'fill' - ], - - /** - * @private - */ - _dataElementOptions: { - backgroundColor: 'pointBackgroundColor', - borderColor: 'pointBorderColor', - borderWidth: 'pointBorderWidth', - hitRadius: 'pointHitRadius', - hoverBackgroundColor: 'pointHoverBackgroundColor', - hoverBorderColor: 'pointHoverBorderColor', - hoverBorderWidth: 'pointHoverBorderWidth', - hoverRadius: 'pointHoverRadius', - pointStyle: 'pointStyle', - radius: 'pointRadius', - rotation: 'pointRotation' - }, - - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var line = meta.dataset; - var points = meta.data || []; - var options = me.chart.options; - var config = me._config; - var showLine = me._showLine = valueOrDefault$6(config.showLine, options.showLines); - var i, ilen; - - me._xScale = me.getScaleForId(meta.xAxisID); - me._yScale = me.getScaleForId(meta.yAxisID); - - // Update Line - if (showLine) { - // Compatibility: If the properties are defined with only the old name, use those values - if (config.tension !== undefined && config.lineTension === undefined) { - config.lineTension = config.tension; - } - - // Utility - line._scale = me._yScale; - line._datasetIndex = me.index; - // Data - line._children = points; - // Model - line._model = me._resolveDatasetElementOptions(line); - - line.pivot(); - } - - // Update Points - for (i = 0, ilen = points.length; i < ilen; ++i) { - me.updateElement(points[i], i, reset); - } - - if (showLine && line._model.tension !== 0) { - me.updateBezierControlPoints(); - } - - // Now pivot the point for animation - for (i = 0, ilen = points.length; i < ilen; ++i) { - points[i].pivot(); - } - }, - - updateElement: function(point, index, reset) { - var me = this; - var meta = me.getMeta(); - var custom = point.custom || {}; - var dataset = me.getDataset(); - var datasetIndex = me.index; - var value = dataset.data[index]; - var xScale = me._xScale; - var yScale = me._yScale; - var lineModel = meta.dataset._model; - var x, y; - - var options = me._resolveDataElementOptions(point, index); - - x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); - y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); - - // Utility - point._xScale = xScale; - point._yScale = yScale; - point._options = options; - point._datasetIndex = datasetIndex; - point._index = index; - - // Desired view properties - point._model = { - x: x, - y: y, - skip: custom.skip || isNaN(x) || isNaN(y), - // Appearance - radius: options.radius, - pointStyle: options.pointStyle, - rotation: options.rotation, - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - tension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0), - steppedLine: lineModel ? lineModel.steppedLine : false, - // Tooltip - hitRadius: options.hitRadius - }; - }, - - /** - * @private - */ - _resolveDatasetElementOptions: function(element) { - var me = this; - var config = me._config; - var custom = element.custom || {}; - var options = me.chart.options; - var lineOptions = options.elements.line; - var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); - - // The default behavior of lines is to break at null values, according - // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 - // This option gives lines the ability to span gaps - values.spanGaps = valueOrDefault$6(config.spanGaps, options.spanGaps); - values.tension = valueOrDefault$6(config.lineTension, lineOptions.tension); - values.steppedLine = resolve$2([custom.steppedLine, config.steppedLine, lineOptions.stepped]); - values.clip = toClip(valueOrDefault$6(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth))); - - return values; - }, - - calculatePointY: function(value, index, datasetIndex) { - var me = this; - var chart = me.chart; - var yScale = me._yScale; - var sumPos = 0; - var sumNeg = 0; - var i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen; - - if (yScale.options.stacked) { - rightValue = +yScale.getRightValue(value); - metasets = chart._getSortedVisibleDatasetMetas(); - ilen = metasets.length; - - for (i = 0; i < ilen; ++i) { - dsMeta = metasets[i]; - if (dsMeta.index === datasetIndex) { - break; - } - - ds = chart.data.datasets[dsMeta.index]; - if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) { - stackedRightValue = +yScale.getRightValue(ds.data[index]); - if (stackedRightValue < 0) { - sumNeg += stackedRightValue || 0; - } else { - sumPos += stackedRightValue || 0; - } - } - } - - if (rightValue < 0) { - return yScale.getPixelForValue(sumNeg + rightValue); - } - return yScale.getPixelForValue(sumPos + rightValue); - } - return yScale.getPixelForValue(value); - }, - - updateBezierControlPoints: function() { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var lineModel = meta.dataset._model; - var area = chart.chartArea; - var points = meta.data || []; - var i, ilen, model, controlPoints; - - // Only consider points that are drawn in case the spanGaps option is used - if (lineModel.spanGaps) { - points = points.filter(function(pt) { - return !pt._model.skip; - }); - } - - function capControlPoint(pt, min, max) { - return Math.max(Math.min(pt, max), min); - } - - if (lineModel.cubicInterpolationMode === 'monotone') { - helpers$1.splineCurveMonotone(points); - } else { - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - controlPoints = helpers$1.splineCurve( - helpers$1.previousItem(points, i)._model, - model, - helpers$1.nextItem(points, i)._model, - lineModel.tension - ); - model.controlPointPreviousX = controlPoints.previous.x; - model.controlPointPreviousY = controlPoints.previous.y; - model.controlPointNextX = controlPoints.next.x; - model.controlPointNextY = controlPoints.next.y; - } - } - - if (chart.options.elements.line.capBezierPoints) { - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - if (isPointInArea(model, area)) { - if (i > 0 && isPointInArea(points[i - 1]._model, area)) { - model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right); - model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom); - } - if (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) { - model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right); - model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom); - } - } - } - } - }, - - draw: function() { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var points = meta.data || []; - var area = chart.chartArea; - var canvas = chart.canvas; - var i = 0; - var ilen = points.length; - var clip; - - if (me._showLine) { - clip = meta.dataset._model.clip; - - helpers$1.canvas.clipArea(chart.ctx, { - left: clip.left === false ? 0 : area.left - clip.left, - right: clip.right === false ? canvas.width : area.right + clip.right, - top: clip.top === false ? 0 : area.top - clip.top, - bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom - }); - - meta.dataset.draw(); - - helpers$1.canvas.unclipArea(chart.ctx); - } - - // Draw the points - for (; i < ilen; ++i) { - points[i].draw(area); - } - }, - - /** - * @protected - */ - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - var getHoverColor = helpers$1.getHoverColor; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth); - model.radius = valueOrDefault$6(options.hoverRadius, options.radius); - }, -}); - -var resolve$3 = helpers$1.options.resolve; - -core_defaults._set('polarArea', { - scale: { - type: 'radialLinear', - angleLines: { - display: false - }, - gridLines: { - circular: true - }, - pointLabels: { - display: false - }, - ticks: { - beginAtZero: true - } - }, - - // Boolean - Whether to animate the rotation of the chart - animation: { - animateRotate: true, - animateScale: true - }, - - startAngle: -0.5 * Math.PI, - legendCallback: function(chart) { - var list = document.createElement('ul'); - var data = chart.data; - var datasets = data.datasets; - var labels = data.labels; - var i, ilen, listItem, listItemSpan; - - list.setAttribute('class', chart.id + '-legend'); - if (datasets.length) { - for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) { - listItem = list.appendChild(document.createElement('li')); - listItemSpan = listItem.appendChild(document.createElement('span')); - listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i]; - if (labels[i]) { - listItem.appendChild(document.createTextNode(labels[i])); - } - } - } - - return list.outerHTML; - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var style = meta.controller.getStyle(i); - - return { - text: label, - fillStyle: style.backgroundColor, - strokeStyle: style.borderColor, - lineWidth: style.borderWidth, - hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }); - } - return []; - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(item, data) { - return data.labels[item.index] + ': ' + item.yLabel; - } - } - } -}); - -var controller_polarArea = core_datasetController.extend({ - - dataElementType: elements.Arc, - - linkScales: helpers$1.noop, - - /** - * @private - */ - _dataElementOptions: [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'borderAlign', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - ], - - /** - * @private - */ - _getIndexScaleId: function() { - return this.chart.scale.id; - }, - - /** - * @private - */ - _getValueScaleId: function() { - return this.chart.scale.id; - }, - - update: function(reset) { - var me = this; - var dataset = me.getDataset(); - var meta = me.getMeta(); - var start = me.chart.options.startAngle || 0; - var starts = me._starts = []; - var angles = me._angles = []; - var arcs = meta.data; - var i, ilen, angle; - - me._updateRadius(); - - meta.count = me.countVisibleElements(); - - for (i = 0, ilen = dataset.data.length; i < ilen; i++) { - starts[i] = start; - angle = me._computeAngle(i); - angles[i] = angle; - start += angle; - } - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - arcs[i]._options = me._resolveDataElementOptions(arcs[i], i); - me.updateElement(arcs[i], i, reset); - } - }, - - /** - * @private - */ - _updateRadius: function() { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); - - chart.outerRadius = Math.max(minSize / 2, 0); - chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); - chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); - - me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index); - me.innerRadius = me.outerRadius - chart.radiusLength; - }, - - updateElement: function(arc, index, reset) { - var me = this; - var chart = me.chart; - var dataset = me.getDataset(); - var opts = chart.options; - var animationOpts = opts.animation; - var scale = chart.scale; - var labels = chart.data.labels; - - var centerX = scale.xCenter; - var centerY = scale.yCenter; - - // var negHalfPI = -0.5 * Math.PI; - var datasetStartAngle = opts.startAngle; - var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); - var startAngle = me._starts[index]; - var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]); - - var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); - var options = arc._options || {}; - - helpers$1.extend(arc, { - // Utility - _datasetIndex: me.index, - _index: index, - _scale: scale, - - // Desired view properties - _model: { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - borderAlign: options.borderAlign, - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: reset ? resetRadius : distance, - startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle, - endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle, - label: helpers$1.valueAtIndexOrDefault(labels, index, labels[index]) - } - }); - - arc.pivot(); - }, - - countVisibleElements: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var count = 0; - - helpers$1.each(meta.data, function(element, index) { - if (!isNaN(dataset.data[index]) && !element.hidden) { - count++; - } - }); - - return count; - }, - - /** - * @protected - */ - setHoverStyle: function(arc) { - var model = arc._model; - var options = arc._options; - var getHoverColor = helpers$1.getHoverColor; - var valueOrDefault = helpers$1.valueOrDefault; - - arc.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - }; - - model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth); - }, - - /** - * @private - */ - _computeAngle: function(index) { - var me = this; - var count = this.getMeta().count; - var dataset = me.getDataset(); - var meta = me.getMeta(); - - if (isNaN(dataset.data[index]) || meta.data[index].hidden) { - return 0; - } - - // Scriptable options - var context = { - chart: me.chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - return resolve$3([ - me.chart.options.elements.arc.angle, - (2 * Math.PI) / count - ], context, index); - } -}); - -core_defaults._set('pie', helpers$1.clone(core_defaults.doughnut)); -core_defaults._set('pie', { - cutoutPercentage: 0 -}); - -// Pie charts are Doughnut chart with different defaults -var controller_pie = controller_doughnut; - -var valueOrDefault$7 = helpers$1.valueOrDefault; - -core_defaults._set('radar', { - spanGaps: false, - scale: { - type: 'radialLinear' - }, - elements: { - line: { - fill: 'start', - tension: 0 // no bezier in radar - } - } -}); - -var controller_radar = core_datasetController.extend({ - datasetElementType: elements.Line, - - dataElementType: elements.Point, - - linkScales: helpers$1.noop, - - /** - * @private - */ - _datasetElementOptions: [ - 'backgroundColor', - 'borderWidth', - 'borderColor', - 'borderCapStyle', - 'borderDash', - 'borderDashOffset', - 'borderJoinStyle', - 'fill' - ], - - /** - * @private - */ - _dataElementOptions: { - backgroundColor: 'pointBackgroundColor', - borderColor: 'pointBorderColor', - borderWidth: 'pointBorderWidth', - hitRadius: 'pointHitRadius', - hoverBackgroundColor: 'pointHoverBackgroundColor', - hoverBorderColor: 'pointHoverBorderColor', - hoverBorderWidth: 'pointHoverBorderWidth', - hoverRadius: 'pointHoverRadius', - pointStyle: 'pointStyle', - radius: 'pointRadius', - rotation: 'pointRotation' - }, - - /** - * @private - */ - _getIndexScaleId: function() { - return this.chart.scale.id; - }, - - /** - * @private - */ - _getValueScaleId: function() { - return this.chart.scale.id; - }, - - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var line = meta.dataset; - var points = meta.data || []; - var scale = me.chart.scale; - var config = me._config; - var i, ilen; - - // Compatibility: If the properties are defined with only the old name, use those values - if (config.tension !== undefined && config.lineTension === undefined) { - config.lineTension = config.tension; - } - - // Utility - line._scale = scale; - line._datasetIndex = me.index; - // Data - line._children = points; - line._loop = true; - // Model - line._model = me._resolveDatasetElementOptions(line); - - line.pivot(); - - // Update Points - for (i = 0, ilen = points.length; i < ilen; ++i) { - me.updateElement(points[i], i, reset); - } - - // Update bezier control points - me.updateBezierControlPoints(); - - // Now pivot the point for animation - for (i = 0, ilen = points.length; i < ilen; ++i) { - points[i].pivot(); - } - }, - - updateElement: function(point, index, reset) { - var me = this; - var custom = point.custom || {}; - var dataset = me.getDataset(); - var scale = me.chart.scale; - var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); - var options = me._resolveDataElementOptions(point, index); - var lineModel = me.getMeta().dataset._model; - var x = reset ? scale.xCenter : pointPosition.x; - var y = reset ? scale.yCenter : pointPosition.y; - - // Utility - point._scale = scale; - point._options = options; - point._datasetIndex = me.index; - point._index = index; - - // Desired view properties - point._model = { - x: x, // value not used in dataset scale, but we want a consistent API between scales - y: y, - skip: custom.skip || isNaN(x) || isNaN(y), - // Appearance - radius: options.radius, - pointStyle: options.pointStyle, - rotation: options.rotation, - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - tension: valueOrDefault$7(custom.tension, lineModel ? lineModel.tension : 0), - - // Tooltip - hitRadius: options.hitRadius - }; - }, - - /** - * @private - */ - _resolveDatasetElementOptions: function() { - var me = this; - var config = me._config; - var options = me.chart.options; - var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); - - values.spanGaps = valueOrDefault$7(config.spanGaps, options.spanGaps); - values.tension = valueOrDefault$7(config.lineTension, options.elements.line.tension); - - return values; - }, - - updateBezierControlPoints: function() { - var me = this; - var meta = me.getMeta(); - var area = me.chart.chartArea; - var points = meta.data || []; - var i, ilen, model, controlPoints; - - // Only consider points that are drawn in case the spanGaps option is used - if (meta.dataset._model.spanGaps) { - points = points.filter(function(pt) { - return !pt._model.skip; - }); - } - - function capControlPoint(pt, min, max) { - return Math.max(Math.min(pt, max), min); - } - - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - controlPoints = helpers$1.splineCurve( - helpers$1.previousItem(points, i, true)._model, - model, - helpers$1.nextItem(points, i, true)._model, - model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - model.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right); - model.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom); - model.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right); - model.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom); - } - }, - - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - var getHoverColor = helpers$1.getHoverColor; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = valueOrDefault$7(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$7(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$7(options.hoverBorderWidth, options.borderWidth); - model.radius = valueOrDefault$7(options.hoverRadius, options.radius); - } -}); - -core_defaults._set('scatter', { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - id: 'x-axis-1', // need an ID so datasets can reference the scale - type: 'linear', // scatter should not use a category axis - position: 'bottom' - }], - yAxes: [{ - id: 'y-axis-1', - type: 'linear', - position: 'left' - }] - }, - - tooltips: { - callbacks: { - title: function() { - return ''; // doesn't make sense for scatter since data are formatted as a point - }, - label: function(item) { - return '(' + item.xLabel + ', ' + item.yLabel + ')'; - } - } - } -}); - -core_defaults._set('global', { - datasets: { - scatter: { - showLine: false - } - } -}); - -// Scatter charts use line controllers -var controller_scatter = controller_line; - -// NOTE export a map in which the key represents the controller type, not -// the class, and so must be CamelCase in order to be correctly retrieved -// by the controller in core.controller.js (`controllers[meta.type]`). - -var controllers = { - bar: controller_bar, - bubble: controller_bubble, - doughnut: controller_doughnut, - horizontalBar: controller_horizontalBar, - line: controller_line, - polarArea: controller_polarArea, - pie: controller_pie, - radar: controller_radar, - scatter: controller_scatter -}; - -/** - * Helper function to get relative position for an event - * @param {Event|IEvent} event - The event to get the position for - * @param {Chart} chart - The chart - * @returns {object} the event position - */ -function getRelativePosition(e, chart) { - if (e.native) { - return { - x: e.x, - y: e.y - }; - } - - return helpers$1.getRelativePosition(e, chart); -} - -/** - * Helper function to traverse all of the visible elements in the chart - * @param {Chart} chart - the chart - * @param {function} handler - the callback to execute for each visible item - */ -function parseVisibleItems(chart, handler) { - var metasets = chart._getSortedVisibleDatasetMetas(); - var metadata, i, j, ilen, jlen, element; - - for (i = 0, ilen = metasets.length; i < ilen; ++i) { - metadata = metasets[i].data; - for (j = 0, jlen = metadata.length; j < jlen; ++j) { - element = metadata[j]; - if (!element._view.skip) { - handler(element); - } - } - } -} - -/** - * Helper function to get the items that intersect the event position - * @param {ChartElement[]} items - elements to filter - * @param {object} position - the point to be nearest to - * @return {ChartElement[]} the nearest items - */ -function getIntersectItems(chart, position) { - var elements = []; - - parseVisibleItems(chart, function(element) { - if (element.inRange(position.x, position.y)) { - elements.push(element); - } - }); - - return elements; -} - -/** - * Helper function to get the items nearest to the event position considering all visible items in teh chart - * @param {Chart} chart - the chart to look at elements from - * @param {object} position - the point to be nearest to - * @param {boolean} intersect - if true, only consider items that intersect the position - * @param {function} distanceMetric - function to provide the distance between points - * @return {ChartElement[]} the nearest items - */ -function getNearestItems(chart, position, intersect, distanceMetric) { - var minDistance = Number.POSITIVE_INFINITY; - var nearestItems = []; - - parseVisibleItems(chart, function(element) { - if (intersect && !element.inRange(position.x, position.y)) { - return; - } - - var center = element.getCenterPoint(); - var distance = distanceMetric(position, center); - if (distance < minDistance) { - nearestItems = [element]; - minDistance = distance; - } else if (distance === minDistance) { - // Can have multiple items at the same distance in which case we sort by size - nearestItems.push(element); - } - }); - - return nearestItems; -} - -/** - * Get a distance metric function for two points based on the - * axis mode setting - * @param {string} axis - the axis mode. x|y|xy - */ -function getDistanceMetricForAxis(axis) { - var useX = axis.indexOf('x') !== -1; - var useY = axis.indexOf('y') !== -1; - - return function(pt1, pt2) { - var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; - var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; - return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); - }; -} - -function indexMode(chart, e, options) { - var position = getRelativePosition(e, chart); - // Default axis for index mode is 'x' to match old behaviour - options.axis = options.axis || 'x'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - var elements = []; - - if (!items.length) { - return []; - } - - chart._getSortedVisibleDatasetMetas().forEach(function(meta) { - var element = meta.data[items[0]._index]; - - // don't count items that are skipped (null data) - if (element && !element._view.skip) { - elements.push(element); - } - }); - - return elements; -} - -/** - * @interface IInteractionOptions - */ -/** - * If true, only consider items that intersect the point - * @name IInterfaceOptions#boolean - * @type Boolean - */ - -/** - * Contains interaction related functions - * @namespace Chart.Interaction - */ -var core_interaction = { - // Helper function for different modes - modes: { - single: function(chart, e) { - var position = getRelativePosition(e, chart); - var elements = []; - - parseVisibleItems(chart, function(element) { - if (element.inRange(position.x, position.y)) { - elements.push(element); - return elements; - } - }); - - return elements.slice(0, 1); - }, - - /** - * @function Chart.Interaction.modes.label - * @deprecated since version 2.4.0 - * @todo remove at version 3 - * @private - */ - label: indexMode, - - /** - * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something - * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item - * @function Chart.Interaction.modes.index - * @since v2.4.0 - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use during interaction - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - index: indexMode, - - /** - * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something - * If the options.intersect is false, we find the nearest item and return the items in that dataset - * @function Chart.Interaction.modes.dataset - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use during interaction - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - dataset: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - - if (items.length > 0) { - items = chart.getDatasetMeta(items[0]._datasetIndex).data; - } - - return items; - }, - - /** - * @function Chart.Interaction.modes.x-axis - * @deprecated since version 2.4.0. Use index mode and intersect == true - * @todo remove at version 3 - * @private - */ - 'x-axis': function(chart, e) { - return indexMode(chart, e, {intersect: false}); - }, - - /** - * Point mode returns all elements that hit test based on the event position - * of the event - * @function Chart.Interaction.modes.intersect - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - point: function(chart, e) { - var position = getRelativePosition(e, chart); - return getIntersectItems(chart, position); - }, - - /** - * nearest mode returns the element closest to the point - * @function Chart.Interaction.modes.intersect - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - nearest: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - return getNearestItems(chart, position, options.intersect, distanceMetric); - }, - - /** - * x mode returns the elements that hit-test at the current x coordinate - * @function Chart.Interaction.modes.x - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - x: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; - - parseVisibleItems(chart, function(element) { - if (element.inXRange(position.x)) { - items.push(element); - } - - if (element.inRange(position.x, position.y)) { - intersectsItem = true; - } - }); - - // If we want to trigger on an intersect and we don't have any items - // that intersect the position, return nothing - if (options.intersect && !intersectsItem) { - items = []; - } - return items; - }, - - /** - * y mode returns the elements that hit-test at the current y coordinate - * @function Chart.Interaction.modes.y - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - y: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; - - parseVisibleItems(chart, function(element) { - if (element.inYRange(position.y)) { - items.push(element); - } - - if (element.inRange(position.x, position.y)) { - intersectsItem = true; - } - }); - - // If we want to trigger on an intersect and we don't have any items - // that intersect the position, return nothing - if (options.intersect && !intersectsItem) { - items = []; - } - return items; - } - } -}; - -var extend = helpers$1.extend; - -function filterByPosition(array, position) { - return helpers$1.where(array, function(v) { - return v.pos === position; - }); -} - -function sortByWeight(array, reverse) { - return array.sort(function(a, b) { - var v0 = reverse ? b : a; - var v1 = reverse ? a : b; - return v0.weight === v1.weight ? - v0.index - v1.index : - v0.weight - v1.weight; - }); -} - -function wrapBoxes(boxes) { - var layoutBoxes = []; - var i, ilen, box; - - for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) { - box = boxes[i]; - layoutBoxes.push({ - index: i, - box: box, - pos: box.position, - horizontal: box.isHorizontal(), - weight: box.weight - }); - } - return layoutBoxes; -} - -function setLayoutDims(layouts, params) { - var i, ilen, layout; - for (i = 0, ilen = layouts.length; i < ilen; ++i) { - layout = layouts[i]; - // store width used instead of chartArea.w in fitBoxes - layout.width = layout.horizontal - ? layout.box.fullWidth && params.availableWidth - : params.vBoxMaxWidth; - // store height used instead of chartArea.h in fitBoxes - layout.height = layout.horizontal && params.hBoxMaxHeight; - } -} - -function buildLayoutBoxes(boxes) { - var layoutBoxes = wrapBoxes(boxes); - var left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true); - var right = sortByWeight(filterByPosition(layoutBoxes, 'right')); - var top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true); - var bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom')); - - return { - leftAndTop: left.concat(top), - rightAndBottom: right.concat(bottom), - chartArea: filterByPosition(layoutBoxes, 'chartArea'), - vertical: left.concat(right), - horizontal: top.concat(bottom) - }; -} - -function getCombinedMax(maxPadding, chartArea, a, b) { - return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]); -} - -function updateDims(chartArea, params, layout) { - var box = layout.box; - var maxPadding = chartArea.maxPadding; - var newWidth, newHeight; - - if (layout.size) { - // this layout was already counted for, lets first reduce old size - chartArea[layout.pos] -= layout.size; - } - layout.size = layout.horizontal ? box.height : box.width; - chartArea[layout.pos] += layout.size; - - if (box.getPadding) { - var boxPadding = box.getPadding(); - maxPadding.top = Math.max(maxPadding.top, boxPadding.top); - maxPadding.left = Math.max(maxPadding.left, boxPadding.left); - maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom); - maxPadding.right = Math.max(maxPadding.right, boxPadding.right); - } - - newWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'); - newHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'); - - if (newWidth !== chartArea.w || newHeight !== chartArea.h) { - chartArea.w = newWidth; - chartArea.h = newHeight; - - // return true if chart area changed in layout's direction - var sizes = layout.horizontal ? [newWidth, chartArea.w] : [newHeight, chartArea.h]; - return sizes[0] !== sizes[1] && (!isNaN(sizes[0]) || !isNaN(sizes[1])); - } -} - -function handleMaxPadding(chartArea) { - var maxPadding = chartArea.maxPadding; - - function updatePos(pos) { - var change = Math.max(maxPadding[pos] - chartArea[pos], 0); - chartArea[pos] += change; - return change; - } - chartArea.y += updatePos('top'); - chartArea.x += updatePos('left'); - updatePos('right'); - updatePos('bottom'); -} - -function getMargins(horizontal, chartArea) { - var maxPadding = chartArea.maxPadding; - - function marginForPositions(positions) { - var margin = {left: 0, top: 0, right: 0, bottom: 0}; - positions.forEach(function(pos) { - margin[pos] = Math.max(chartArea[pos], maxPadding[pos]); - }); - return margin; - } - - return horizontal - ? marginForPositions(['left', 'right']) - : marginForPositions(['top', 'bottom']); -} - -function fitBoxes(boxes, chartArea, params) { - var refitBoxes = []; - var i, ilen, layout, box, refit, changed; - - for (i = 0, ilen = boxes.length; i < ilen; ++i) { - layout = boxes[i]; - box = layout.box; - - box.update( - layout.width || chartArea.w, - layout.height || chartArea.h, - getMargins(layout.horizontal, chartArea) - ); - if (updateDims(chartArea, params, layout)) { - changed = true; - if (refitBoxes.length) { - // Dimensions changed and there were non full width boxes before this - // -> we have to refit those - refit = true; - } - } - if (!box.fullWidth) { // fullWidth boxes don't need to be re-fitted in any case - refitBoxes.push(layout); - } - } - - return refit ? fitBoxes(refitBoxes, chartArea, params) || changed : changed; -} - -function placeBoxes(boxes, chartArea, params) { - var userPadding = params.padding; - var x = chartArea.x; - var y = chartArea.y; - var i, ilen, layout, box; - - for (i = 0, ilen = boxes.length; i < ilen; ++i) { - layout = boxes[i]; - box = layout.box; - if (layout.horizontal) { - box.left = box.fullWidth ? userPadding.left : chartArea.left; - box.right = box.fullWidth ? params.outerWidth - userPadding.right : chartArea.left + chartArea.w; - box.top = y; - box.bottom = y + box.height; - box.width = box.right - box.left; - y = box.bottom; - } else { - box.left = x; - box.right = x + box.width; - box.top = chartArea.top; - box.bottom = chartArea.top + chartArea.h; - box.height = box.bottom - box.top; - x = box.right; - } - } - - chartArea.x = x; - chartArea.y = y; -} - -core_defaults._set('global', { - layout: { - padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - } -}); - -/** - * @interface ILayoutItem - * @prop {string} position - The position of the item in the chart layout. Possible values are - * 'left', 'top', 'right', 'bottom', and 'chartArea' - * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area - * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down - * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) - * @prop {function} update - Takes two parameters: width and height. Returns size of item - * @prop {function} getPadding - Returns an object with padding on the edges - * @prop {number} width - Width of item. Must be valid after update() - * @prop {number} height - Height of item. Must be valid after update() - * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update - * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update - * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update - * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update - */ - -// The layout service is very self explanatory. It's responsible for the layout within a chart. -// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need -// It is this service's responsibility of carrying out that layout. -var core_layouts = { - defaults: {}, - - /** - * Register a box to a chart. - * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title. - * @param {Chart} chart - the chart to use - * @param {ILayoutItem} item - the item to add to be layed out - */ - addBox: function(chart, item) { - if (!chart.boxes) { - chart.boxes = []; - } - - // initialize item with default values - item.fullWidth = item.fullWidth || false; - item.position = item.position || 'top'; - item.weight = item.weight || 0; - item._layers = item._layers || function() { - return [{ - z: 0, - draw: function() { - item.draw.apply(item, arguments); - } - }]; - }; - if(Array.isArray(chart.boxes)){ - chart.boxes.push(item); - } - }, - - /** - * Remove a layoutItem from a chart - * @param {Chart} chart - the chart to remove the box from - * @param {ILayoutItem} layoutItem - the item to remove from the layout - */ - removeBox: function(chart, layoutItem) { - if(chart.boxes){ - if(layoutItem){ - if(Array.isArray(chart.boxes)){ - var index = chart.boxes.indexOf(layoutItem) - chart.boxes.splice(index, 1); - } - } - } - }, - - /** - * Sets (or updates) options on the given `item`. - * @param {Chart} chart - the chart in which the item lives (or will be added to) - * @param {ILayoutItem} item - the item to configure with the given options - * @param {object} options - the new item options. - */ - configure: function(chart, item, options) { - var props = ['fullWidth', 'position', 'weight']; - var ilen = props.length; - var i = 0; - var prop; - - for (; i < ilen; ++i) { - prop = props[i]; - if (options.hasOwnProperty(prop)) { - item[prop] = options[prop]; - } - } - }, - - /** - * Fits boxes of the given chart into the given size by having each box measure itself - * then running a fitting algorithm - * @param {Chart} chart - the chart - * @param {number} width - the width to fit into - * @param {number} height - the height to fit into - */ - update: function(chart, width, height) { - if (!chart) { - return; - } - - var layoutOptions = chart.options.layout || {}; - var padding = helpers$1.options.toPadding(layoutOptions.padding); - - var availableWidth = width - padding.width; - var availableHeight = height - padding.height; - var boxes = buildLayoutBoxes(chart.boxes); - var verticalBoxes = boxes.vertical; - var horizontalBoxes = boxes.horizontal; - - // Essentially we now have any number of boxes on each of the 4 sides. - // Our canvas looks like the following. - // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and - // B1 is the bottom axis - // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays - // These locations are single-box locations only, when trying to register a chartArea location that is already taken, - // an error will be thrown. - // - // |----------------------------------------------------| - // | T1 (Full Width) | - // |----------------------------------------------------| - // | | | T2 | | - // | |----|-------------------------------------|----| - // | | | C1 | | C2 | | - // | | |----| |----| | - // | | | | | - // | L1 | L2 | ChartArea (C0) | R1 | - // | | | | | - // | | |----| |----| | - // | | | C3 | | C4 | | - // | |----|-------------------------------------|----| - // | | | B1 | | - // |----------------------------------------------------| - // | B2 (Full Width) | - // |----------------------------------------------------| - // - - var params = Object.freeze({ - outerWidth: width, - outerHeight: height, - padding: padding, - availableWidth: availableWidth, - vBoxMaxWidth: availableWidth / 2 / verticalBoxes.length, - hBoxMaxHeight: availableHeight / 2 - }); - var chartArea = extend({ - maxPadding: extend({}, padding), - w: availableWidth, - h: availableHeight, - x: padding.left, - y: padding.top - }, padding); - - setLayoutDims(verticalBoxes.concat(horizontalBoxes), params); - - // First fit vertical boxes - fitBoxes(verticalBoxes, chartArea, params); - - // Then fit horizontal boxes - if (fitBoxes(horizontalBoxes, chartArea, params)) { - // if the area changed, re-fit vertical boxes - fitBoxes(verticalBoxes, chartArea, params); - } - - handleMaxPadding(chartArea); - - // Finally place the boxes to correct coordinates - placeBoxes(boxes.leftAndTop, chartArea, params); - - // Move to opposite side of chart - chartArea.x += chartArea.w; - chartArea.y += chartArea.h; - - placeBoxes(boxes.rightAndBottom, chartArea, params); - - chart.chartArea = { - left: chartArea.left, - top: chartArea.top, - right: chartArea.left + chartArea.w, - bottom: chartArea.top + chartArea.h - }; - - // Finally update boxes in chartArea (radial scale for example) - helpers$1.each(boxes.chartArea, function(layout) { - var box = layout.box; - extend(box, chart.chartArea); - box.update(chartArea.w, chartArea.h); - }); - } -}; - -/** - * Platform fallback implementation (minimal). - * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939 - */ - -var platform_basic = { - acquireContext: function(item) { - if (item && item.canvas) { - // Support for any object associated to a canvas (including a context2d) - item = item.canvas; - } - - return item && item.getContext('2d') || null; - } -}; - -var platform_dom = "/*\n * DOM element rendering detection\n * https://davidwalsh.name/detect-node-insertion\n */\n@keyframes chartjs-render-animation {\n\tfrom { opacity: 0.99; }\n\tto { opacity: 1; }\n}\n\n.chartjs-render-monitor {\n\tanimation: chartjs-render-animation 0.001s;\n}\n\n/*\n * DOM element resizing detection\n * https://github.com/marcj/css-element-queries\n */\n.chartjs-size-monitor,\n.chartjs-size-monitor-expand,\n.chartjs-size-monitor-shrink {\n\tposition: absolute;\n\tdirection: ltr;\n\tleft: 0;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n\tvisibility: hidden;\n\tz-index: -1;\n}\n\n.chartjs-size-monitor-expand > div {\n\tposition: absolute;\n\twidth: 1000000px;\n\theight: 1000000px;\n\tleft: 0;\n\ttop: 0;\n}\n\n.chartjs-size-monitor-shrink > div {\n\tposition: absolute;\n\twidth: 200%;\n\theight: 200%;\n\tleft: 0;\n\ttop: 0;\n}\n"; - -var platform_dom$1 = /*#__PURE__*/Object.freeze({ -__proto__: null, -'default': platform_dom -}); - -var stylesheet = getCjsExportFromNamespace(platform_dom$1); - -var EXPANDO_KEY = '$chartjs'; -var CSS_PREFIX = 'chartjs-'; -var CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor'; -var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor'; -var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation'; -var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart']; - -/** - * DOM event types -> Chart.js event types. - * Note: only events with different types are mapped. - * @see https://developer.mozilla.org/en-US/docs/Web/Events - */ -var EVENT_TYPES = { - touchstart: 'mousedown', - touchmove: 'mousemove', - touchend: 'mouseup', - pointerenter: 'mouseenter', - pointerdown: 'mousedown', - pointermove: 'mousemove', - pointerup: 'mouseup', - pointerleave: 'mouseout', - pointerout: 'mouseout' -}; - -/** - * The "used" size is the final value of a dimension property after all calculations have - * been performed. This method uses the computed style of `element` but returns undefined - * if the computed style is not expressed in pixels. That can happen in some cases where - * `element` has a size relative to its parent and this last one is not yet displayed, - * for example because of `display: none` on a parent node. - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value - * @returns {number} Size in pixels or undefined if unknown. - */ -function readUsedSize(element, property) { - var value = helpers$1.getStyle(element, property); - var matches = value && value.match(/^(\d+)(\.\d+)?px$/); - return matches ? Number(matches[1]) : undefined; -} - -/** - * Initializes the canvas style and render size without modifying the canvas display size, - * since responsiveness is handled by the controller.resize() method. The config is used - * to determine the aspect ratio to apply in case no explicit height has been specified. - */ -function initCanvas(canvas, config) { - var style = canvas.style; - - // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it - // returns null or '' if no explicit value has been set to the canvas attribute. - var renderHeight = canvas.getAttribute('height'); - var renderWidth = canvas.getAttribute('width'); - - // Chart.js modifies some canvas values that we want to restore on destroy - canvas[EXPANDO_KEY] = { - initial: { - height: renderHeight, - width: renderWidth, - style: { - display: style.display, - height: style.height, - width: style.width - } - } - }; - - // Force canvas to display as block to avoid extra space caused by inline - // elements, which would interfere with the responsive resize process. - // https://github.com/chartjs/Chart.js/issues/2538 - style.display = style.display || 'block'; - - if (renderWidth === null || renderWidth === '') { - var displayWidth = readUsedSize(canvas, 'width'); - if (displayWidth !== undefined) { - canvas.width = displayWidth; - } - } - - if (renderHeight === null || renderHeight === '') { - if (canvas.style.height === '') { - // If no explicit render height and style height, let's apply the aspect ratio, - // which one can be specified by the user but also by charts as default option - // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2. - canvas.height = canvas.width / (config.options.aspectRatio || 2); - } else { - var displayHeight = readUsedSize(canvas, 'height'); - if (displayWidth !== undefined) { - canvas.height = displayHeight; - } - } - } - - return canvas; -} - -/** - * Detects support for options object argument in addEventListener. - * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support - * @private - */ -var supportsEventListenerOptions = (function() { - var supports = false; - try { - var options = Object.defineProperty({}, 'passive', { - // eslint-disable-next-line getter-return - get: function() { - supports = true; - } - }); - _window.addEventListener('e', null, options); - } catch (e) { - // continue regardless of error - } - return supports; -}()); - -// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events. -// https://github.com/chartjs/Chart.js/issues/4287 -var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false; - -function addListener(node, type, listener) { - node.addEventListener(type, listener, eventListenerOptions); -} - -function removeListener(node, type, listener) { - node.removeEventListener(type, listener, eventListenerOptions); -} - -function createEvent(type, chart, x, y, nativeEvent) { - return { - type: type, - chart: chart, - native: nativeEvent || null, - x: x !== undefined ? x : null, - y: y !== undefined ? y : null, - }; -} - -function fromNativeEvent(event, chart) { - var type = EVENT_TYPES[event.type] || event.type; - var pos = helpers$1.getRelativePosition(event, chart); - return createEvent(type, chart, pos.x, pos.y, event); -} - -function throttled(fn, thisArg) { - var ticking = false; - var args = []; - - return function() { - args = Array.prototype.slice.call(arguments); - thisArg = thisArg || this; - - if (!ticking) { - ticking = true; - helpers$1.requestAnimFrame.call(_window, function() { - ticking = false; - fn.apply(thisArg, args); - }); - } - }; -} - -function createDiv(cls) { - var el = document.createElement('div'); - el.className = cls || ''; - return el; -} - -// Implementation based on https://github.com/marcj/css-element-queries -function createResizer(handler) { - var maxSize = 1000000; - - // NOTE(SB) Don't use innerHTML because it could be considered unsafe. - // https://github.com/chartjs/Chart.js/issues/5902 - var resizer = createDiv(CSS_SIZE_MONITOR); - var expand = createDiv(CSS_SIZE_MONITOR + '-expand'); - var shrink = createDiv(CSS_SIZE_MONITOR + '-shrink'); - - expand.appendChild(createDiv()); - shrink.appendChild(createDiv()); - - resizer.appendChild(expand); - resizer.appendChild(shrink); - resizer._reset = function() { - expand.scrollLeft = maxSize; - expand.scrollTop = maxSize; - shrink.scrollLeft = maxSize; - shrink.scrollTop = maxSize; - }; - - var onScroll = function() { - resizer._reset(); - handler(); - }; - - addListener(expand, 'scroll', onScroll.bind(expand, 'expand')); - addListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink')); - - return resizer; -} - -// https://davidwalsh.name/detect-node-insertion -function watchForRender(node, handler) { - var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); - var proxy = expando.renderProxy = function(e) { - if (e.animationName === CSS_RENDER_ANIMATION) { - handler(); - } - }; - - helpers$1.each(ANIMATION_START_EVENTS, function(type) { - addListener(node, type, proxy); - }); - - // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class - // is removed then added back immediately (same animation frame?). Accessing the - // `offsetParent` property will force a reflow and re-evaluate the CSS animation. - // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics - // https://github.com/chartjs/Chart.js/issues/4737 - expando.reflow = !!node.offsetParent; - - node.classList.add(CSS_RENDER_MONITOR); -} - -function unwatchForRender(node) { - var expando = node[EXPANDO_KEY] || {}; - var proxy = expando.renderProxy; - - if (proxy) { - helpers$1.each(ANIMATION_START_EVENTS, function(type) { - removeListener(node, type, proxy); - }); - - delete expando.renderProxy; - } - - node.classList.remove(CSS_RENDER_MONITOR); -} - -function addResizeListener(node, listener, chart) { - var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); - - // Let's keep track of this added resizer and thus avoid DOM query when removing it. - var resizer = expando.resizer = createResizer(throttled(function() { - if (expando.resizer) { - var container = chart.options.maintainAspectRatio && node.parentNode; - var w = container ? container.clientWidth : 0; - listener(createEvent('resize', chart)); - if (container && container.clientWidth < w && chart.canvas) { - // If the container size shrank during chart resize, let's assume - // scrollbar appeared. So we resize again with the scrollbar visible - - // effectively making chart smaller and the scrollbar hidden again. - // Because we are inside `throttled`, and currently `ticking`, scroll - // events are ignored during this whole 2 resize process. - // If we assumed wrong and something else happened, we are resizing - // twice in a frame (potential performance issue) - listener(createEvent('resize', chart)); - } - } - })); - - // The resizer needs to be attached to the node parent, so we first need to be - // sure that `node` is attached to the DOM before injecting the resizer element. - watchForRender(node, function() { - if (expando.resizer) { - var container = node.parentNode; - if (container && container !== resizer.parentNode) { - container.insertBefore(resizer, container.firstChild); - } - - // The container size might have changed, let's reset the resizer state. - resizer._reset(); - } - }); -} - -function removeResizeListener(node) { - var expando = node[EXPANDO_KEY] || {}; - var resizer = expando.resizer; - - delete expando.resizer; - unwatchForRender(node); - - if (resizer && resizer.parentNode) { - resizer.parentNode.removeChild(resizer); - } -} - -/** - * Injects CSS styles inline if the styles are not already present. - * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the