This commit is contained in:
朱子楚\zhuzi 2024-04-28 18:19:21 +08:00
parent d93aac3518
commit effd9f3058
8 changed files with 75 additions and 85 deletions

View File

@ -36,7 +36,7 @@ static inline bool isCompositionEnabled() {
} }
static inline void setShadow(HWND hwnd){ static inline void setShadow(HWND hwnd){
const MARGINS shadow = { 1, 1, 1, 1 }; const MARGINS shadow = { 1, 0, 0, 0 };
typedef HRESULT (WINAPI* DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset); typedef HRESULT (WINAPI* DwmExtendFrameIntoClientAreaPtr)(HWND hWnd, const MARGINS *pMarInset);
HMODULE module = LoadLibraryW(L"dwmapi.dll"); HMODULE module = LoadLibraryW(L"dwmapi.dll");
if (module) if (module)
@ -122,7 +122,9 @@ void FluFrameless::componentComplete() {
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER); ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOOWNERZORDER);
::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); ::RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
}); });
setShadow(hwnd); if(!window()->property("_hideShadow").toBool()){
setShadow(hwnd);
}
#endif #endif
h = qRound(h + _appbar->height()); h = qRound(h + _appbar->height());
if (_fixSize) { if (_fixSize) {

View File

@ -1,12 +1,11 @@
#include "FluTreeModel.h" #include "FluTreeModel.h"
#include <QMetaEnum> #include <QMetaEnum>
#include <utility>
FluTreeNode::FluTreeNode(QObject *parent) : QObject{parent} { FluTreeNode::FluTreeNode(QObject *parent) : QObject{parent} {
} }
FluTreeModel::FluTreeModel(QObject *parent) : QAbstractItemModel{parent} { FluTreeModel::FluTreeModel(QObject *parent) : QAbstractTableModel{parent} {
_dataSourceSize = 0; _dataSourceSize = 0;
} }
@ -17,7 +16,7 @@ QModelIndex FluTreeModel::parent(const QModelIndex &child) const {
QModelIndex FluTreeModel::index(int row, int column, const QModelIndex &parent) const { QModelIndex FluTreeModel::index(int row, int column, const QModelIndex &parent) const {
if (!hasIndex(row, column, parent) || parent.isValid()) if (!hasIndex(row, column, parent) || parent.isValid())
return {}; return {};
return createIndex(row, column, _rows.at(row)); return createIndex(row, column);
} }
int FluTreeModel::rowCount(const QModelIndex &parent) const { int FluTreeModel::rowCount(const QModelIndex &parent) const {

View File

@ -86,12 +86,11 @@ public:
FluTreeNode *_parent = nullptr; FluTreeNode *_parent = nullptr;
}; };
class FluTreeModel : public QAbstractItemModel { class FluTreeModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(int, dataSourceSize) Q_PROPERTY_AUTO(int, dataSourceSize)
Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource) Q_PROPERTY_AUTO(QList<QVariantMap>, columnSource)
QML_NAMED_ELEMENT(FluTreeModel) QML_NAMED_ELEMENT(FluTreeModel)
QML_ADDED_IN_MINOR_VERSION(1)
public: public:
enum TreeModelRoles { enum TreeModelRoles {
RowModel = 0x0101, RowModel = 0x0101,

View File

@ -15,6 +15,7 @@
#include "FluQrCodeItem.h" #include "FluQrCodeItem.h"
#include "FluTableSortProxyModel.h" #include "FluTableSortProxyModel.h"
#include "FluFrameless.h" #include "FluFrameless.h"
#include "FluTableModel.h"
void FluentUI::registerTypes(QQmlEngine *engine) { void FluentUI::registerTypes(QQmlEngine *engine) {
initializeEngine(engine, _uri); initializeEngine(engine, _uri);
@ -32,6 +33,7 @@ void FluentUI::registerTypes(const char *uri) const {
qmlRegisterType<FluWatermark>(uri, major, minor, "FluWatermark"); qmlRegisterType<FluWatermark>(uri, major, minor, "FluWatermark");
qmlRegisterType<FluAccentColor>(uri, major, minor, "FluAccentColor"); qmlRegisterType<FluAccentColor>(uri, major, minor, "FluAccentColor");
qmlRegisterType<FluTreeModel>(uri, major, minor, "FluTreeModel"); qmlRegisterType<FluTreeModel>(uri, major, minor, "FluTreeModel");
qmlRegisterType<FluTableModel>(uri, major, minor, "FluTableModel");
qmlRegisterType<FluRectangle>(uri, major, minor, "FluRectangle"); qmlRegisterType<FluRectangle>(uri, major, minor, "FluRectangle");
qmlRegisterType<FluFrameless>(uri, major, minor, "FluFrameless"); qmlRegisterType<FluFrameless>(uri, major, minor, "FluFrameless");
qmlRegisterType<FluTableSortProxyModel>(uri, major, minor, "FluTableSortProxyModel"); qmlRegisterType<FluTableSortProxyModel>(uri, major, minor, "FluTableSortProxyModel");

View File

@ -10,7 +10,7 @@ Rectangle {
readonly property alias columns: table_view.columns readonly property alias columns: table_view.columns
readonly property alias current: d.current readonly property alias current: d.current
readonly property alias sourceModel: table_model readonly property alias sourceModel: table_model
property var columnSource property var columnSource: []
property var dataSource property var dataSource
property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1) property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1)
property bool horizonalHeaderVisible: true property bool horizonalHeaderVisible: true
@ -27,17 +27,13 @@ Rectangle {
onColumnSourceChanged: { onColumnSourceChanged: {
if(columnSource.length!==0){ if(columnSource.length!==0){
var columns= [] var columns= []
var columnsData = []
var headerRow = {} var headerRow = {}
columnSource.forEach(function(item){ columnSource.forEach(function(item){
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model); var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model);
column.display = item.dataIndex column.display = item.dataIndex
columnsData.push(item)
columns.push(column) columns.push(column)
headerRow[item.dataIndex] = item.title headerRow[item.dataIndex] = item.title
}) })
d.columns_data = columnsData
table_model.columns = columns
header_column_model.columns = columns header_column_model.columns = columns
header_column_model.rows = [headerRow] header_column_model.rows = [headerRow]
} }
@ -48,15 +44,14 @@ Rectangle {
property int rowHoverIndex: -1 property int rowHoverIndex: -1
property int defaultItemWidth: 100 property int defaultItemWidth: 100
property int defaultItemHeight: 42 property int defaultItemHeight: 42
property var columns_data: []
property var editDelegate property var editDelegate
property var editPosition property var editPosition
function getEditDelegate(column){ function getEditDelegate(column){
var obj =d.columns_data[column].editDelegate var obj =control.columnSource[column].editDelegate
if(obj){ if(obj){
return obj return obj
} }
if(d.columns_data[column].editMultiline === true){ if(control.columnSource[column].editMultiline === true){
return com_edit_multiline return com_edit_multiline
} }
return com_edit return com_edit
@ -66,13 +61,13 @@ Rectangle {
table_model.clear() table_model.clear()
table_model.rows = dataSource table_model.rows = dataSource
} }
TableModel { FluTableModel {
id:table_model id:table_model
TableModelColumn {} columnSource: control.columnSource
} }
TableModel{ TableModel{
id:header_column_model id:header_column_model
TableModelColumn {} TableModelColumn { display : "title"}
} }
TableModel{ TableModel{
id:header_row_model id:header_row_model
@ -87,7 +82,7 @@ Rectangle {
FluTextBox{ FluTextBox{
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
Component.onCompleted: { Component.onCompleted: {
forceActiveFocus() forceActiveFocus()
selectAll() selectAll()
@ -113,7 +108,7 @@ Rectangle {
TextArea.flickable: FluMultilineTextBox { TextArea.flickable: FluMultilineTextBox {
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
isCtrlEnterForNewline: true isCtrlEnterForNewline: true
Component.onCompleted: { Component.onCompleted: {
@ -196,15 +191,21 @@ Rectangle {
id:com_table_delegate id:com_table_delegate
MouseArea{ MouseArea{
id:item_table_mouse id:item_table_mouse
property bool isRowSelected: {
if(rowModel === null)
return false
if(d.current){
return rowModel._key === d.current._key
}
return false
}
TableView.onPooled: { TableView.onPooled: {
if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){ if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){
control.closeEditor() control.closeEditor()
} }
} }
property var rowObject : control.getRow(row)
property var itemModel: model
property bool editVisible: { property bool editVisible: {
if(rowObject && d.editPosition && d.editPosition._key === rowObject._key && d.editPosition.column === column){ if(d.editPosition && d.editPosition._key === rowModel._key && d.editPosition.column === column){
return true return true
} }
return false return false
@ -235,7 +236,7 @@ Rectangle {
} }
function updateEditPosition(){ function updateEditPosition(){
var obj = {} var obj = {}
obj._key = rowObject._key obj._key = rowModel._key
obj.column = column obj.column = column
obj.row = row obj.row = row
obj.x = item_table_mouse.x obj.x = item_table_mouse.x
@ -245,22 +246,12 @@ Rectangle {
d.editPosition = obj d.editPosition = obj
} }
Rectangle{ Rectangle{
id:item_table
anchors.fill: parent 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:{ color:{
if(item_table.isRowSelected){ if(item_table_mouse.isRowSelected){
return control.selectedColor return control.selectedColor
} }
if(d.rowHoverIndex === row || item_table.isRowSelected){ if(d.rowHoverIndex === row || item_table_mouse.isRowSelected){
return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) 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)) return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.015) : Qt.rgba(0,0,0,0.015))
@ -279,22 +270,24 @@ Rectangle {
if(typeof(display) == "object"){ if(typeof(display) == "object"){
return return
} }
loader_edit.display = display loader_edit.display = item_table_loader.display
d.editDelegate = d.getEditDelegate(column) d.editDelegate = d.getEditDelegate(column)
updateEditPosition() updateEditPosition()
} }
onClicked: onClicked:
(event)=>{ (event)=>{
d.current = rowObject d.current = rowModel
control.closeEditor() control.closeEditor()
event.accepted = true event.accepted = true
} }
} }
FluLoader{ FluLoader{
property var model: itemModel id: item_table_loader
property var display: itemModel.display property var display: rowModel[columnModel.dataIndex]
property int row: item_table.position.y property var rowModel : model.rowModel
property int column: item_table.position.x property var columnModel : model.columnModel
property int row : model.row
property int column: model.column
property bool isObject: typeof(display) == "object" property bool isObject: typeof(display) == "object"
property var options: { property var options: {
if(isObject){ if(isObject){
@ -312,7 +305,7 @@ Rectangle {
} }
Item{ Item{
anchors.fill: parent anchors.fill: parent
visible: item_table.isRowSelected visible: item_table_mouse.isRowSelected
Rectangle{ Rectangle{
width: 1 width: 1
height: parent.height height: parent.height
@ -365,7 +358,7 @@ Rectangle {
ScrollBar.horizontal:scroll_bar_h ScrollBar.horizontal:scroll_bar_h
ScrollBar.vertical:scroll_bar_v ScrollBar.vertical:scroll_bar_v
columnWidthProvider: function(column) { columnWidthProvider: function(column) {
var columnObject = d.columns_data[column] var columnObject = control.columnSource[column]
var width = columnObject.width var width = columnObject.width
if(width){ if(width){
return width return width
@ -416,7 +409,7 @@ Rectangle {
onEditTextChaged: onEditTextChaged:
(text)=>{ (text)=>{
var obj = control.getRow(row) var obj = control.getRow(row)
obj[d.columns_data[column].dataIndex] = text obj[control.columnSource[column].dataIndex] = text
control.setRow(row,obj) control.setRow(row,obj)
} }
width: { width: {
@ -454,7 +447,7 @@ Rectangle {
readonly property real cellPadding: 8 readonly property real cellPadding: 8
property bool canceled: false property bool canceled: false
property int columnIndex: column property int columnIndex: column
readonly property var columnObject : d.columns_data[column] readonly property var columnObject : control.columnSource[column]
implicitWidth: { implicitWidth: {
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2) return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2)
} }

View File

@ -60,6 +60,7 @@ Window {
signal lazyLoad() signal lazyLoad()
property var _windowRegister property var _windowRegister
property string _route property string _route
property bool _hideShadow: false
id:window id:window
color:"transparent" color:"transparent"
Component.onCompleted: { Component.onCompleted: {

View File

@ -10,7 +10,7 @@ Rectangle {
readonly property alias columns: table_view.columns readonly property alias columns: table_view.columns
readonly property alias current: d.current readonly property alias current: d.current
readonly property alias sourceModel: table_model readonly property alias sourceModel: table_model
property var columnSource property var columnSource: []
property var dataSource property var dataSource
property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1) property color borderColor: FluTheme.dark ? Qt.rgba(37/255,37/255,37/255,1) : Qt.rgba(228/255,228/255,228/255,1)
property bool horizonalHeaderVisible: true property bool horizonalHeaderVisible: true
@ -27,17 +27,13 @@ Rectangle {
onColumnSourceChanged: { onColumnSourceChanged: {
if(columnSource.length!==0){ if(columnSource.length!==0){
var columns= [] var columns= []
var columnsData = []
var headerRow = {} var headerRow = {}
columnSource.forEach(function(item){ columnSource.forEach(function(item){
var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model); var column = Qt.createQmlObject('import Qt.labs.qmlmodels 1.0;TableModelColumn{}',table_model);
column.display = item.dataIndex column.display = item.dataIndex
columnsData.push(item)
columns.push(column) columns.push(column)
headerRow[item.dataIndex] = item.title headerRow[item.dataIndex] = item.title
}) })
d.columns_data = columnsData
table_model.columns = columns
header_column_model.columns = columns header_column_model.columns = columns
header_column_model.rows = [headerRow] header_column_model.rows = [headerRow]
} }
@ -48,15 +44,14 @@ Rectangle {
property int rowHoverIndex: -1 property int rowHoverIndex: -1
property int defaultItemWidth: 100 property int defaultItemWidth: 100
property int defaultItemHeight: 42 property int defaultItemHeight: 42
property var columns_data: []
property var editDelegate property var editDelegate
property var editPosition property var editPosition
function getEditDelegate(column){ function getEditDelegate(column){
var obj =d.columns_data[column].editDelegate var obj =control.columnSource[column].editDelegate
if(obj){ if(obj){
return obj return obj
} }
if(d.columns_data[column].editMultiline === true){ if(control.columnSource[column].editMultiline === true){
return com_edit_multiline return com_edit_multiline
} }
return com_edit return com_edit
@ -66,13 +61,13 @@ Rectangle {
table_model.clear() table_model.clear()
table_model.rows = dataSource table_model.rows = dataSource
} }
TableModel { FluTableModel {
id:table_model id:table_model
TableModelColumn {} columnSource: control.columnSource
} }
TableModel{ TableModel{
id:header_column_model id:header_column_model
TableModelColumn {} TableModelColumn { display : "title"}
} }
TableModel{ TableModel{
id:header_row_model id:header_row_model
@ -87,7 +82,7 @@ Rectangle {
FluTextBox{ FluTextBox{
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
Component.onCompleted: { Component.onCompleted: {
forceActiveFocus() forceActiveFocus()
selectAll() selectAll()
@ -113,7 +108,7 @@ Rectangle {
TextArea.flickable: FluMultilineTextBox { TextArea.flickable: FluMultilineTextBox {
id:text_box id:text_box
text: String(display) text: String(display)
readOnly: true === d.columns_data[column].readOnly readOnly: true === control.columnSource[column].readOnly
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
isCtrlEnterForNewline: true isCtrlEnterForNewline: true
Component.onCompleted: { Component.onCompleted: {
@ -196,15 +191,21 @@ Rectangle {
id:com_table_delegate id:com_table_delegate
MouseArea{ MouseArea{
id:item_table_mouse id:item_table_mouse
property bool isRowSelected: {
if(rowModel === null)
return false
if(d.current){
return rowModel._key === d.current._key
}
return false
}
TableView.onPooled: { TableView.onPooled: {
if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){ if(d.editPosition && d.editPosition.row === row && d.editPosition.column === column){
control.closeEditor() control.closeEditor()
} }
} }
property var rowObject : control.getRow(row)
property var itemModel: model
property bool editVisible: { property bool editVisible: {
if(rowObject && d.editPosition && d.editPosition._key === rowObject._key && d.editPosition.column === column){ if(d.editPosition && d.editPosition._key === rowModel._key && d.editPosition.column === column){
return true return true
} }
return false return false
@ -235,7 +236,7 @@ Rectangle {
} }
function updateEditPosition(){ function updateEditPosition(){
var obj = {} var obj = {}
obj._key = rowObject._key obj._key = rowModel._key
obj.column = column obj.column = column
obj.row = row obj.row = row
obj.x = item_table_mouse.x obj.x = item_table_mouse.x
@ -245,22 +246,12 @@ Rectangle {
d.editPosition = obj d.editPosition = obj
} }
Rectangle{ Rectangle{
id:item_table
anchors.fill: parent 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:{ color:{
if(item_table.isRowSelected){ if(item_table_mouse.isRowSelected){
return control.selectedColor return control.selectedColor
} }
if(d.rowHoverIndex === row || item_table.isRowSelected){ if(d.rowHoverIndex === row || item_table_mouse.isRowSelected){
return FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06) 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)) return (row%2!==0) ? control.color : (FluTheme.dark ? Qt.rgba(1,1,1,0.015) : Qt.rgba(0,0,0,0.015))
@ -279,22 +270,24 @@ Rectangle {
if(typeof(display) == "object"){ if(typeof(display) == "object"){
return return
} }
loader_edit.display = display loader_edit.display = item_table_loader.display
d.editDelegate = d.getEditDelegate(column) d.editDelegate = d.getEditDelegate(column)
updateEditPosition() updateEditPosition()
} }
onClicked: onClicked:
(event)=>{ (event)=>{
d.current = rowObject d.current = rowModel
control.closeEditor() control.closeEditor()
event.accepted = true event.accepted = true
} }
} }
FluLoader{ FluLoader{
property var model: itemModel id: item_table_loader
property var display: itemModel.display property var display: rowModel[columnModel.dataIndex]
property int row: item_table.position.y property var rowModel : model.rowModel
property int column: item_table.position.x property var columnModel : model.columnModel
property int row : model.row
property int column: model.column
property bool isObject: typeof(display) == "object" property bool isObject: typeof(display) == "object"
property var options: { property var options: {
if(isObject){ if(isObject){
@ -312,7 +305,7 @@ Rectangle {
} }
Item{ Item{
anchors.fill: parent anchors.fill: parent
visible: item_table.isRowSelected visible: item_table_mouse.isRowSelected
Rectangle{ Rectangle{
width: 1 width: 1
height: parent.height height: parent.height
@ -365,7 +358,7 @@ Rectangle {
ScrollBar.horizontal:scroll_bar_h ScrollBar.horizontal:scroll_bar_h
ScrollBar.vertical:scroll_bar_v ScrollBar.vertical:scroll_bar_v
columnWidthProvider: function(column) { columnWidthProvider: function(column) {
var columnObject = d.columns_data[column] var columnObject = control.columnSource[column]
var width = columnObject.width var width = columnObject.width
if(width){ if(width){
return width return width
@ -416,7 +409,7 @@ Rectangle {
onEditTextChaged: onEditTextChaged:
(text)=>{ (text)=>{
var obj = control.getRow(row) var obj = control.getRow(row)
obj[d.columns_data[column].dataIndex] = text obj[control.columnSource[column].dataIndex] = text
control.setRow(row,obj) control.setRow(row,obj)
} }
width: { width: {
@ -454,7 +447,7 @@ Rectangle {
readonly property real cellPadding: 8 readonly property real cellPadding: 8
property bool canceled: false property bool canceled: false
property int columnIndex: column property int columnIndex: column
readonly property var columnObject : d.columns_data[column] readonly property var columnObject : control.columnSource[column]
implicitWidth: { implicitWidth: {
return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2) return (item_column_loader.item && item_column_loader.item.implicitWidth) + (cellPadding * 2)
} }

View File

@ -59,6 +59,7 @@ Window {
signal lazyLoad() signal lazyLoad()
property var _windowRegister property var _windowRegister
property string _route property string _route
property bool _hideShadow: false
id:window id:window
color:"transparent" color:"transparent"
Component.onCompleted: { Component.onCompleted: {