diff --git a/example/MainPage.qml b/example/MainPage.qml index 82e3ce5..72c566f 100644 --- a/example/MainPage.qml +++ b/example/MainPage.qml @@ -55,6 +55,10 @@ FluWindow { text:"Rectangle" page:"qrc:/T_Rectangle.qml" } + ListElement{ + text:"TreeView" + page:"qrc:/T_TreeView.qml" + } ListElement{ text:"Theme" page:"qrc:/T_Theme.qml" @@ -93,12 +97,6 @@ FluWindow { FluApp.navigate("/About") } } - // FluMenuItem{ - // text:"设置" - // onClicked:{ - // FluApp.navigate("/Setting") - // } - // } } onClicked:{ menu.open() diff --git a/example/T_Dialog.qml b/example/T_Dialog.qml index 9881e07..98e25a9 100644 --- a/example/T_Dialog.qml +++ b/example/T_Dialog.qml @@ -6,11 +6,29 @@ import QtGraphicalEffects 1.15 import FluentUI 1.0 Item { + FluText{ id:title - text:"Dialog" + text:"Dialog" fontStyle: FluText.TitleLarge } + + FluContentDialog{ + id:dialog + title:"友情提示" + message:"确定要退出程序么?" + negativeText:"取消" + onNegativeClicked:{ + showSuccess("点击取消按钮") + } + positiveText:"确定" + onPositiveClicked:{ + showSuccess("点击确定按钮") + } + } + + + ScrollView{ clip: true width: parent.width @@ -25,7 +43,7 @@ Item { Layout.topMargin: 20 text:"Show Dialog" onClicked: { - + dialog.open() } } } diff --git a/example/T_Progress.qml b/example/T_Progress.qml index 2718d96..36cd07f 100644 --- a/example/T_Progress.qml +++ b/example/T_Progress.qml @@ -44,6 +44,7 @@ Item { progress_bar.progress = value/100 progress_ring.progress = value/100 } + Layout.bottomMargin: 30 } } } diff --git a/example/T_Slider.qml b/example/T_Slider.qml index 14c9bb8..2f2b692 100644 --- a/example/T_Slider.qml +++ b/example/T_Slider.qml @@ -23,6 +23,7 @@ Item { spacing: 5 FluSlider{ Layout.topMargin: 20 + Layout.leftMargin: 15 value: 50 } } diff --git a/example/T_TreeView.qml b/example/T_TreeView.qml new file mode 100644 index 0000000..72bae9f --- /dev/null +++ b/example/T_TreeView.qml @@ -0,0 +1,27 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Window 2.15 +import QtQuick.Controls 2.15 +import QtGraphicalEffects 1.15 +import FluentUI 1.0 + +Item { + FluText{ + id:title + text:"TreeView" + fontStyle: FluText.TitleLarge + } + FluTreeView{ + id:tree_view + width:100 + anchors{ + top:title.bottom + left:parent.left + bottom:parent.bottom + } + Component.onCompleted: { + + } + + } +} diff --git a/example/T_Typography.qml b/example/T_Typography.qml index 7229036..da7895d 100644 --- a/example/T_Typography.qml +++ b/example/T_Typography.qml @@ -6,7 +6,7 @@ import FluentUI 1.0 Item { FluText{ id:title - text:"Theme" + text:"Typography" fontStyle: FluText.TitleLarge } ScrollView{ @@ -21,6 +21,7 @@ Item { spacing: 5 FluText{ text:"Display" + Layout.topMargin: 20 fontStyle: FluText.Display } FluText{ diff --git a/example/qml.qrc b/example/qml.qrc index 27f69c0..912619c 100644 --- a/example/qml.qrc +++ b/example/qml.qrc @@ -28,5 +28,6 @@ T_TextBox.qml T_Theme.qml T_Dialog.qml + T_TreeView.qml diff --git a/src/Fluent.cpp b/src/Fluent.cpp index 6fec0fd..bd1e989 100644 --- a/src/Fluent.cpp +++ b/src/Fluent.cpp @@ -33,6 +33,7 @@ void Fluent::registerTypes(const char *uri){ qmlRegisterType(uri,major,minor,"WindowHelper"); qmlRegisterType(uri,major,minor,"FluColorSet"); + qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTreeView.qml"),uri,major,minor,"FluTreeView"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluContentDialog.qml"),uri,major,minor,"FluContentDialog"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu"); qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenuItem.qml"),uri,major,minor,"FluMenuItem"); diff --git a/src/FramelessView_win.cpp b/src/FramelessView_win.cpp index a129a10..ae53d3e 100644 --- a/src/FramelessView_win.cpp +++ b/src/FramelessView_win.cpp @@ -4,6 +4,27 @@ #include #include +#include +#include +#include +#include // Fixes error C2504: 'IUnknown' : base class undefined +#include +#include +#include +#pragma comment(lib, "Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved +#pragma comment(lib, "User32.lib") +#pragma comment(lib, "Gdi32.lib") + +static bool isMaxWin(QWindow* win) +{ + return win->windowState() == Qt::WindowMaximized; +} +static bool isFullWin(QQuickView* win) +{ + return win->windowState() == Qt::WindowFullScreen; +} + + class FramelessViewPrivate { public: @@ -100,6 +121,44 @@ bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, qint bool FramelessView::nativeEvent(const QByteArray &eventType, void *message, long *result) #endif { +#if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1)) + // Work-around a bug caused by typo which only exists in Qt 5.11.1 + const auto msg = *reinterpret_cast(message); +#else + const auto msg = static_cast(message); +#endif + if (!msg || !msg->hwnd) + { + return false; + } + switch (msg->message) + { + case WM_NCCALCSIZE: { + const auto mode = static_cast(msg->wParam); + const auto clientRect = mode ? &(reinterpret_cast(msg->lParam)->rgrc[0]) : reinterpret_cast(msg->lParam); + if (mode == TRUE) + { + *result = WVR_REDRAW; + //规避 拖动border进行resize时界面闪烁 + if (!isMaxWin(this) && !isFullWin(this)) + { + if (clientRect->top != 0) + { + clientRect->top -= 0.1; + } + } + else + { + if (clientRect->top != 0) + { + clientRect->top += 0.1; + } + } + return true; + } + break; + } + } return Super::nativeEvent(eventType, message, result); } diff --git a/src/controls/FluAppBar.qml b/src/controls/FluAppBar.qml index eef8b88..48b52c2 100644 --- a/src/controls/FluAppBar.qml +++ b/src/controls/FluAppBar.qml @@ -11,7 +11,7 @@ Rectangle{ color: { if(Window.window == null) return borerlessColor - return Window.window.active ? borerlessColor : Qt.lighter(FluTheme.primaryColor.lightest,1.1) + return Window.window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1) } height: 50 width: { diff --git a/src/controls/FluContentDialog.qml b/src/controls/FluContentDialog.qml index 46da69c..3c46977 100644 --- a/src/controls/FluContentDialog.qml +++ b/src/controls/FluContentDialog.qml @@ -1,19 +1,115 @@ import QtQuick 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 +import QtQuick.Window 2.15 Popup { id: popup - default property alias content: container.data + property string title: "Title" + property string message: "Messaeg" + property string negativeText: "Negative" + property string positiveText: "Positive" + signal negativeClicked + signal positiveClicked + + property var minWidth: { + if(Window.window==null) + return 400 + return Math.min(Window.window.width,400) + } + + modal:true + anchors.centerIn: Overlay.overlay + closePolicy: Popup.CloseOnEscape background: Rectangle { - implicitWidth: 140 - implicitHeight: container.height - color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(237/255,237/255,237/255,1) - radius: 5 + implicitWidth:minWidth + implicitHeight: text_title.height + text_message.height + layout_actions.height + color:FluTheme.isDark ? Qt.rgba(45/255,45/255,45/255,1) : Qt.rgba(249/255,249/255,249/255,1) + radius:5 FluShadow{ radius: 5 } + FluText{ + id:text_title + fontStyle: FluText.TitleLarge + text:title + topPadding: 20 + leftPadding: 20 + rightPadding: 20 + wrapMode: Text.WrapAnywhere + anchors{ + top:parent.top + left: parent.left + right: parent.right + } + } + + FluText{ + id:text_message + fontStyle: FluText.Body + wrapMode: Text.WrapAnywhere + text:message + topPadding: 14 + leftPadding: 20 + rightPadding: 20 + bottomPadding: 14 + anchors{ + top:text_title.bottom + left: parent.left + right: parent.right + } + } + + Rectangle{ + id:layout_actions + height: 68 + radius: 5 + color: FluTheme.isDark ? Qt.rgba(32/255,32/255,32/255,1) : Qt.rgba(243/255,243/255,243/255,1) + anchors{ + top:text_message.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: negativeText + onClicked: { + popup.close() + negativeClicked() + } + } + + FluFilledButton{ + anchors{ + right: parent.right + left: divider.right + rightMargin: 20 + leftMargin: 10 + verticalCenter: parent.verticalCenter + } + text: positiveText + onClicked: { + popup.close() + positiveClicked() + } + } + + } } } diff --git a/src/controls/FluTreeItem.qml b/src/controls/FluTreeItem.qml new file mode 100644 index 0000000..cc3b985 --- /dev/null +++ b/src/controls/FluTreeItem.qml @@ -0,0 +1,6 @@ +import QtQuick 2.15 + +QtObject { + property string text; + property list items; +} diff --git a/src/controls/FluTreeView.qml b/src/controls/FluTreeView.qml new file mode 100644 index 0000000..c8ab3fe --- /dev/null +++ b/src/controls/FluTreeView.qml @@ -0,0 +1,52 @@ +import QtQuick 2.15 +import QtQuick.Window 2.15 +import QtQuick.Layouts 1.15 +import FluentUI 1.0 +import QtGraphicalEffects 1.15 + +Rectangle { + id:root + color:"#eeeeee" + + ListModel{ + id:list_model + } + + ListView { + id: list_root + anchors.fill: parent + + delegate: Rectangle{ + width: list_root.width + height: 40 + FluText{ + anchors.centerIn: parent + text:model.text + } + } + model:list_model + clip: true + } + + + function addItems(items:list){ + items.map(item=>{ + list_model.append({"text":item.text}) + console.debug(item.text) + }) + } + + function createItem(text){ + var com = Qt.createComponent("FluTreeItem.qml") + return com.createObject(root,{text:text}) + } + + Component.onCompleted: { + addItems([createItem("item1"),createItem("item2")]) + // var data=[{"text":"item1"},{"text":"item1"}] + // list_model.append(data) + } + + + +} diff --git a/src/controls/FluWindow.qml b/src/controls/FluWindow.qml index 53e1607..7423002 100644 --- a/src/controls/FluWindow.qml +++ b/src/controls/FluWindow.qml @@ -46,7 +46,7 @@ Item { color: { if(window === null) return borerlessColor - return window.active ? borerlessColor : Qt.lighter(FluTheme.primaryColor.lightest,1.1) + return window.active ? borerlessColor : Qt.lighter(borerlessColor,1.1) } border.width: 1 anchors.fill: parent diff --git a/src/res.qrc b/src/res.qrc index 2932444..80f8caa 100644 --- a/src/res.qrc +++ b/src/res.qrc @@ -33,5 +33,7 @@ controls/FluShadow.qml controls/FluTextButton.qml controls/FluContentDialog.qml + controls/FluTreeView.qml + controls/FluTreeItem.qml