This commit is contained in:
朱子楚\zhuzi 2023-04-01 21:01:46 +08:00
parent ed0c9048b0
commit 27db8160d4
18 changed files with 377 additions and 222 deletions

4
CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)
project(FluentUI VERSION 0.1 LANGUAGES CXX)
add_subdirectory(src)
add_subdirectory(example)

69
example/CMakeLists.txt Normal file
View File

@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 3.16)
project(example)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
find_package(Qt6 COMPONENTS Core Quick QuickControls2 Concurrent Network Multimedia REQUIRED)
set(SOURCES
ChatController.cpp
main.cpp
)
set(HEADERS
ChatController.h
)
set(RESOURCES
qml.qrc
)
set(RC_ICONS
favicon.ico
)
qt_add_resources(QT_RESOURCES ${RESOURCES})
if(WIN32)
if(QT_ARCH EQUAL 32)
set(COPYDLL ${CMAKE_CURRENT_SOURCE_DIR}/../third/Win_x86/*.dll ${DESTDIR})
else()
set(COPYDLL ${CMAKE_CURRENT_SOURCE_DIR}/../third/Win_x64/*.dll ${DESTDIR})
endif()
if(QMAKE_CC STREQUAL "cl")
set(QMAKE_PRE_LINK "${QMAKE_COPY} ${COPYDLL}")
else()
set(QMAKE_PRE_LINK "${QMAKE_COPY} ${COPYDLL}")
endif()
endif()
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QT_RESOURCES} ${RC_ICONS})
target_compile_definitions(${PROJECT_NAME} PRIVATE
QT_DEPRECATED_WARNINGS
QT_NO_WARNING_OUTPUT
)
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt6::Core
Qt6::Quick
Qt6::QuickControls2
Qt6::Concurrent
Qt6::Network
Qt6::Multimedia
)
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE WIN32 _WINDOWS)
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
endif()
if(APPLE)
set_target_properties(${PROJECT_NAME} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST Info.plist
)
endif()

View File

@ -129,7 +129,7 @@ FluScrollablePage{
id:item_mouse
anchors.fill: parent
hoverEnabled: true
onWheel: {
onWheel: (wheel)=>{
if (wheel.angleDelta.y > 0) scrollbar_header.decrease()
else scrollbar_header.increase()
}

View File

@ -17,7 +17,7 @@ FluScrollablePage{
Layout.preferredWidth: 300
disabled:toggle_switch.selected
}
FluMultiLineTextBox{
FluMultilineTextBox{
Layout.topMargin: 20
Layout.preferredWidth: 300
placeholderText: "多行输入框"

64
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.16)
project(FluentUI)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
find_package(Qt6 COMPONENTS Core Quick Svg REQUIRED)
set(QT_INSTALL_QML ${Qt6Core_DIR}/../../../qml)
set(TARGET_TYPE SHARED)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/FluentUI)
set(TARGET_RESOURCES res.qrc)
set(TARGET_SOURCES
Def.cpp
FluApp.cpp
FluColorSet.cpp
FluColors.cpp
FluRegister.cpp
FluTheme.cpp
Fluent.cpp
FluentUI.cpp
WindowHelper.cpp
qml_plugin.cpp
)
set(TARGET_HEADERS
Def.h
FluApp.h
FluColorSet.h
FluColors.h
FluRegister.h
FluTheme.h
Fluent.h
FluentUI.h
FramelessView.h
WindowHelper.h
qml_plugin.h
stdafx.h
)
if(WIN32)
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_win.cpp)
else()
set(TARGET_SOURCES ${TARGET_SOURCES} FramelessView_unix.cpp)
endif()
add_library(${PROJECT_NAME} ${TARGET_TYPE} ${TARGET_SOURCES} ${TARGET_HEADERS} ${TARGET_RESOURCES})
target_compile_definitions(${PROJECT_NAME} PRIVATE VERSION_IN=\\\"1.0.0\\\" URI_STR=\\\"FluentUI\\\")
if(WIN32)
target_link_libraries(${PROJECT_NAME} PRIVATE dwmapi user32)
else()
endif()
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Quick Qt6::Svg)
if(WIN32)
include(build_windows.cmake)
else()
include(build_macos.cmake)
endif()

View File

@ -22,7 +22,7 @@ Fluent *Fluent::getInstance()
QString Fluent::version() const
{
return QStringLiteral(VERSION_IN);
return QStringLiteral("1.0.0");
}
void Fluent::registerTypes(const char *uri){
@ -59,7 +59,7 @@ void Fluent::registerTypes(const char *uri){
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMenu.qml"),uri,major,minor,"FluMenu");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluScrollBar.qml"),uri,major,minor,"FluScrollBar");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTextButton.qml"),uri,major,minor,"FluTextButton");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultiLineTextBox.qml"),uri,major,minor,"FluMultiLineTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluMultilineTextBox.qml"),uri,major,minor,"FluMultilineTextBox");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluTooltip.qml"),uri,major,minor,"FluTooltip");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluDivider.qml"),uri,major,minor,"FluDivider");
qmlRegisterType(QUrl("qrc:/com.zhuzichu/controls/FluIcon.qml"),uri,major,minor,"FluIcon");

37
src/build_macos.cmake Normal file
View File

@ -0,0 +1,37 @@
set(OUTP "${CMAKE_CURRENT_BINARY_DIR}/../bin/FluentUI/")
add_definitions(-DMACOS)
# Set DESTDIR to the output directory
set(CMAKE_INSTALL_PREFIX ${OUTP})
set(CMAKE_INSTALL_DESTDIR ${OUTP})
# Add the current source directory to the include path
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# Set MOC options
set(QMAKE_MOC_OPTIONS -Muri=${uri})
# Set pre-link commands
add_custom_command(
TARGET ${PROJECT_NAME} PRE_LINK
COMMAND chmod -R 777 ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh PRESET ${CMAKE_CURRENT_SOURCE_DIR}/ ${OUTP}
)
# Set post-link commands for shared library
if(BUILD_SHARED_LIBS)
# Set INST_QMLPATH variable
set(INST_QMLPATH "${QT_INSTALL_QML}/${uri}" REPLACE "\\" "/")
# Set post-link command
add_custom_command(
TARGET ${PROJECT_NAME} POST_LINK
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/macos_install.sh INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/ ${OUTP} ${INST_QMLPATH}
)
# Include dev.pri if it exists
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../dev.pri)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../dev.pri)
endif()
endif()

27
src/build_windows.cmake Normal file
View File

@ -0,0 +1,27 @@
set(OUTP "${CMAKE_BINARY_DIR}/src/../bin/FluentUI")
set(BUILDBIN_PATH "${OUTP}")
set(QTQMLFLUENT_PATH "${QT_INSTALL_QML}/FluentUI")
set(PRESET_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build-preset")
set(SOLIBFILE_PATH "${CMAKE_BINARY_DIR}/libFluentUI.so")
set(ANDROID NO)
if (ANDROID)
set(ANDROID YES)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTP})
else()
set(CMAKE_INSTALL_PREFIX "${OUTP}")
endif()
set(SHAREDSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/win_install.bat SHARED ${CMAKE_CURRENT_SOURCE_DIR} ${PRESET_PATH} ${BUILDBIN_PATH} ${QTQMLFLUENT_PATH} ${ANDROID} ${SOLIBFILE_PATH})
set(STATICSCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/win_install.bat STATIC ${CMAKE_CURRENT_SOURCE_DIR} ${PRESET_PATH} ${BUILDBIN_PATH} ${QTQMLFLUENT_PATH} ${ANDROID} ${SOLIBFILE_PATH})
string(REPLACE "/" "\\" SHAREDSCRIPT "${SHAREDSCRIPT}")
string(REPLACE "/" "\\" STATICSCRIPT "${STATICSCRIPT}")
if (${TARGET_TYPE} STREQUAL "SHARED")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${SHAREDSCRIPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
else()
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${STATICSCRIPT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endif()

View File

@ -1,5 +1,8 @@
OUTP = $$OUT_PWD/../bin/FluentUI
BUILDBIN_PATH = $$replace(OUTP, src/../bin, bin)
message("----------------->")
message($$OUTP)
message($$BUILDBIN_PATH)
QTQMLFLUENT_PATH = $$[QT_INSTALL_QML]/FluentUI
PRESET_PATH = $$PWD/build-preset
SOLIBFILE_PATH = $$OUT_PWD/libFluentUI.so
@ -15,6 +18,8 @@ android{
SHAREDSCRIPT = "$$PWD\win_install.bat" SHARED "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
STATICSCRIPT = "$$PWD\win_install.bat" STATIC "$$PWD" "$$PRESET_PATH" "$$BUILDBIN_PATH" "$$QTQMLFLUENT_PATH" $$ANDROID "$$SOLIBFILE_PATH"
message("-------------------------")
message($$SHAREDSCRIPT)
CONFIG(sharedlib){
QMAKE_POST_LINK *= $$replace(SHAREDSCRIPT, /, \\)
}

View File

@ -30,10 +30,10 @@ Item {
pickerCursor.y = Math.max(0, Math.min(height, mouse.y)-cursorHeight)
}
}
onPositionChanged: {
onPositionChanged:(mouse)=> {
handleMouse(mouse)
}
onPressed: handleMouse(mouse)
onPressed:(mouse)=> handleMouse(mouse)
}
function setValue(val) {

View File

@ -7,16 +7,28 @@ import FluentUI
Rectangle{
property string title: ""
property string darkText : "夜间模式"
property string minimizeText : "最小化"
property string restoreText : "向下还原"
property string maximizeText : "最大化"
property string closeText : "关闭"
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
property color minimizeNormalColor: Qt.rgba(0,0,0,0)
property color minimizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
property color maximizeNormalColor: Qt.rgba(0,0,0,0)
property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06)
property color closeNormalColor: Qt.rgba(0,0,0,0)
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
property bool showDark: false
property bool showFps: false
property var window: Window.window
property color borerlessColor : FluTheme.dark ? FluTheme.primaryColor.lighter : FluTheme.primaryColor.dark
property bool resizable: {
if(window == null){
return false
}
return !(window.minimumHeight === window.maximumHeight && window.maximumWidth === window.minimumWidth)
Item{
id:d
property var win: Window.window
property bool isRestore: win && Window.Maximized === win.visibility
property bool resizable: win && !(win.minimumHeight === win.maximumHeight && win.maximumWidth === win.minimumWidth)
}
id:root
@ -34,7 +46,7 @@ Rectangle{
DragHandler {
target: null
grabPermissions: TapHandler.CanTakeOverFromAnything
onActiveChanged: if (active) { window.startSystemMove(); }
onActiveChanged: if (active) { d.win.startSystemMove(); }
}
FluText {
@ -62,7 +74,7 @@ Rectangle{
visible: showDark
spacing: 5
FluText{
text:"夜间模式"
text:darkText
color:root.textColor
}
FluToggleSwitch{
@ -79,53 +91,24 @@ Rectangle{
iconSource : FluentIcons.ChromeMinimize
Layout.alignment: Qt.AlignVCenter
iconSize: 11
text:"最小化"
text:minimizeText
radius: 0
textColor: root.textColor
color:{
if(FluTheme.dark){
if(hovered){
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(hovered){
return Qt.rgba(0,0,0,0.06)
}
return Qt.rgba(0,0,0,0)
}
}
color: hovered ? minimizeHoverColor : minimizeNormalColor
onClicked: {
window.showMinimized()
d.win.showMinimized()
}
}
FluIconButton{
width: 40
height: 30
property bool isRestore:{
if(window == null)
return false
return Window.Maximized === window.visibility
}
iconSource : isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
color:{
if(FluTheme.dark){
if(hovered){
return Qt.rgba(1,1,1,0.06)
}
return Qt.rgba(0,0,0,0)
}else{
if(hovered){
return Qt.rgba(0,0,0,0.06)
}
return Qt.rgba(0,0,0,0)
}
}
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
color: hovered ? maximizeHoverColor : maximizeNormalColor
Layout.alignment: Qt.AlignVCenter
visible: resizable
visible: d.resizable
radius: 0
textColor: root.textColor
text:isRestore?"向下还原":"最大化"
text:d.isRestore?restoreText:maximizeText
iconSize: 11
onClicked: {
toggleMaximized()
@ -134,26 +117,26 @@ Rectangle{
FluIconButton{
iconSource : FluentIcons.ChromeClose
Layout.alignment: Qt.AlignVCenter
text:"关闭"
text:closeText
width: 40
height: 30
radius: 0
iconSize: 10
textColor: hovered ? Qt.rgba(1,1,1,1) : root.textColor
color:hovered ? Qt.rgba(251/255,115/255,115/255,1) : "#00000000"
color:hovered ? closeHoverColor : closeNormalColor
onClicked: {
Window.window.close()
d.win.close()
}
}
}
function toggleMaximized() {
if(!resizable)
if(!d.resizable)
return
if (window.visibility === Window.Maximized) {
window.showNormal();
if (d.win.visibility === Window.Maximized) {
d.win.showNormal();
} else {
window.showMaximized();
d.win.showMaximized();
}
}

View File

@ -6,34 +6,40 @@ TextField{
property var items:[]
property int fontStyle: FluText.Body
property string emptyText: "没有找到结果"
property int pixelSize : FluTheme.textSize
property int iconSource: 0
property bool disabled: false
signal itemClicked(var data)
signal handleClicked
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)
QtObject{
id:d
property bool flagVisible: true
}
id:input
id:control
width: 300
enabled: !disabled
color: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return disableColor
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
return normalColor
}
selectionColor: FluTheme.primaryColor.lightest
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
placeholderTextColor: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return placeholderDisableColor
}
if(focus){
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
return placeholderFocusColor
}
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
return placeholderNormalColor
}
rightPadding: icon_right.visible ? 50 : 30
selectByMouse: true
@ -92,27 +98,25 @@ TextField{
width: 20
height: 20
opacity: 0.5
visible: input.text !== ""
visible: control.text !== ""
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: icon_right.visible ? 25 : 5
}
onClicked:{
input.text = ""
control.text = ""
}
}
background: FluTextBoxBackground{
inputItem: input
inputItem: control
FluIcon{
id:icon_right
iconSource: input.iconSource
iconSource: control.iconSource
iconSize: 15
opacity: 0.5
visible: input.iconSource != 0
visible: control.iconSource != 0
anchors{
verticalCenter: parent.verticalCenter
right: parent.right
@ -122,18 +126,18 @@ TextField{
}
Component.onCompleted: {
searchData()
loadData()
}
Popup{
id:input_popup
y:input.height
id:control_popup
y:control.height
focus: false
enter: Transition {
NumberAnimation {
property: "y"
from:0
to:input_popup.y
to:control_popup.y
duration: 150
}
NumberAnimation {
@ -149,7 +153,7 @@ TextField{
}
}
background: Rectangle{
width: input.width
width: control.width
radius: 4
FluShadow{
radius: 4
@ -163,11 +167,11 @@ TextField{
currentIndex: -1
ScrollBar.vertical: FluScrollBar {}
header: Item{
width: input.width
width: control.width
height: visible ? 38 : 0
visible: list_view.count === 0
FluText{
text:"没有找到结果"
text:emptyText
anchors{
verticalCenter: parent.verticalCenter
left: parent.left
@ -176,7 +180,7 @@ TextField{
}
}
delegate:Control{
width: input.width
width: control.width
padding:10
background: Rectangle{
color: {
@ -192,7 +196,7 @@ TextField{
id:mouse_area
anchors.fill: parent
Connections{
target: input
target: control
function onHandleClicked(){
if((list_view.currentIndex === index)){
handleClick(modelData)
@ -223,72 +227,41 @@ TextField{
}
}
}
onTextChanged: {
loadData()
if(d.flagVisible){
control_popup.visible = true
}
}
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluTextBoxMenu{
id:menu
inputItem: control
}
function handleClick(modelData){
input_popup.visible = false
input.itemClicked(modelData)
control_popup.visible = false
control.itemClicked(modelData)
updateText(modelData.title)
}
function updateText(text){
d.flagVisible = false
input.text = text
control.text = text
d.flagVisible = true
}
onTextChanged: {
searchData()
if(d.flagVisible){
input_popup.visible = true
}
}
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: input.echoMode !== TextInput.Password && menu.popup()
}
FluMenu{
id:menu
focus: false
FluMenuItem{
text: "剪切"
visible: input.text !== ""
onClicked: {
input.cut()
}
}
FluMenuItem{
text: "复制"
visible: input.selectedText !== ""
onClicked: {
input.copy()
}
}
FluMenuItem{
text: "粘贴"
visible: input.canPaste
onClicked: {
input.paste()
}
}
FluMenuItem{
text: "全选"
visible: input.text !== ""
onClicked: {
input.selectAll()
}
}
}
function searchData(){
function loadData(){
var result = []
if(items==null){
list_view.model = result
return
}
items.map(function(item){
if(item.title.indexOf(input.text)!==-1){
if(item.title.indexOf(control.text)!==-1){
result.push(item)
}
})

View File

@ -9,9 +9,10 @@ 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: "请选择日期"
property var window : Window.window
id:root
id:control
color: {
if(mouse_area.containsMouse){
return hoverColor
@ -44,7 +45,7 @@ Rectangle {
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text:"请选择日期"
text:control.text
}
FluIcon{
@ -95,15 +96,15 @@ Rectangle {
}
background: Item{}
function showPopup() {
var pos = root.mapToItem(null, 0, 0)
if(window.height>pos.y+root.height+popup.height){
popup.y = root.height
var pos = control.mapToItem(null, 0, 0)
if(window.height>pos.y+control.height+popup.height){
popup.y = control.height
} else if(pos.y>popup.height){
popup.y = -popup.height
} else {
popup.y = window.height-(pos.y+popup.height)
}
popup.x = -(popup.width-root.width)/2
popup.x = -(popup.width-control.width)/2
popup.open()
}
}

View File

@ -7,31 +7,32 @@ TextArea{
property int fontStyle: FluText.Body
property int pixelSize : FluTheme.textSize
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)
id:input
id:control
width: 300
enabled: !disabled
color: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return disableColor
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
return normalColor
}
enabled: !disabled
wrapMode: Text.WrapAnywhere
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectByMouse: true
selectionColor: FluTheme.primaryColor.lightest
background: FluTextBoxBackground{
inputItem: input
}
placeholderTextColor: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return placeholderDisableColor
}
if(focus){
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
return placeholderFocusColor
}
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
return placeholderNormalColor
}
font.bold: {
switch (fontStyle) {
@ -73,40 +74,15 @@ TextArea{
return text.pixelSize * 1.0
}
}
selectByMouse: true
background: FluTextBoxBackground{ inputItem: control }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: input.echoMode !== TextInput.Password && menu.popup()
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluMenu{
FluTextBoxMenu{
id:menu
focus: false
FluMenuItem{
text: "剪切"
visible: input.text !== ""
onClicked: {
input.cut()
}
}
FluMenuItem{
text: "复制"
visible: input.selectedText !== ""
onClicked: {
input.copy()
}
}
FluMenuItem{
text: "粘贴"
visible: input.canPaste
onClicked: {
input.paste()
}
}
FluMenuItem{
text: "全选"
visible: input.text !== ""
onClicked: {
input.selectAll()
}
}
inputItem: control
}
}

View File

@ -131,7 +131,7 @@ Item {
drag.target: item_container
drag.axis: Drag.XAxis
onWheel: {
onWheel: (wheel)=>{
if (wheel.angleDelta.y > 0) scroll_nav.decrease()
else scroll_nav.increase()
}
@ -198,7 +198,7 @@ Item {
}
}
function updatePosition(pos){
var idx = tab_nav.indexAt(pos.x+tab_nav.contentX, pos.y)
var idx = tab_nav.indexAt(pos.x+tab_nav.contentX+1, pos.y)
var firstIdx = tab_nav.indexAt(tab_nav.contentX+1, pos.y)
var lastIdx = tab_nav.indexAt(tab_nav.width+tab_nav.contentX-1, pos.y)
if(lastIdx === -1){

View File

@ -7,26 +7,31 @@ TextField{
property int fontStyle: FluText.Body
property int pixelSize : FluTheme.textSize
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)
id:input
id:control
width: 300
enabled: !disabled
color: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return disableColor
}
return FluTheme.dark ? Qt.rgba(255/255,255/255,255/255,1) : Qt.rgba(27/255,27/255,27/255,1)
return normalColor
}
renderType: FluTheme.nativeText ? Text.NativeRendering : Text.QtRendering
selectionColor: FluTheme.primaryColor.lightest
placeholderTextColor: {
if(disabled){
return FluTheme.dark ? Qt.rgba(131/255,131/255,131/255,1) : Qt.rgba(160/255,160/255,160/255,1)
return placeholderDisableColor
}
if(focus){
return FluTheme.dark ? Qt.rgba(152/255,152/255,152/255,1) : Qt.rgba(141/255,141/255,141/255,1)
return placeholderFocusColor
}
return FluTheme.dark ? Qt.rgba(210/255,210/255,210/255,1) : Qt.rgba(96/255,96/255,96/255,1)
return placeholderNormalColor
}
font.bold: {
switch (fontStyle) {
@ -69,44 +74,14 @@ TextField{
}
}
selectByMouse: true
background: FluTextBoxBackground{
inputItem: input
}
background: FluTextBoxBackground{ inputItem: control }
TapHandler {
acceptedButtons: Qt.RightButton
onTapped: input.echoMode !== TextInput.Password && menu.popup()
onTapped: control.echoMode !== TextInput.Password && menu.popup()
}
FluMenu{
FluTextBoxMenu{
id:menu
focus: false
FluMenuItem{
text: "剪切"
visible: input.text !== ""
onClicked: {
input.cut()
}
}
FluMenuItem{
text: "复制"
visible: input.selectedText !== ""
onClicked: {
input.copy()
}
}
FluMenuItem{
text: "粘贴"
visible: input.canPaste
onClicked: {
input.paste()
}
}
FluMenuItem{
text: "全选"
visible: input.text !== ""
onClicked: {
input.selectAll()
}
}
inputItem: control
}
}

View File

@ -0,0 +1,40 @@
import QtQuick
import FluentUI
FluMenu{
property string cutText : "剪切"
property string copyText : "复制"
property string pasteText : "粘贴"
property string selectAllText : "全选"
property var inputItem
id:menu
focus: false
FluMenuItem{
text: cutText
visible: inputItem.text !== ""
onClicked: {
inputItem.cut()
}
}
FluMenuItem{
text: copyText
visible: inputItem.selectedText !== ""
onClicked: {
inputItem.copy()
}
}
FluMenuItem{
text: pasteText
visible: inputItem.canPaste
onClicked: {
inputItem.paste()
}
}
FluMenuItem{
text: selectAllText
visible: inputItem.text !== ""
onClicked: {
inputItem.selectAll()
}
}
}

View File

@ -1,4 +1,4 @@
<RCC>
<RCC>
<qresource prefix="/com.zhuzichu">
<file>controls/FluButton.qml</file>
<file>controls/FluFilledButton.qml</file>
@ -23,7 +23,6 @@
<file>controls/FluDivider.qml</file>
<file>controls/FluTooltip.qml</file>
<file>controls/FluTextBoxBackground.qml</file>
<file>controls/FluMultiLineTextBox.qml</file>
<file>controls/FluWindowResize.qml</file>
<file>controls/FluScrollBar.qml</file>
<file>controls/FluMenu.qml</file>
@ -60,5 +59,7 @@
<file>controls/FluTabView.qml</file>
<file>controls/FluItem.qml</file>
<file>controls/FluPaneItemExpander.qml</file>
<file>controls/FluTextBoxMenu.qml</file>
<file>controls/FluMultilineTextBox.qml</file>
</qresource>
</RCC>