qtdeclarative/tests/manual/quickcontrols/menus/Main.qml

367 lines
11 KiB
QML
Raw Normal View History

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtCore
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
ApplicationWindow {
id: window
width: 800
height: 600
visible: true
title: qsTr("Menus - style: %1").arg(currentStyle)
required property string currentStyle
Shortcut {
sequence: "Ctrl+Q"
onActivated: Qt.quit()
}
Settings {
id: settings
property alias windowX: window.x
property alias windowY: window.y
}
menuBar: MenuBar {
visible: menuBarVisibleSwitch.checked
Menu {
id: fileMenu
objectName: "file"
title: qsTr("&File")
ContextAction { text: qsTr("&New...") }
ContextMenuItem { text: "menuItem" }
ContextAction { text: qsTr("&Open...") }
ContextAction { text: qsTr("&Save") }
ContextAction { text: qsTr("Save &As...") }
MenuSeparator { }
ContextAction { text: qsTr("&Quit") }
Action {
text: qsTr("Remove menu")
onTriggered: menuBar.removeMenu(fileMenu)
}
}
Menu {
id: editMenu
objectName: "edit"
title: qsTr("&Edit")
ContextAction {
text: qsTr("Cut")
enabled: textArea.selectedText.length > 0
}
ContextAction {
text: qsTr("Copy")
enabled: textArea.selectedText.length > 0
}
ContextAction {
text: qsTr("Paste")
enabled: textArea.activeFocus
}
MenuSeparator {}
Action {
text: qsTr("Remove menu")
onTriggered: menuBar.removeMenu(editMenu)
}
Menu {
id: editSubMenu
title: qsTr("Find / Replace")
Action { text: qsTr("&Find") }
}
MenuSeparator {}
ContextAction {
text: qsTr("Dummy Action")
shortcut: "Ctrl+I"
}
}
MenuBarItem {
menu: Menu {
id: menuBarItemMenu
objectName: "MenuBarItem"
title: "MenuBarItem"
ContextAction { text: qsTr("Action") }
Action {
text: qsTr("Remove menu")
onTriggered: menuBar.removeMenu(menuBarItemMenu)
}
}
}
}
Component {
id: extraMenuComp
Menu {
id: extraMenu
objectName: "Extra"
title: qsTr("&Extra")
ContextAction { text: qsTr("&Trigger") }
Action {
text: qsTr("Remove Extra menu")
onTriggered: menuBar.removeMenu(extraMenu)
}
}
}
ColumnLayout {
anchors.fill: parent
Label {
text: qsTr("Right click on the window background to open a context menu. "
+ "Right click on the TextArea to access its edit context menu.\n\n"
+ "Things to check:\n\n"
+ "- Do the menu items trigger their actions (check console for output)?\n"
+ "- Do checkable menu items work?\n"
+ "- Do the Edit menu items (in the MenuBar menu and edit context menu)"
+ " work as expected with the TextArea?\n"
+ " - Are they enabled/disabled as expected?\n"
+ " - Does the TextArea keep focus after interacting with the Edit menu items?\n"
+ "- Does adding and removing menu items work?\n"
+ "- Do the menus in the MenuBar work?\n"
+ "- Can you add and remove menus from the MenuBar?\n"
+ "- Do shortcuts work?")
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: window.width * 0.5
Layout.fillHeight: true
}
GroupBox {
title: qsTr("Context menu")
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
Switch {
text: qsTr("Don't use native menu windows")
checked: CppSettings.dontUseNativeMenuWindows
onClicked: CppSettings.dontUseNativeMenuWindows = checked
}
Row {
Button {
text: qsTr("Add action")
onClicked: backgroundContextMenu.appendAction()
}
Button {
text: qsTr("Remove action")
onClicked: backgroundContextMenu.removeLastAction()
}
Button {
text: qsTr("Add sub-menu action")
onClicked: subMenu.appendAction()
}
Button {
text: qsTr("Remove sub-menu action")
onClicked: subMenu.removeLastAction()
}
}
}
}
TextArea {
id: textArea
text: qsTr("Dummy TextArea to test disabled menu items")
Layout.fillWidth: true
Layout.minimumHeight: 100
TapHandler {
objectName: "textAreaTapHandler"
acceptedButtons: Qt.RightButton
onTapped: editContextMenu.popup()
}
}
GroupBox {
title: qsTr("MenuBar")
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
Row {
Switch {
text: qsTr("Don't use native menu bar")
checked: CppSettings.dontUseNativeMenuBar
onClicked: CppSettings.dontUseNativeMenuBar = checked
}
Switch {
id: menuBarVisibleSwitch
text: qsTr("MenuBar visible")
checked: true
}
}
Row {
Button {
text: "Append menu"
onClicked: {
let menu = extraMenuComp.createObject(menuBar, { title: "Extra " + menuBar.count })
menuBar.addMenu(menu)
}
}
Button {
text: "Prepend menu"
onClicked: {
let menu = extraMenuComp.createObject(menuBar, { title: "Extra " + menuBar.count })
menuBar.insertMenu(0, menu)
}
}
Button {
text: qsTr("Add file menu")
onClicked: menuBar.addMenu(fileMenu)
}
}
}
}
}
TapHandler {
objectName: "backgroundTapHandler"
acceptedButtons: Qt.RightButton
onTapped: backgroundContextMenu.popup()
}
Component {
id: actionComponent
Action {}
}
component ContextAction: Action {
onCheckedChanged: (checked) => print("checked of \"" + text + "\" changed to " + checked)
onTriggered: print("triggered \"" + text + "\"")
}
component ContextMenuItem: MenuItem {
onCheckedChanged: print("checked of \"" + text + "\" changed to " + checked)
onTriggered: print("triggered \"" + text + "\"")
}
Menu {
id: backgroundContextMenu
objectName: "backgroundContextMenu"
function appendAction() {
let action = actionComponent.createObject(null, { text: qsTr("Extra context menu item") })
backgroundContextMenu.addAction(action)
}
function removeLastAction() {
// TODO: Can't use count here because it's 0: it uses contentModel->count(), but native menu items
// are not Qt Quick items, so we either need to document that you should use contentData.count
// or add an "actions" property. The problem with contentData is that it could contain
// non-Action objects. Another potential issue is that "It is not re-ordered when items are inserted or moved",
// making it unreliable as a general purpose container of actions if users add or remove them dynamically.
backgroundContextMenu.removeAction(backgroundContextMenu.actionAt(backgroundContextMenu.contentData.length - 1))
}
ContextAction {
text: qsTr("Context menu item")
shortcut: "A"
}
ContextMenuItem {
text: qsTr("Checkable context menu item")
checkable: true
}
ContextAction {
text: qsTr("Checked context menu item")
checkable: true
checked: true
shortcut: "C"
}
ContextAction {
text: qsTr("Disabled context menu item")
enabled: false
shortcut: "D"
}
ContextAction {
text: qsTr("Checked and disabled context menu item")
checkable: true
checked: true
enabled: false
shortcut: "E"
}
MenuSeparator {}
Menu {
id: subMenu
title: qsTr("Sub-menu")
objectName: title
function appendAction() {
let action = actionComponent.createObject(null, { text: qsTr("Extra sub-menu item") })
subMenu.addAction(action)
}
function removeLastAction() {
subMenu.removeAction(subMenu.actionAt(subMenu.contentData.length - 1))
}
ContextAction {
text: qsTr("Sub-menu item")
}
ContextAction {
text: qsTr("Checkable sub-menu item")
checkable: true
shortcut: "G"
}
ContextAction {
text: qsTr("Checked sub-menu item")
checkable: true
checked: true
}
MenuSeparator {}
ContextAction {
text: qsTr("Disabled sub-menu item")
enabled: false
shortcut: "I"
}
ContextAction {
text: qsTr("Checked and disabled sub-menu item")
checkable: true
checked: true
enabled: false
shortcut: "J"
}
}
}
Menu {
id: editContextMenu
objectName: "editContextMenu"
ContextAction {
text: qsTr("Cut")
enabled: textArea.selectedText.length > 0
}
ContextAction {
text: qsTr("Copy")
enabled: textArea.selectedText.length > 0
}
ContextAction {
text: qsTr("Paste")
enabled: textArea.activeFocus
}
}
}