forked from qt-creator/qt-creator
QmlDesigner: Add top level toolbar
* Added Designer\TopToolBar=true to .ini to enable toolbar * Added backend to CrumbleBar * Added crumble bar * Added QML toolbar * Disabled original toolbar in DesignModeWidget * Added callback to DesignerActionManager * Added id to ZoomPreviewAction * Dock Manager is exposed in DesignModeWidget * Added new version of icon font Change-Id: I8c8ad16137c84229854a1d0fa6dfdf498edf4253 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
@@ -307,7 +307,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentStateInternalIdChanged: layoutTimer.start()
|
//onCurrentStateInternalIdChanged: layoutTimer.start()
|
||||||
|
|
||||||
StudioControls.Dialog {
|
StudioControls.Dialog {
|
||||||
id: editDialog
|
id: editDialog
|
||||||
@@ -573,6 +573,8 @@ Rectangle {
|
|||||||
y: scrollView.height - height
|
y: scrollView.height - height
|
||||||
width: scrollView.availableWidth
|
width: scrollView.availableWidth
|
||||||
orientation: Qt.Horizontal
|
orientation: Qt.Horizontal
|
||||||
|
active: frame.contentHeight > scrollView.height
|
||||||
|
visible: frame.contentHeight > scrollView.height
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollBar.vertical: StateScrollBar {
|
ScrollBar.vertical: StateScrollBar {
|
||||||
@@ -582,6 +584,8 @@ Rectangle {
|
|||||||
y: scrollView.topPadding
|
y: scrollView.topPadding
|
||||||
height: scrollView.availableHeight
|
height: scrollView.availableHeight
|
||||||
orientation: Qt.Vertical
|
orientation: Qt.Vertical
|
||||||
|
active: frame.contentWidth > scrollView.width
|
||||||
|
visible: frame.contentWidth > scrollView.width
|
||||||
}
|
}
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ T.AbstractButton {
|
|||||||
color: control.style.background.idle
|
color: control.style.background.idle
|
||||||
border.color: control.style.border.idle
|
border.color: control.style.border.idle
|
||||||
border.width: control.style.borderWidth
|
border.width: control.style.borderWidth
|
||||||
|
radius: control.style.radius
|
||||||
}
|
}
|
||||||
|
|
||||||
indicator: Item {
|
indicator: Item {
|
||||||
@@ -77,7 +78,7 @@ T.AbstractButton {
|
|||||||
when: control.enabled && control.pressed
|
when: control.enabled && control.pressed
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: buttonIcon
|
target: buttonIcon
|
||||||
color: control.style.icon.idle
|
color: control.style.icon.interaction
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ T.ComboBox {
|
|||||||
__parentPopup: control.popup
|
__parentPopup: control.popup
|
||||||
x: comboBoxInput.x + comboBoxInput.width
|
x: comboBoxInput.x + comboBoxInput.width
|
||||||
y: control.style.borderWidth
|
y: control.style.borderWidth
|
||||||
width: control.style.baseIconSize.width - control.style.borderWidth
|
width: control.style.squareControlSize.width - control.style.borderWidth
|
||||||
height: control.style.baseIconSize.height - control.style.borderWidth * 2
|
height: control.style.squareControlSize.height - control.style.borderWidth * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
@@ -162,7 +162,7 @@ T.ComboBox {
|
|||||||
: control.style.text.idle
|
: control.style.text.idle
|
||||||
font.family: StudioTheme.Constants.iconFont.family
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
font.pixelSize: control.style.smallIconFontSize
|
font.pixelSize: control.style.smallIconFontSize
|
||||||
visible: control.currentIndex === index ? true : false
|
visible: control.currentIndex === index
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
@@ -261,8 +261,7 @@ T.ComboBox {
|
|||||||
// tab focus. It is therefor possible to use the mouse wheel to scroll through the items.
|
// tab focus. It is therefor possible to use the mouse wheel to scroll through the items.
|
||||||
State {
|
State {
|
||||||
name: "focus"
|
name: "focus"
|
||||||
when: control.enabled && control.activeFocus && !control.editable
|
when: control.enabled && control.activeFocus && !control.editable && !control.open
|
||||||
&& !control.open
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: control
|
target: control
|
||||||
wheelEnabled: true
|
wheelEnabled: true
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ TextInput {
|
|||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "dragHover"
|
name: "dragHover"
|
||||||
when: control.__parentControl.enabled && control.__parentControl.hasActiveHoverDrag
|
when: control.__parentControl.enabled
|
||||||
|
&& (control.__parentControl.hasActiveHoverDrag ?? false)
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: background
|
target: background
|
||||||
color: control.style.background.interaction
|
color: control.style.background.interaction
|
||||||
|
|||||||
@@ -0,0 +1,230 @@
|
|||||||
|
// Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Templates 2.12 as T
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
|
T.ComboBox {
|
||||||
|
id: control
|
||||||
|
|
||||||
|
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
|
||||||
|
|
||||||
|
property bool hover: (comboBoxInput.hover || window.visible) && control.enabled
|
||||||
|
property bool edit: false
|
||||||
|
property bool open: window.visible
|
||||||
|
|
||||||
|
editable: false
|
||||||
|
width: control.style.controlSize.width
|
||||||
|
height: control.style.controlSize.height
|
||||||
|
|
||||||
|
leftPadding: control.style.borderWidth
|
||||||
|
rightPadding: popupIndicator.width + control.style.borderWidth
|
||||||
|
font.pixelSize: control.style.baseFontSize
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
required property int index
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
width: control.width
|
||||||
|
highlighted: control.highlightedIndex === index
|
||||||
|
contentItem: Text {
|
||||||
|
text: modelData
|
||||||
|
color: "#21be2b"
|
||||||
|
font: control.font
|
||||||
|
elide: Text.ElideRight
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indicator: CheckIndicator {
|
||||||
|
id: popupIndicator
|
||||||
|
style: control.style
|
||||||
|
__parentControl: control
|
||||||
|
__parentPopup: comboBoxPopup
|
||||||
|
x: comboBoxInput.x + comboBoxInput.width
|
||||||
|
y: control.style.borderWidth
|
||||||
|
width: control.style.squareControlSize.width - control.style.borderWidth
|
||||||
|
height: control.style.squareControlSize.height - control.style.borderWidth * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: ComboBoxInput {
|
||||||
|
id: comboBoxInput
|
||||||
|
style: control.style
|
||||||
|
__parentControl: control
|
||||||
|
text: control.editText
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
id: comboBoxBackground
|
||||||
|
color: control.style.background.idle
|
||||||
|
border.color: control.style.border.idle
|
||||||
|
border.width: control.style.borderWidth
|
||||||
|
width: control.width
|
||||||
|
height: control.height
|
||||||
|
}
|
||||||
|
|
||||||
|
popup: T.Popup {
|
||||||
|
id: comboBoxPopup
|
||||||
|
width: 0
|
||||||
|
height: 0
|
||||||
|
closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent
|
||||||
|
onAboutToShow: {
|
||||||
|
control.menuDelegate.parent = window.contentItem
|
||||||
|
control.menuDelegate.visible = true
|
||||||
|
|
||||||
|
window.show()
|
||||||
|
window.requestActivate()
|
||||||
|
window.x = control.mapToGlobal(0,0).x
|
||||||
|
window.y = control.mapToGlobal(0,0).y + control.height
|
||||||
|
control.menuDelegate.focus = true
|
||||||
|
}
|
||||||
|
|
||||||
|
onAboutToHide: window.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close popup when application goes to background
|
||||||
|
Connections {
|
||||||
|
target: Qt.application
|
||||||
|
function onStateChanged() {
|
||||||
|
if (Qt.application.state === Qt.ApplicationInactive)
|
||||||
|
comboBoxPopup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: window
|
||||||
|
width: control.menuDelegate.implicitWidth
|
||||||
|
height: control.menuDelegate.implicitHeight
|
||||||
|
visible: false
|
||||||
|
flags: Qt.Popup | Qt.NoDropShadowWindowHint
|
||||||
|
modality: Qt.NonModal
|
||||||
|
transientParent: control.Window.window
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
property Menu menuDelegate: Menu {
|
||||||
|
id: textEditMenu
|
||||||
|
y: 0
|
||||||
|
width: control.width
|
||||||
|
overlap: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: control.model
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
id: menuItem
|
||||||
|
x: 0
|
||||||
|
text: modelData
|
||||||
|
onTriggered: {
|
||||||
|
control.currentIndex = index
|
||||||
|
comboBoxPopup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: textLabel.implicitWidth + menuItem.labelSpacing
|
||||||
|
+ menuItem.leftPadding + menuItem.rightPadding
|
||||||
|
implicitHeight: control.style.controlSize.height
|
||||||
|
x: control.style.borderWidth
|
||||||
|
y: control.style.borderWidth
|
||||||
|
width: menuItem.menu.width - (control.style.borderWidth * 2)
|
||||||
|
height: menuItem.height - (control.style.borderWidth * 2)
|
||||||
|
color: menuItem.highlighted ? control.style.interaction
|
||||||
|
: "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
Text {
|
||||||
|
id: textLabel
|
||||||
|
leftPadding: itemDelegateIconArea.width
|
||||||
|
text: menuItem.text
|
||||||
|
font: control.font
|
||||||
|
color: menuItem.highlighted ? control.style.text.selectedText
|
||||||
|
: control.style.text.idle
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: itemDelegateIconArea
|
||||||
|
width: menuItem.height
|
||||||
|
height: menuItem.height
|
||||||
|
|
||||||
|
T.Label {
|
||||||
|
id: itemDelegateIcon
|
||||||
|
text: StudioTheme.Constants.tickIcon
|
||||||
|
color: textLabel.color
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: control.style.smallIconFontSize
|
||||||
|
visible: control.currentIndex === index
|
||||||
|
anchors.fill: parent
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: control.enabled && !control.hover && !control.edit && !control.open
|
||||||
|
&& !control.activeFocus && !control.hasActiveDrag
|
||||||
|
PropertyChanges {
|
||||||
|
target: control
|
||||||
|
wheelEnabled: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: comboBoxInput
|
||||||
|
selectByMouse: false
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: comboBoxBackground
|
||||||
|
color: control.style.background.idle
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// This state is intended for ComboBoxes which aren't editable, but have focus e.g. via
|
||||||
|
// tab focus. It is therefor possible to use the mouse wheel to scroll through the items.
|
||||||
|
State {
|
||||||
|
name: "focus"
|
||||||
|
when: control.enabled && control.activeFocus && !control.editable && !control.open
|
||||||
|
PropertyChanges {
|
||||||
|
target: control
|
||||||
|
wheelEnabled: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: comboBoxInput
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "popup"
|
||||||
|
when: control.enabled && control.open
|
||||||
|
PropertyChanges {
|
||||||
|
target: control
|
||||||
|
wheelEnabled: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: comboBoxInput
|
||||||
|
selectByMouse: false
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: comboBoxBackground
|
||||||
|
color: control.style.background.interaction
|
||||||
|
border.color: control.style.border.interaction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "disable"
|
||||||
|
when: !control.enabled
|
||||||
|
PropertyChanges {
|
||||||
|
target: comboBoxBackground
|
||||||
|
color: control.style.background.disabled
|
||||||
|
border.color: control.style.border.disabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -49,3 +49,4 @@ TextField 1.0 TextField.qml
|
|||||||
ToolTip 1.0 ToolTip.qml
|
ToolTip 1.0 ToolTip.qml
|
||||||
TranslationIndicator 1.0 TranslationIndicator.qml
|
TranslationIndicator 1.0 TranslationIndicator.qml
|
||||||
VerticalScrollBar 1.0 VerticalScrollBar.qml
|
VerticalScrollBar 1.0 VerticalScrollBar.qml
|
||||||
|
TopLevelComboBox 1.0 TopLevelComboBox.qml
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ QtObject {
|
|||||||
property real bigIconFontSize: Values.bigIconFontSize
|
property real bigIconFontSize: Values.bigIconFontSize
|
||||||
|
|
||||||
property real borderWidth: Values.border
|
property real borderWidth: Values.border
|
||||||
property real radius: 4
|
property real radius: Values.radius
|
||||||
|
|
||||||
property size smallControlSize: Qt.size(Values.smallRectWidth,
|
property size smallControlSize: Qt.size(Values.smallRectWidth,
|
||||||
Values.smallRectWidth)
|
Values.smallRectWidth)
|
||||||
@@ -28,7 +28,6 @@ QtObject {
|
|||||||
|
|
||||||
property size smallIconSize: Qt.size(Values.spinControlIconSizeMulti,
|
property size smallIconSize: Qt.size(Values.spinControlIconSizeMulti,
|
||||||
Values.spinControlIconSizeMulti)
|
Values.spinControlIconSizeMulti)
|
||||||
property size baseIconSize: Qt.size(Values.height, Values.height)
|
|
||||||
|
|
||||||
// TODO only used once
|
// TODO only used once
|
||||||
property size spinBoxIndicatorSize: Qt.size(Values.spinBoxIndicatorWidth,
|
property size spinBoxIndicatorSize: Qt.size(Values.spinBoxIndicatorWidth,
|
||||||
@@ -92,6 +91,7 @@ QtObject {
|
|||||||
component BorderColors: QtObject {
|
component BorderColors: QtObject {
|
||||||
property color idle: Values.themeControlOutline
|
property color idle: Values.themeControlOutline
|
||||||
property color interaction: Values.themeControlOutlineInteraction
|
property color interaction: Values.themeControlOutlineInteraction
|
||||||
|
property color hover: "red"
|
||||||
property color disabled: Values.themeControlOutlineDisabled
|
property color disabled: Values.themeControlOutlineDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
ControlStyle {
|
ControlStyle {
|
||||||
background {
|
controlSize: Qt.size(Values.topLevelComboWidth, Values.topLevelComboHeight)
|
||||||
idle: "red"
|
baseIconFontSize: Values.topLevelComboIcon
|
||||||
}
|
smallIconFontSize: 10
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ QtObject {
|
|||||||
|
|
||||||
property real baseHeight: 29
|
property real baseHeight: 29
|
||||||
|
|
||||||
|
property real topLevelComboWidth: 210
|
||||||
|
property real topLevelComboHeight: 36
|
||||||
|
property real topLevelComboIcon: 20
|
||||||
|
|
||||||
property real smallFont: 8
|
property real smallFont: 8
|
||||||
property real baseFont: 12
|
property real baseFont: 12
|
||||||
property real mediumFont: 14
|
property real mediumFont: 14
|
||||||
@@ -77,6 +81,7 @@ QtObject {
|
|||||||
property real marginTopBottom: 4
|
property real marginTopBottom: 4
|
||||||
property real border: 1
|
property real border: 1
|
||||||
property real borderHover: 3
|
property real borderHover: 3
|
||||||
|
property real radius: 0
|
||||||
|
|
||||||
property real maxComboBoxPopupHeight: Math.round(300 * values.scaleFactor)
|
property real maxComboBoxPopupHeight: Math.round(300 * values.scaleFactor)
|
||||||
property real maxTextAreaPopupHeight: Math.round(150 * values.scaleFactor)
|
property real maxTextAreaPopupHeight: Math.round(150 * values.scaleFactor)
|
||||||
@@ -350,4 +355,24 @@ QtObject {
|
|||||||
|
|
||||||
property ControlStyle controlStyle: DefaultStyle {}
|
property ControlStyle controlStyle: DefaultStyle {}
|
||||||
property ControlStyle toolbarStyle: ToolbarStyle {}
|
property ControlStyle toolbarStyle: ToolbarStyle {}
|
||||||
|
property ControlStyle primaryToolbarStyle: ToolbarStyle {
|
||||||
|
baseIconFontSize: values.baseFontSize
|
||||||
|
radius: 4
|
||||||
|
|
||||||
|
icon: ControlStyle.IconColors {
|
||||||
|
idle: values.themeTextSelectedTextColor
|
||||||
|
disabled: "#636363"
|
||||||
|
}
|
||||||
|
|
||||||
|
background: ControlStyle.BackgroundColors {
|
||||||
|
idle: values.themeInteraction
|
||||||
|
}
|
||||||
|
|
||||||
|
border: ControlStyle.BorderColors {
|
||||||
|
idle: values.themeInteraction
|
||||||
|
hover: "#000000"
|
||||||
|
interaction: "#DCDADA"
|
||||||
|
disabled: "#636363"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
share/qtcreator/qmldesigner/statusbar/Main.qml
Normal file
21
share/qtcreator/qmldesigner/statusbar/Main.qml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: toolbarContainer
|
||||||
|
|
||||||
|
height: 24
|
||||||
|
width: 2024
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
|
||||||
|
color: "#2d2d2d"
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
93
share/qtcreator/qmldesigner/toolbar/CrumbleBar.qml
Normal file
93
share/qtcreator/qmldesigner/toolbar/CrumbleBar.qml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real crumbleWidth: 166
|
||||||
|
property real crumbleHeight: 36
|
||||||
|
|
||||||
|
property real inset: 5
|
||||||
|
property real strokeWidth: 1
|
||||||
|
property real textLeftMargin: 18
|
||||||
|
property real textTopMargin: 6
|
||||||
|
property real textRightMargin: 6
|
||||||
|
property real textBottomMargin: 6
|
||||||
|
|
||||||
|
property alias font: fontMetrics.font
|
||||||
|
|
||||||
|
signal clicked(index: int)
|
||||||
|
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
flickableDirection: Flickable.HorizontalFlick
|
||||||
|
interactive: true
|
||||||
|
|
||||||
|
orientation: ListView.Horizontal
|
||||||
|
clip: true
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
function updateContentX() {
|
||||||
|
root.contentX = (root.contentWidth < root.width) ? 0 : root.contentWidth - root.width
|
||||||
|
}
|
||||||
|
|
||||||
|
onCountChanged: root.updateContentX()
|
||||||
|
onWidthChanged: root.updateContentX()
|
||||||
|
|
||||||
|
visible: root.count > 1 && root.width > (root.crumbleWidth) - 24
|
||||||
|
|
||||||
|
delegate: CrumbleBread {
|
||||||
|
text: fileName
|
||||||
|
tooltip: fileAddress
|
||||||
|
|
||||||
|
width: root.crumbleWidth
|
||||||
|
height: root.crumbleHeight
|
||||||
|
|
||||||
|
inset: root.inset
|
||||||
|
strokeWidth: root.strokeWidth
|
||||||
|
textLeftMargin: root.textLeftMargin
|
||||||
|
textTopMargin: root.textTopMargin
|
||||||
|
textRightMargin: root.textRightMargin
|
||||||
|
textBottomMargin: root.textBottomMargin
|
||||||
|
|
||||||
|
font: root.font
|
||||||
|
|
||||||
|
modelSize: root.count
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (index + 1 < root.count)
|
||||||
|
root.clicked(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "opacity"
|
||||||
|
from: 0
|
||||||
|
to: 1.0
|
||||||
|
duration: 400
|
||||||
|
}
|
||||||
|
NumberAnimation {
|
||||||
|
property: "scale"
|
||||||
|
from: 0
|
||||||
|
to: 1.0
|
||||||
|
duration: 400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displaced: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "x"
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.OutBack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FontMetrics {
|
||||||
|
id: fontMetrics
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.family: "SF Pro"
|
||||||
|
}
|
||||||
|
}
|
||||||
176
share/qtcreator/qmldesigner/toolbar/CrumbleBread.qml
Normal file
176
share/qtcreator/qmldesigner/toolbar/CrumbleBread.qml
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Shapes
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
antialiasing: true
|
||||||
|
|
||||||
|
property int modelSize
|
||||||
|
|
||||||
|
/* Colors might come from Theme */
|
||||||
|
property color idleBackgroundColor: "#2e2f30"
|
||||||
|
property color idleStrokeColor: "#1f1f1f"
|
||||||
|
property color idleTextColor: "#ffffff"
|
||||||
|
property color hoverBackgroundColor: "#434343"
|
||||||
|
property color hoverStrokeColor: "#434343"
|
||||||
|
property color activeColor: "#57b9fc"
|
||||||
|
property color activeTextColor: "#1f1f1f"
|
||||||
|
|
||||||
|
property string tooltip
|
||||||
|
|
||||||
|
property alias text: label.text
|
||||||
|
property alias font: label.font
|
||||||
|
property alias inset: backgroundPath.inset
|
||||||
|
property alias strokeWidth: backgroundPath.strokeWidth
|
||||||
|
|
||||||
|
property real textLeftMargin: 18
|
||||||
|
property real textTopMargin: 6
|
||||||
|
property real textRightMargin: 6
|
||||||
|
property real textBottomMargin: 6
|
||||||
|
|
||||||
|
readonly property int itemIndex: index
|
||||||
|
readonly property bool isFirst: itemIndex === 0
|
||||||
|
readonly property bool isLast: (itemIndex + 1) === modelSize
|
||||||
|
|
||||||
|
signal clicked(int callIdx)
|
||||||
|
|
||||||
|
width: 166
|
||||||
|
height: 36
|
||||||
|
|
||||||
|
Shape {
|
||||||
|
id: backgroundShape
|
||||||
|
anchors.fill: root
|
||||||
|
|
||||||
|
antialiasing: root.antialiasing
|
||||||
|
layer.enabled: antialiasing
|
||||||
|
layer.smooth: antialiasing
|
||||||
|
layer.samples: antialiasing ? 4 : 0
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
id: backgroundPath
|
||||||
|
|
||||||
|
joinStyle: ShapePath.MiterJoin
|
||||||
|
fillColor: root.idleBackgroundColor
|
||||||
|
strokeColor: root.idleStrokeColor
|
||||||
|
strokeWidth: 1
|
||||||
|
|
||||||
|
property real inset: 5
|
||||||
|
property real rightOut: root.isLast ? 0 : root.inset
|
||||||
|
property real leftIn: root.isFirst ? 0 : root.inset
|
||||||
|
property real strokeOffset: backgroundPath.strokeWidth / 2
|
||||||
|
|
||||||
|
property real topY: backgroundPath.strokeOffset
|
||||||
|
property real bottomY: backgroundShape.height - backgroundPath.strokeOffset
|
||||||
|
property real halfY: (backgroundPath.topY + backgroundPath.bottomY) / 2
|
||||||
|
|
||||||
|
startX: backgroundPath.strokeOffset
|
||||||
|
startY: backgroundPath.topY
|
||||||
|
|
||||||
|
PathLine {
|
||||||
|
x: backgroundShape.width - backgroundPath.strokeOffset - backgroundPath.rightOut
|
||||||
|
y: backgroundPath.topY
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundShape.width - backgroundPath.strokeOffset
|
||||||
|
y: backgroundPath.halfY
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundShape.width - backgroundPath.strokeOffset - backgroundPath.rightOut
|
||||||
|
y: backgroundPath.bottomY
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundPath.strokeOffset
|
||||||
|
y: backgroundPath.bottomY
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundPath.leftIn + backgroundPath.strokeOffset
|
||||||
|
y: backgroundPath.halfY
|
||||||
|
}
|
||||||
|
PathLine {
|
||||||
|
x: backgroundPath.strokeOffset
|
||||||
|
y: backgroundPath.topY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: label
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: root.textLeftMargin
|
||||||
|
anchors.topMargin: root.textTopMargin
|
||||||
|
anchors.rightMargin: root.textRightMargin
|
||||||
|
anchors.bottomMargin: root.textBottomMargin
|
||||||
|
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
color: root.idleTextColor
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 1
|
||||||
|
|
||||||
|
text: "Crumble File"
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.family: "SF Pro"
|
||||||
|
|
||||||
|
ToolTip.text: root.tooltip
|
||||||
|
ToolTip.visible: mouseArea.containsMouse
|
||||||
|
ToolTip.delay: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: root.clicked(root.itemIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "idle"
|
||||||
|
when: !mouseArea.containsMouse && !mouseArea.pressed && !root.isLast
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: backgroundPath
|
||||||
|
fillColor: root.idleBackgroundColor
|
||||||
|
strokeColor: root.idleStrokeColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "active"
|
||||||
|
when: root.isLast
|
||||||
|
extend: "pressed"
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hover"
|
||||||
|
when: mouseArea.containsMouse && !mouseArea.pressed
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: backgroundPath
|
||||||
|
fillColor: root.hoverBackgroundColor
|
||||||
|
strokeColor: root.hoverStrokeColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "pressed"
|
||||||
|
when: mouseArea.pressed
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: backgroundPath
|
||||||
|
strokeColor: root.activeColor
|
||||||
|
fillColor: root.activeColor
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: label
|
||||||
|
color: root.activeTextColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
223
share/qtcreator/qmldesigner/toolbar/Main.qml
Normal file
223
share/qtcreator/qmldesigner/toolbar/Main.qml
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
// Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
|
||||||
|
import StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
|
import ToolBar 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: toolbarContainer
|
||||||
|
color: "#2d2d2d"
|
||||||
|
border.color: "#00000000"
|
||||||
|
|
||||||
|
height: 56
|
||||||
|
width: 2024
|
||||||
|
|
||||||
|
ToolBarBackend {
|
||||||
|
id: backend
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: topToolbarOtherMode
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: !backend.isInDesignMode
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: homeOther
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
enabled: backend.isDesignModeEnabled
|
||||||
|
tooltip: qsTr("Switch to Design Mode")
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_designMode
|
||||||
|
|
||||||
|
onClicked: backend.triggerModeChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: topToolbar
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: backend.isInDesignMode
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: home
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_home
|
||||||
|
|
||||||
|
onClicked: backend.triggerModeChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: runProject
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: home.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_runProject
|
||||||
|
style: StudioTheme.ToolbarStyle {
|
||||||
|
icon: StudioTheme.ControlStyle.IconColors {
|
||||||
|
idle: "#649a5d"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: backend.runProject()
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: livePreviewButton
|
||||||
|
style: StudioTheme.Values.primaryToolbarStyle
|
||||||
|
width: 96
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: runProject.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
buttonIcon: qsTr("Live Preview")
|
||||||
|
|
||||||
|
onClicked: livePreview.trigger()
|
||||||
|
|
||||||
|
ActionSubscriber {
|
||||||
|
id: livePreview
|
||||||
|
actionId: "LivePreview"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TopLevelComboBox {
|
||||||
|
id: currentFile
|
||||||
|
style: StudioTheme.Values.toolbarStyle
|
||||||
|
width: 320
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: livePreviewButton.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
model: backend.documentModel
|
||||||
|
currentIndex: backend.documentIndex
|
||||||
|
|
||||||
|
onActivated: backend.openFileByIndex(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: backButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: currentFile.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
enabled: backend.canGoBack
|
||||||
|
tooltip: qsTr("Go Back")
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_navFile
|
||||||
|
iconRotation: 0
|
||||||
|
|
||||||
|
onClicked: backend.goBackward()
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: forwardButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: backButton.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
enabled: backend.canGoForward
|
||||||
|
tooltip: qsTr("Go Forward")
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_navFile
|
||||||
|
iconRotation: 180
|
||||||
|
|
||||||
|
onClicked: backend.goForward()
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: closeButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: forwardButton.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
tooltip: qsTr("Close")
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_closeFile
|
||||||
|
|
||||||
|
onClicked: backend.closeCurrentDocument()
|
||||||
|
}
|
||||||
|
|
||||||
|
CrumbleBar {
|
||||||
|
id: flickable
|
||||||
|
height: 36
|
||||||
|
anchors.left: closeButton.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.right: createComponent.left
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
model: CrumbleBarModel {
|
||||||
|
id: crumbleBarModel
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: crumbleBarModel.onCrumblePathElementClicked(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: createComponent
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: enterComponent.left
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
enabled: moveToComponentBackend.available
|
||||||
|
tooltip: moveToComponentBackend.tooltip
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_makeComponent
|
||||||
|
|
||||||
|
onClicked: moveToComponentBackend.trigger()
|
||||||
|
|
||||||
|
ActionSubscriber {
|
||||||
|
id: moveToComponentBackend
|
||||||
|
actionId: "MakeComponent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: enterComponent
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: workspaces.left
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
enabled: goIntoComponentBackend.available
|
||||||
|
tooltip: goIntoComponentBackend.tooltip
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_enterComponent
|
||||||
|
|
||||||
|
onClicked: goIntoComponentBackend.trigger()
|
||||||
|
|
||||||
|
ActionSubscriber {
|
||||||
|
id: goIntoComponentBackend
|
||||||
|
actionId: "GoIntoComponent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TopLevelComboBox {
|
||||||
|
id: workspaces
|
||||||
|
style: StudioTheme.Values.toolbarStyle
|
||||||
|
width: 210
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: annotations.left
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
model: backend.workspaces
|
||||||
|
onCurrentTextChanged: backend.setCurrentWorkspace(workspaces.currentText)
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: annotations
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: shareButton.left
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
tooltip: qsTr("Edit Annotations")
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_annotations
|
||||||
|
|
||||||
|
onClicked: backend.editGlobalAnnoation()
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolbarButton {
|
||||||
|
id: shareButton
|
||||||
|
style: StudioTheme.Values.primaryToolbarStyle
|
||||||
|
width: 96
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 8
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
buttonIcon: qsTr("Share")
|
||||||
|
|
||||||
|
onClicked: backend.shareApplicationOnline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
share/qtcreator/qmldesigner/toolbar/ToolbarButton.qml
Normal file
24
share/qtcreator/qmldesigner/toolbar/ToolbarButton.qml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import HelperWidgets 2.0
|
||||||
|
|
||||||
|
StudioControls.AbstractButton {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
property alias tooltip: toolTipArea.tooltip
|
||||||
|
|
||||||
|
style: StudioTheme.Values.toolbarStyle
|
||||||
|
hover: toolTipArea.containsMouse
|
||||||
|
|
||||||
|
ToolTipArea {
|
||||||
|
id: toolTipArea
|
||||||
|
anchors.fill: parent
|
||||||
|
// Without setting the acceptedButtons property the clicked event won't
|
||||||
|
// reach the AbstractButton, it will be consumed by the ToolTipArea
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1111,6 +1111,15 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
shortcutwidget.cpp shortcutwidget.h
|
shortcutwidget.cpp shortcutwidget.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
SOURCES_PREFIX components/toolbar
|
||||||
|
SOURCES
|
||||||
|
toolbar.cpp
|
||||||
|
toolbar.h
|
||||||
|
toolbarbackend.cpp
|
||||||
|
toolbarbackend.h
|
||||||
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
CONDITION TARGET Nanotrace
|
CONDITION TARGET Nanotrace
|
||||||
DEPENDS Nanotrace
|
DEPENDS Nanotrace
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
|
|
||||||
#include <nodeabstractproperty.h>
|
#include <nodeabstractproperty.h>
|
||||||
|
#include <toolbar.h>
|
||||||
|
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
@@ -60,6 +61,7 @@ void CrumbleBar::pushFile(const Utils::FilePath &fileName)
|
|||||||
{
|
{
|
||||||
if (!m_isInternalCalled) {
|
if (!m_isInternalCalled) {
|
||||||
crumblePath()->clear();
|
crumblePath()->clear();
|
||||||
|
m_pathes.clear();
|
||||||
} else {
|
} else {
|
||||||
// If the path already exists in crumblePath, pop up to first instance of that to avoid
|
// If the path already exists in crumblePath, pop up to first instance of that to avoid
|
||||||
// cyclical crumblePath
|
// cyclical crumblePath
|
||||||
@@ -71,8 +73,10 @@ void CrumbleBar::pushFile(const Utils::FilePath &fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (match != -1) {
|
if (match != -1) {
|
||||||
for (int i = crumblePath()->length() - 1 - match; i > 0; --i)
|
for (int i = crumblePath()->length() - 1 - match; i > 0; --i) {
|
||||||
crumblePath()->popElement();
|
crumblePath()->popElement();
|
||||||
|
m_pathes.removeLast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,10 +85,13 @@ void CrumbleBar::pushFile(const Utils::FilePath &fileName)
|
|||||||
CrumbleBarInfo crumbleBarInfo;
|
CrumbleBarInfo crumbleBarInfo;
|
||||||
crumbleBarInfo.fileName = fileName;
|
crumbleBarInfo.fileName = fileName;
|
||||||
crumblePath()->pushElement(fileName.fileName(), QVariant::fromValue(crumbleBarInfo));
|
crumblePath()->pushElement(fileName.fileName(), QVariant::fromValue(crumbleBarInfo));
|
||||||
|
m_pathes.append({fileName, fileName.fileName(), {}});
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isInternalCalled = false;
|
m_isInternalCalled = false;
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
|
|
||||||
|
emit pathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrumbleBar::pushInFileComponent(const ModelNode &modelNode)
|
void CrumbleBar::pushInFileComponent(const ModelNode &modelNode)
|
||||||
@@ -97,10 +104,13 @@ void CrumbleBar::pushInFileComponent(const ModelNode &modelNode)
|
|||||||
crumblePath()->popElement();
|
crumblePath()->popElement();
|
||||||
|
|
||||||
crumblePath()->pushElement(crumbleBarInfo.displayName, QVariant::fromValue(crumbleBarInfo));
|
crumblePath()->pushElement(crumbleBarInfo.displayName, QVariant::fromValue(crumbleBarInfo));
|
||||||
|
m_pathes.append({{}, crumbleBarInfo.displayName, modelNode});
|
||||||
|
|
||||||
m_isInternalCalled = false;
|
m_isInternalCalled = false;
|
||||||
|
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
|
|
||||||
|
emit pathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrumbleBar::nextFileIsCalledInternally()
|
void CrumbleBar::nextFileIsCalledInternally()
|
||||||
@@ -120,6 +130,21 @@ Utils::CrumblePath *CrumbleBar::crumblePath()
|
|||||||
return m_crumblePath;
|
return m_crumblePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList CrumbleBar::path() const
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
for (auto &path : m_pathes) {
|
||||||
|
list.append(path.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<CrumbleBarInfo> CrumbleBar::infos() const
|
||||||
|
{
|
||||||
|
return m_pathes;
|
||||||
|
}
|
||||||
|
|
||||||
bool CrumbleBar::showSaveDialog()
|
bool CrumbleBar::showSaveDialog()
|
||||||
{
|
{
|
||||||
bool canceled = false;
|
bool canceled = false;
|
||||||
@@ -151,11 +176,15 @@ void CrumbleBar::onCrumblePathElementClicked(const QVariant &data)
|
|||||||
if (!inlineComp && !showSaveDialog())
|
if (!inlineComp && !showSaveDialog())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (clickedCrumbleBarInfo != crumblePath()->dataForLastIndex().value<CrumbleBarInfo>())
|
while (clickedCrumbleBarInfo != crumblePath()->dataForLastIndex().value<CrumbleBarInfo>()) {
|
||||||
crumblePath()->popElement();
|
crumblePath()->popElement();
|
||||||
|
m_pathes.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
if (crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isValid())
|
if (crumblePath()->dataForLastIndex().value<CrumbleBarInfo>().modelNode.isValid()) {
|
||||||
crumblePath()->popElement();
|
crumblePath()->popElement();
|
||||||
|
m_pathes.removeLast();
|
||||||
|
}
|
||||||
|
|
||||||
m_isInternalCalled = true;
|
m_isInternalCalled = true;
|
||||||
if (inlineComp) {
|
if (inlineComp) {
|
||||||
@@ -164,6 +193,7 @@ void CrumbleBar::onCrumblePathElementClicked(const QVariant &data)
|
|||||||
QmlDesignerPlugin::instance()->viewManager().setComponentViewToMaster();
|
QmlDesignerPlugin::instance()->viewManager().setComponentViewToMaster();
|
||||||
} else {
|
} else {
|
||||||
crumblePath()->popElement();
|
crumblePath()->popElement();
|
||||||
|
m_pathes.removeLast();
|
||||||
nextFileIsCalledInternally();
|
nextFileIsCalledInternally();
|
||||||
Core::EditorManager::openEditor(clickedCrumbleBarInfo.fileName,
|
Core::EditorManager::openEditor(clickedCrumbleBarInfo.fileName,
|
||||||
Utils::Id(),
|
Utils::Id(),
|
||||||
@@ -175,12 +205,14 @@ void CrumbleBar::onCrumblePathElementClicked(const QVariant &data)
|
|||||||
QmlDesignerPlugin::instance()->viewManager().setComponentViewToMaster();
|
QmlDesignerPlugin::instance()->viewManager().setComponentViewToMaster();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
emit pathChanged();
|
||||||
updateVisibility();
|
updateVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrumbleBar::updateVisibility()
|
void CrumbleBar::updateVisibility()
|
||||||
{
|
{
|
||||||
crumblePath()->setVisible(crumblePath()->length() > 1);
|
if (!ToolBar::isVisible())
|
||||||
|
crumblePath()->setVisible(crumblePath()->length() > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==(const CrumbleBarInfo &first, const CrumbleBarInfo &second)
|
bool operator ==(const CrumbleBarInfo &first, const CrumbleBarInfo &second)
|
||||||
|
|||||||
@@ -10,6 +10,24 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class CrumbleBarInfo {
|
||||||
|
public:
|
||||||
|
|
||||||
|
CrumbleBarInfo() = default;
|
||||||
|
|
||||||
|
CrumbleBarInfo(Utils::FilePath f,
|
||||||
|
QString d,
|
||||||
|
ModelNode m) :
|
||||||
|
fileName(f),
|
||||||
|
displayName(d),
|
||||||
|
modelNode(m)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Utils::FilePath fileName;
|
||||||
|
QString displayName;
|
||||||
|
ModelNode modelNode;
|
||||||
|
};
|
||||||
|
|
||||||
class CrumbleBar : public QObject
|
class CrumbleBar : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -24,21 +42,23 @@ public:
|
|||||||
|
|
||||||
Utils::CrumblePath *crumblePath();
|
Utils::CrumblePath *crumblePath();
|
||||||
|
|
||||||
private:
|
QStringList path() const;
|
||||||
|
|
||||||
|
QList<CrumbleBarInfo> infos() const;
|
||||||
|
|
||||||
void onCrumblePathElementClicked(const QVariant &data);
|
void onCrumblePathElementClicked(const QVariant &data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void pathChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
void updateVisibility();
|
void updateVisibility();
|
||||||
bool showSaveDialog();
|
bool showSaveDialog();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_isInternalCalled = false;
|
bool m_isInternalCalled = false;
|
||||||
Utils::CrumblePath *m_crumblePath = nullptr;
|
Utils::CrumblePath *m_crumblePath = nullptr;
|
||||||
};
|
QList<CrumbleBarInfo> m_pathes;
|
||||||
|
|
||||||
class CrumbleBarInfo {
|
|
||||||
public:
|
|
||||||
Utils::FilePath fileName;
|
|
||||||
QString displayName;
|
|
||||||
ModelNode modelNode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator ==(const CrumbleBarInfo &first, const CrumbleBarInfo &second);
|
bool operator ==(const CrumbleBarInfo &first, const CrumbleBarInfo &second);
|
||||||
|
|||||||
@@ -293,6 +293,11 @@ QIcon DesignerActionManager::contextIcon(int contextId) const
|
|||||||
return m_designerIcons->icon(DesignerIcons::IconId(contextId), DesignerIcons::ContextMenuArea);
|
return m_designerIcons->icon(DesignerIcons::IconId(contextId), DesignerIcons::ContextMenuArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DesignerActionManager::addAddActionCallback(ActionAddedInterface callback)
|
||||||
|
{
|
||||||
|
m_callBacks.append(callback);
|
||||||
|
}
|
||||||
|
|
||||||
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
|
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -2051,6 +2056,10 @@ void DesignerActionManager::createDefaultModelNodePreviewImageHandlers()
|
|||||||
void DesignerActionManager::addDesignerAction(ActionInterface *newAction)
|
void DesignerActionManager::addDesignerAction(ActionInterface *newAction)
|
||||||
{
|
{
|
||||||
m_designerActions.append(QSharedPointer<ActionInterface>(newAction));
|
m_designerActions.append(QSharedPointer<ActionInterface>(newAction));
|
||||||
|
|
||||||
|
for (auto callback : m_callBacks) {
|
||||||
|
callback(newAction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManager::addCreatorCommand(Core::Command *command, const QByteArray &category, int priority,
|
void DesignerActionManager::addCreatorCommand(Core::Command *command, const QByteArray &category, int priority,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QGraphicsItem;
|
class QGraphicsItem;
|
||||||
class QGraphicsWidget;
|
class QGraphicsWidget;
|
||||||
@@ -27,6 +29,7 @@ class DesignerIcons;
|
|||||||
|
|
||||||
using AddResourceOperation = std::function<AddFilesResult(const QStringList &, const QString &, bool)>;
|
using AddResourceOperation = std::function<AddFilesResult(const QStringList &, const QString &, bool)>;
|
||||||
using ModelNodePreviewImageOperation = std::function<QVariant(const ModelNode &)>;
|
using ModelNodePreviewImageOperation = std::function<QVariant(const ModelNode &)>;
|
||||||
|
using ActionAddedInterface = std::function<void(ActionInterface*)>;
|
||||||
|
|
||||||
struct AddResourceHandler
|
struct AddResourceHandler
|
||||||
{
|
{
|
||||||
@@ -121,6 +124,8 @@ public:
|
|||||||
QHash<QString, QStringList> handleExternalAssetsDrop(const QMimeData *data) const;
|
QHash<QString, QStringList> handleExternalAssetsDrop(const QMimeData *data) const;
|
||||||
QIcon contextIcon(int contextId) const;
|
QIcon contextIcon(int contextId) const;
|
||||||
|
|
||||||
|
void addAddActionCallback(ActionAddedInterface callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addTransitionEffectAction(const TypeName &typeName);
|
void addTransitionEffectAction(const TypeName &typeName);
|
||||||
void addCustomTransitionEffectAction();
|
void addCustomTransitionEffectAction();
|
||||||
@@ -133,6 +138,7 @@ private:
|
|||||||
QList<ModelNodePreviewImageHandler> m_modelNodePreviewImageHandlers;
|
QList<ModelNodePreviewImageHandler> m_modelNodePreviewImageHandlers;
|
||||||
ExternalDependenciesInterface &m_externalDependencies;
|
ExternalDependenciesInterface &m_externalDependencies;
|
||||||
QScopedPointer<DesignerIcons> m_designerIcons;
|
QScopedPointer<DesignerIcons> m_designerIcons;
|
||||||
|
QList<ActionAddedInterface> m_callBacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
126
src/plugins/qmldesigner/components/toolbar/toolbar.cpp
Normal file
126
src/plugins/qmldesigner/components/toolbar/toolbar.cpp
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "toolbar.h"
|
||||||
|
#include "toolbarbackend.h"
|
||||||
|
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
QmlDesigner::ToolBar::ToolBar()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static Utils::FilePath propertyEditorResourcesPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return Utils::FilePath::fromString(QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources");
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources");
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::FilePath qmlSourcesStatusBarPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return Utils::FilePath::fromString(QLatin1String(SHARE_QML_PATH) + "/statusbar");
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/statusbar");
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::FilePath qmlSourcesPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return Utils::FilePath::fromString(QLatin1String(SHARE_QML_PATH) + "/toolbar");
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/toolbar");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBar::create()
|
||||||
|
{
|
||||||
|
if (!isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ToolBarBackend::registerDeclarativeType();
|
||||||
|
|
||||||
|
auto window = Core::ICore::mainWindow();
|
||||||
|
|
||||||
|
//Core::ICore::statusBar()->hide();
|
||||||
|
|
||||||
|
auto toolBar = new QToolBar;
|
||||||
|
|
||||||
|
toolBar->setFloatable(false);
|
||||||
|
toolBar->setMovable(false);
|
||||||
|
|
||||||
|
auto quickWidget = new QQuickWidget;
|
||||||
|
|
||||||
|
quickWidget->setFixedHeight(48);
|
||||||
|
quickWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
|
quickWidget->setMinimumWidth(200);
|
||||||
|
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
|
||||||
|
quickWidget->engine()->addImportPath(propertyEditorResourcesPath().toString() + "/imports");
|
||||||
|
|
||||||
|
Utils::FilePath qmlFilePath = qmlSourcesPath() / "Main.qml";
|
||||||
|
QTC_ASSERT(qmlFilePath.exists(), return );
|
||||||
|
|
||||||
|
Theme::setupTheme(quickWidget->engine());
|
||||||
|
|
||||||
|
quickWidget->setSource(QUrl::fromLocalFile(qmlFilePath.toFSPathString()));
|
||||||
|
|
||||||
|
toolBar->addWidget(quickWidget);
|
||||||
|
window->addToolBar(toolBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBar::createStatusBar()
|
||||||
|
{
|
||||||
|
if (!isVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ToolBarBackend::registerDeclarativeType();
|
||||||
|
|
||||||
|
auto quickWidget = new QQuickWidget;
|
||||||
|
|
||||||
|
quickWidget->setFixedHeight(24);
|
||||||
|
quickWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
|
quickWidget->setMinimumWidth(200);
|
||||||
|
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
|
||||||
|
quickWidget->engine()->addImportPath(propertyEditorResourcesPath().toString() + "/imports");
|
||||||
|
|
||||||
|
Utils::FilePath qmlFilePath = qmlSourcesStatusBarPath() + QStringLiteral("/Main.qml");
|
||||||
|
QTC_ASSERT(qmlFilePath.exists(), return );
|
||||||
|
|
||||||
|
Theme::setupTheme(quickWidget->engine());
|
||||||
|
|
||||||
|
quickWidget->setSource(QUrl::fromLocalFile(qmlFilePath.toFSPathString()));
|
||||||
|
|
||||||
|
for (QWidget *w : Core::ICore::statusBar()->findChildren<QWidget *>(Qt::FindDirectChildrenOnly)) {
|
||||||
|
w->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::ICore::statusBar()->addWidget(quickWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToolBar::isVisible()
|
||||||
|
{
|
||||||
|
QSettings *settings = Core::ICore::settings();
|
||||||
|
const QString qdsToolbarEntry = "QML/Designer/TopToolBar";
|
||||||
|
|
||||||
|
return settings->value(qdsToolbarEntry, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
21
src/plugins/qmldesigner/components/toolbar/toolbar.h
Normal file
21
src/plugins/qmldesigner/components/toolbar/toolbar.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQuickWidget>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ToolBar : public QQuickWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ToolBar();
|
||||||
|
static void create();
|
||||||
|
static void createStatusBar();
|
||||||
|
static bool isVisible();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
409
src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp
Normal file
409
src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp
Normal file
@@ -0,0 +1,409 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "toolbarbackend.h"
|
||||||
|
|
||||||
|
#include <crumblebar.h>
|
||||||
|
#include <designeractionmanager.h>
|
||||||
|
#include <designmodewidget.h>
|
||||||
|
#include <viewmanager.h>
|
||||||
|
#include <qmldesignerplugin.h>
|
||||||
|
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
#include <coreplugin/coreconstants.h>
|
||||||
|
#include <coreplugin/designmode.h>
|
||||||
|
#include <coreplugin/editormanager/documentmodel.h>
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/modemanager.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
|
#include <qmlprojectmanager/qmlproject.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static Internal::DesignModeWidget *designModeWidget()
|
||||||
|
{
|
||||||
|
return QmlDesignerPlugin::instance()->mainWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DesignDocument *currentDesignDocument()
|
||||||
|
{
|
||||||
|
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
static CrumbleBar *crumbleBar()
|
||||||
|
{
|
||||||
|
return designModeWidget()->crumbleBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Utils::FilePath getMainUiFile()
|
||||||
|
{
|
||||||
|
auto project = ProjectExplorer::SessionManager::startupProject();
|
||||||
|
if (!project)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (!project->activeTarget())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>(
|
||||||
|
project->activeTarget()->buildSystem());
|
||||||
|
return qmlBuildSystem->mainUiFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void openUiFile()
|
||||||
|
{
|
||||||
|
const Utils::FilePath mainUiFile = getMainUiFile();
|
||||||
|
|
||||||
|
if (mainUiFile.completeSuffix() == "ui.qml" && mainUiFile.exists())
|
||||||
|
Core::EditorManager::openEditor(mainUiFile, Utils::Id());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::triggerModeChange()
|
||||||
|
{
|
||||||
|
QTimer::singleShot(0, []() { //Do not trigger mode change directly from QML
|
||||||
|
bool qmlFileOpen = false;
|
||||||
|
|
||||||
|
auto document = Core::EditorManager::currentDocument();
|
||||||
|
|
||||||
|
if (document)
|
||||||
|
qmlFileOpen = document->filePath().fileName().endsWith(".qml");
|
||||||
|
|
||||||
|
if (Core::ModeManager::currentModeId() == Core::Constants::MODE_DESIGN)
|
||||||
|
Core::ModeManager::activateMode(Core::Constants::MODE_WELCOME);
|
||||||
|
else if (qmlFileOpen)
|
||||||
|
Core::ModeManager::activateMode(Core::Constants::MODE_DESIGN);
|
||||||
|
else if (Core::ModeManager::currentModeId() == Core::Constants::MODE_WELCOME)
|
||||||
|
openUiFile();
|
||||||
|
else
|
||||||
|
Core::ModeManager::activateMode(Core::Constants::MODE_WELCOME);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::runProject()
|
||||||
|
{
|
||||||
|
ProjectExplorer::ProjectExplorerPlugin::runStartupProject(
|
||||||
|
ProjectExplorer::Constants::NORMAL_RUN_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::goForward()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(designModeWidget(), return );
|
||||||
|
designModeWidget()->toolBarOnGoForwardClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::goBackward()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(designModeWidget(), return );
|
||||||
|
designModeWidget()->toolBarOnGoBackClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::openFileByIndex(int i)
|
||||||
|
{
|
||||||
|
auto fileName = Core::DocumentModel::entries().at(i)->fileName();
|
||||||
|
|
||||||
|
Core::EditorManager::openEditor(fileName, Utils::Id(), Core::EditorManager::DoNotMakeVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::closeCurrentDocument()
|
||||||
|
{
|
||||||
|
Core::EditorManager::slotCloseCurrentEditorOrDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::shareApplicationOnline()
|
||||||
|
{
|
||||||
|
auto command = Core::ActionManager::command("QmlProject.ShareDesign");
|
||||||
|
if (command)
|
||||||
|
command->action()->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::setCurrentWorkspace(const QString &workspace)
|
||||||
|
{
|
||||||
|
designModeWidget()->dockManager()->openWorkspace(workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::editGlobalAnnoation()
|
||||||
|
{
|
||||||
|
ModelNode node = currentDesignDocument()->rewriterView()->rootModelNode();
|
||||||
|
|
||||||
|
if (node.isValid()) {
|
||||||
|
designModeWidget()->globalAnnotationEditor().setModelNode(node);
|
||||||
|
designModeWidget()->globalAnnotationEditor().showWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToolBarBackend::canGoBack() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(designModeWidget(), return false);
|
||||||
|
return designModeWidget()->canGoBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToolBarBackend::canGoForward() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(designModeWidget(), return false);
|
||||||
|
return designModeWidget()->canGoForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolBarBackend::ToolBarBackend(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
ActionAddedInterface callback = [this](ActionInterface *interface) {
|
||||||
|
if (interface->menuId() == "PreviewZoom")
|
||||||
|
m_zoomAction = interface;
|
||||||
|
};
|
||||||
|
|
||||||
|
QmlDesignerPlugin::instance()->viewManager().designerActionManager().addAddActionCallback(callback);
|
||||||
|
|
||||||
|
connect(designModeWidget(),
|
||||||
|
&Internal::DesignModeWidget::navigationHistoryChanged,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::navigationHistoryChanged);
|
||||||
|
|
||||||
|
connect(Core::DocumentModel::model(),
|
||||||
|
&QAbstractItemModel::rowsInserted,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::updateDocumentModel);
|
||||||
|
connect(Core::DocumentModel::model(),
|
||||||
|
&QAbstractItemModel::rowsRemoved,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::updateDocumentModel);
|
||||||
|
connect(Core::DocumentModel::model(),
|
||||||
|
&QAbstractItemModel::dataChanged,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::updateDocumentModel);
|
||||||
|
connect(Core::DocumentModel::model(),
|
||||||
|
&QAbstractItemModel::modelReset,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::updateDocumentModel);
|
||||||
|
|
||||||
|
connect(Core::EditorManager::instance(),
|
||||||
|
&Core::EditorManager::currentEditorChanged,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::documentIndexChanged);
|
||||||
|
|
||||||
|
connect(designModeWidget(), &Internal::DesignModeWidget::initialized, this, [this]() {
|
||||||
|
const auto dockManager = designModeWidget()->dockManager();
|
||||||
|
|
||||||
|
connect(dockManager,
|
||||||
|
&ADS::DockManager::workspaceListChanged,
|
||||||
|
this,
|
||||||
|
&ToolBarBackend::setupWorkspaces);
|
||||||
|
connect(dockManager, &ADS::DockManager::workspaceLoaded, this, [this](const QString &) {
|
||||||
|
emit currentWorkspaceChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
setupWorkspaces();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto editorManager = Core::EditorManager::instance();
|
||||||
|
|
||||||
|
connect(editorManager, &Core::EditorManager::documentClosed, this, [this]() {
|
||||||
|
if (isInDesignMode() && Core::DocumentModel::entryCount() == 0) {
|
||||||
|
QTimer::singleShot(0, []() { /* The mode change has to happen from event loop.
|
||||||
|
Otherwise we and up in an invalid state */
|
||||||
|
Core::ModeManager::activateMode(Core::Constants::MODE_WELCOME);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(Core::ICore::instance(), &Core::ICore::coreAboutToOpen, this, [this] {
|
||||||
|
connect(Core::DesignMode::instance(), &Core::DesignMode::enabledStateChanged, this, [this] {
|
||||||
|
emit isDesignModeEnabledChanged();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, this, [this]() {
|
||||||
|
emit isInDesignModeChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::registerDeclarativeType()
|
||||||
|
{
|
||||||
|
qmlRegisterType<ToolBarBackend>("ToolBar", 1, 0, "ToolBarBackend");
|
||||||
|
qmlRegisterType<ActionSubscriber>("ToolBar", 1, 0, "ActionSubscriber");
|
||||||
|
qmlRegisterType<CrumbleBarModel>("ToolBar", 1, 0, "CrumbleBarModel");
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList ToolBarBackend::documentModel() const
|
||||||
|
{
|
||||||
|
return m_openDocuments;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::updateDocumentModel()
|
||||||
|
{
|
||||||
|
m_openDocuments.clear();
|
||||||
|
for (auto &entry : Core::DocumentModel::entries())
|
||||||
|
m_openDocuments.append(entry->displayName());
|
||||||
|
|
||||||
|
emit openDocumentsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ToolBarBackend::documentIndex() const
|
||||||
|
{
|
||||||
|
if (Core::EditorManager::currentDocument())
|
||||||
|
return Core::DocumentModel::indexOfDocument(Core::EditorManager::currentDocument()).value();
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ToolBarBackend::currentWorkspace() const
|
||||||
|
{
|
||||||
|
return designModeWidget()->dockManager()->activeWorkspace();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList ToolBarBackend::workspaces() const
|
||||||
|
{
|
||||||
|
return m_workspaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToolBarBackend::isInDesignMode() const
|
||||||
|
{
|
||||||
|
if (!Core::ModeManager::instance())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return Core::ModeManager::currentModeId() == Core::Constants::MODE_DESIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToolBarBackend::isDesignModeEnabled() const
|
||||||
|
{
|
||||||
|
if (Core::DesignMode::instance())
|
||||||
|
return Core::DesignMode::instance()->isEnabled() || getMainUiFile().exists();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBarBackend::setupWorkspaces()
|
||||||
|
{
|
||||||
|
m_workspaces.clear();
|
||||||
|
m_workspaces = designModeWidget()->dockManager()->workspaces();
|
||||||
|
Utils::sort(m_workspaces);
|
||||||
|
emit workspacesChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionSubscriber::ActionSubscriber(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
ActionAddedInterface callback = [this](ActionInterface *interface) {
|
||||||
|
if (interface->menuId() == m_actionId.toLatin1()) {
|
||||||
|
m_interface = interface;
|
||||||
|
setupNotifier();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QmlDesignerPlugin::instance()->viewManager().designerActionManager().addAddActionCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSubscriber::trigger()
|
||||||
|
{
|
||||||
|
if (m_interface)
|
||||||
|
m_interface->action()->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActionSubscriber::available() const
|
||||||
|
{
|
||||||
|
if (m_interface)
|
||||||
|
return m_interface->action()->isEnabled();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActionSubscriber::checked() const
|
||||||
|
{
|
||||||
|
if (m_interface)
|
||||||
|
return m_interface->action()->isChecked();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ActionSubscriber::actionId() const
|
||||||
|
{
|
||||||
|
return m_actionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSubscriber::setActionId(const QString &id)
|
||||||
|
{
|
||||||
|
if (id == m_actionId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_actionId = id;
|
||||||
|
emit actionIdChanged();
|
||||||
|
emit tooltipChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ActionSubscriber::tooltip() const
|
||||||
|
{
|
||||||
|
if (m_interface)
|
||||||
|
return m_interface->action()->text();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionSubscriber::setupNotifier()
|
||||||
|
{
|
||||||
|
if (!m_interface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
connect(m_interface->action(), &QAction::enabledChanged, this, &ActionSubscriber::availableChanged);
|
||||||
|
|
||||||
|
emit tooltipChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
CrumbleBarModel::CrumbleBarModel(QObject *)
|
||||||
|
{
|
||||||
|
connect(crumbleBar(), &CrumbleBar::pathChanged, this, &CrumbleBarModel::handleCrumblePathChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CrumbleBarModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return crumbleBar()->path().count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> CrumbleBarModel::roleNames() const
|
||||||
|
{
|
||||||
|
static QHash<int, QByteArray> roleNames{{Qt::UserRole + 1, "fileName"},
|
||||||
|
{Qt::UserRole + 2, "fileAddress"}};
|
||||||
|
|
||||||
|
return roleNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant CrumbleBarModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (index.isValid() && index.row() < rowCount()) {
|
||||||
|
auto info = crumbleBar()->infos().at(index.row());
|
||||||
|
|
||||||
|
if (role == Qt::UserRole + 1) {
|
||||||
|
return info.displayName;
|
||||||
|
} else if (role == Qt::UserRole + 2) {
|
||||||
|
return info.fileName.displayName();
|
||||||
|
} else {
|
||||||
|
qWarning() << Q_FUNC_INFO << "invalid role";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << Q_FUNC_INFO << "invalid index";
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrumbleBarModel::handleCrumblePathChanged()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrumbleBarModel::onCrumblePathElementClicked(int i)
|
||||||
|
{
|
||||||
|
if (i < rowCount()) {
|
||||||
|
auto info = crumbleBar()->infos().at(i);
|
||||||
|
crumbleBar()->onCrumblePathElementClicked(QVariant::fromValue(info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
129
src/plugins/qmldesigner/components/toolbar/toolbarbackend.h
Normal file
129
src/plugins/qmldesigner/components/toolbar/toolbarbackend.h
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ActionInterface;
|
||||||
|
|
||||||
|
class CrumbleBarModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CrumbleBarModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
void handleCrumblePathChanged();
|
||||||
|
|
||||||
|
Q_INVOKABLE void onCrumblePathElementClicked(int i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionSubscriber : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ActionSubscriber(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
Q_PROPERTY(QString actionId READ actionId WRITE setActionId NOTIFY actionIdChanged)
|
||||||
|
Q_PROPERTY(bool available READ available NOTIFY availableChanged)
|
||||||
|
Q_PROPERTY(bool checked READ checked NOTIFY checkedChanged)
|
||||||
|
Q_PROPERTY(QString tooltip READ tooltip NOTIFY tooltipChanged)
|
||||||
|
|
||||||
|
Q_INVOKABLE void trigger();
|
||||||
|
|
||||||
|
bool available() const;
|
||||||
|
bool checked() const;
|
||||||
|
|
||||||
|
QString actionId() const;
|
||||||
|
void setActionId(const QString &id);
|
||||||
|
|
||||||
|
QString tooltip() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void actionIdChanged();
|
||||||
|
void availableChanged();
|
||||||
|
void checkedChanged();
|
||||||
|
void tooltipChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupNotifier();
|
||||||
|
|
||||||
|
ActionInterface *m_interface = nullptr;
|
||||||
|
QString m_actionId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ToolBarBackend : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationHistoryChanged)
|
||||||
|
Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationHistoryChanged)
|
||||||
|
Q_PROPERTY(QStringList documentModel READ documentModel NOTIFY openDocumentsChanged)
|
||||||
|
Q_PROPERTY(int documentIndex READ documentIndex NOTIFY documentIndexChanged)
|
||||||
|
Q_PROPERTY(QString currentWorkspace READ currentWorkspace NOTIFY currentWorkspaceChanged)
|
||||||
|
Q_PROPERTY(QStringList workspaces READ workspaces NOTIFY workspacesChanged)
|
||||||
|
Q_PROPERTY(bool isInDesignMode READ isInDesignMode NOTIFY isInDesignModeChanged)
|
||||||
|
Q_PROPERTY(bool isDesignModeEnabled READ isDesignModeEnabled NOTIFY isDesignModeEnabledChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ToolBarBackend(QObject *parent = nullptr);
|
||||||
|
static void registerDeclarativeType();
|
||||||
|
|
||||||
|
Q_INVOKABLE void triggerModeChange();
|
||||||
|
Q_INVOKABLE void runProject();
|
||||||
|
Q_INVOKABLE void goForward();
|
||||||
|
Q_INVOKABLE void goBackward();
|
||||||
|
Q_INVOKABLE void openFileByIndex(int i);
|
||||||
|
Q_INVOKABLE void closeCurrentDocument();
|
||||||
|
Q_INVOKABLE void shareApplicationOnline();
|
||||||
|
Q_INVOKABLE void setCurrentWorkspace(const QString &workspace);
|
||||||
|
Q_INVOKABLE void editGlobalAnnoation();
|
||||||
|
|
||||||
|
bool canGoBack() const;
|
||||||
|
bool canGoForward() const;
|
||||||
|
|
||||||
|
QStringList documentModel() const;
|
||||||
|
|
||||||
|
void updateDocumentModel();
|
||||||
|
int documentIndex() const;
|
||||||
|
|
||||||
|
QString currentWorkspace() const;
|
||||||
|
QStringList workspaces() const;
|
||||||
|
|
||||||
|
bool isInDesignMode() const;
|
||||||
|
bool isDesignModeEnabled() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void navigationHistoryChanged();
|
||||||
|
void openDocumentsChanged();
|
||||||
|
void documentIndexChanged();
|
||||||
|
void currentWorkspaceChanged();
|
||||||
|
void workspacesChanged();
|
||||||
|
void isInDesignModeChanged();
|
||||||
|
void isDesignModeEnabledChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupWorkspaces();
|
||||||
|
|
||||||
|
ActionInterface *m_zoomAction;
|
||||||
|
ActionInterface *editAnnotation;
|
||||||
|
ActionInterface *goIntoComponent;
|
||||||
|
ActionInterface *moveToComponent;
|
||||||
|
|
||||||
|
QStringList m_openDocuments;
|
||||||
|
QStringList m_workspaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <nodeinstanceview.h>
|
#include <nodeinstanceview.h>
|
||||||
#include <itemlibrarywidget.h>
|
#include <itemlibrarywidget.h>
|
||||||
#include <theme.h>
|
#include <theme.h>
|
||||||
|
#include <toolbar.h>
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
@@ -341,27 +342,69 @@ void DesignModeWidget::setup()
|
|||||||
mviews->addAction(command);
|
mviews->addAction(command);
|
||||||
|
|
||||||
// Create toolbars
|
// Create toolbars
|
||||||
auto toolBar = new QToolBar();
|
if (!ToolBar::isVisible()) {
|
||||||
|
auto toolBar = new QToolBar();
|
||||||
|
|
||||||
toolBar->addAction(viewManager().componentViewAction());
|
toolBar->addAction(viewManager().componentViewAction());
|
||||||
toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
DesignerActionToolBar *designerToolBar = QmlDesignerPlugin::instance()->viewManager().designerActionManager().createToolBar(m_toolBar);
|
DesignerActionToolBar *designerToolBar = QmlDesignerPlugin::instance()->viewManager().designerActionManager().createToolBar(m_toolBar);
|
||||||
|
|
||||||
designerToolBar->layout()->addWidget(toolBar);
|
designerToolBar->layout()->addWidget(toolBar);
|
||||||
|
|
||||||
m_toolBar->addCenterToolBar(designerToolBar);
|
m_toolBar->addCenterToolBar(designerToolBar);
|
||||||
m_toolBar->setMinimumWidth(320);
|
m_toolBar->setMinimumWidth(320);
|
||||||
m_toolBar->setToolbarCreationFlags(Core::EditorToolBar::FlagsStandalone);
|
m_toolBar->setToolbarCreationFlags(Core::EditorToolBar::FlagsStandalone);
|
||||||
m_toolBar->setNavigationVisible(true);
|
m_toolBar->setNavigationVisible(true);
|
||||||
|
|
||||||
connect(m_toolBar, &Core::EditorToolBar::goForwardClicked, this, &DesignModeWidget::toolBarOnGoForwardClicked);
|
connect(m_toolBar, &Core::EditorToolBar::goForwardClicked, this, &DesignModeWidget::toolBarOnGoForwardClicked);
|
||||||
connect(m_toolBar, &Core::EditorToolBar::goBackClicked, this, &DesignModeWidget::toolBarOnGoBackClicked);
|
connect(m_toolBar, &Core::EditorToolBar::goBackClicked, this, &DesignModeWidget::toolBarOnGoBackClicked);
|
||||||
|
|
||||||
QToolBar* toolBarWrapper = new QToolBar();
|
|
||||||
toolBarWrapper->addWidget(m_toolBar);
|
QToolBar* toolBarWrapper = new QToolBar();
|
||||||
toolBarWrapper->addWidget(createCrumbleBarFrame());
|
toolBarWrapper->addWidget(m_toolBar);
|
||||||
toolBarWrapper->setMovable(false);
|
toolBarWrapper->addWidget(createCrumbleBarFrame());
|
||||||
addToolBar(Qt::TopToolBarArea, toolBarWrapper);
|
toolBarWrapper->setMovable(false);
|
||||||
|
addToolBar(Qt::TopToolBarArea, toolBarWrapper);
|
||||||
|
|
||||||
|
|
||||||
|
addSpacerToToolBar(toolBar);
|
||||||
|
|
||||||
|
auto workspaceComboBox = new QComboBox();
|
||||||
|
workspaceComboBox->setMinimumWidth(120);
|
||||||
|
workspaceComboBox->setToolTip(tr("Switch the active workspace."));
|
||||||
|
auto sortedWorkspaces = m_dockManager->workspaces();
|
||||||
|
Utils::sort(sortedWorkspaces);
|
||||||
|
workspaceComboBox->addItems(sortedWorkspaces);
|
||||||
|
workspaceComboBox->setCurrentText(m_dockManager->activeWorkspace());
|
||||||
|
toolBar->addWidget(workspaceComboBox);
|
||||||
|
|
||||||
|
connect(m_dockManager, &ADS::DockManager::workspaceListChanged,
|
||||||
|
workspaceComboBox, [this, workspaceComboBox]() {
|
||||||
|
workspaceComboBox->clear();
|
||||||
|
auto sortedWorkspaces = m_dockManager->workspaces();
|
||||||
|
Utils::sort(sortedWorkspaces);
|
||||||
|
workspaceComboBox->addItems(sortedWorkspaces);
|
||||||
|
workspaceComboBox->setCurrentText(m_dockManager->activeWorkspace());
|
||||||
|
});
|
||||||
|
connect(m_dockManager, &ADS::DockManager::workspaceLoaded, workspaceComboBox, &QComboBox::setCurrentText);
|
||||||
|
connect(workspaceComboBox, &QComboBox::activated,
|
||||||
|
m_dockManager, [this, workspaceComboBox]([[maybe_unused]] int index) {
|
||||||
|
m_dockManager->openWorkspace(workspaceComboBox->currentText());
|
||||||
|
});
|
||||||
|
|
||||||
|
const QIcon gaIcon = Utils::StyleHelper::getIconFromIconFont(
|
||||||
|
fontName, Theme::getIconUnicode(Theme::Icon::annotationBubble),
|
||||||
|
36, 36, Theme::getColor(Theme::IconsBaseColor));
|
||||||
|
toolBar->addAction(gaIcon, tr("Edit global annotation for current file."), [&](){
|
||||||
|
ModelNode node = currentDesignDocument()->rewriterView()->rootModelNode();
|
||||||
|
|
||||||
|
if (node.isValid()) {
|
||||||
|
m_globalAnnotationEditor.setModelNode(node);
|
||||||
|
m_globalAnnotationEditor.showWidget();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (currentDesignDocument())
|
if (currentDesignDocument())
|
||||||
setupNavigatorHistory(currentDesignDocument()->textEditor());
|
setupNavigatorHistory(currentDesignDocument()->textEditor());
|
||||||
@@ -392,43 +435,6 @@ void DesignModeWidget::setup()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
addSpacerToToolBar(toolBar);
|
|
||||||
|
|
||||||
auto workspaceComboBox = new QComboBox();
|
|
||||||
workspaceComboBox->setMinimumWidth(120);
|
|
||||||
workspaceComboBox->setToolTip(tr("Switch the active workspace."));
|
|
||||||
auto sortedWorkspaces = m_dockManager->workspaces();
|
|
||||||
Utils::sort(sortedWorkspaces);
|
|
||||||
workspaceComboBox->addItems(sortedWorkspaces);
|
|
||||||
workspaceComboBox->setCurrentText(m_dockManager->activeWorkspace());
|
|
||||||
toolBar->addWidget(workspaceComboBox);
|
|
||||||
|
|
||||||
connect(m_dockManager, &ADS::DockManager::workspaceListChanged,
|
|
||||||
workspaceComboBox, [this, workspaceComboBox]() {
|
|
||||||
workspaceComboBox->clear();
|
|
||||||
auto sortedWorkspaces = m_dockManager->workspaces();
|
|
||||||
Utils::sort(sortedWorkspaces);
|
|
||||||
workspaceComboBox->addItems(sortedWorkspaces);
|
|
||||||
workspaceComboBox->setCurrentText(m_dockManager->activeWorkspace());
|
|
||||||
});
|
|
||||||
connect(m_dockManager, &ADS::DockManager::workspaceLoaded, workspaceComboBox, &QComboBox::setCurrentText);
|
|
||||||
connect(workspaceComboBox, &QComboBox::activated,
|
|
||||||
m_dockManager, [this, workspaceComboBox]([[maybe_unused]] int index) {
|
|
||||||
m_dockManager->openWorkspace(workspaceComboBox->currentText());
|
|
||||||
});
|
|
||||||
|
|
||||||
const QIcon gaIcon = Utils::StyleHelper::getIconFromIconFont(
|
|
||||||
fontName, Theme::getIconUnicode(Theme::Icon::annotationBubble),
|
|
||||||
36, 36, Theme::getColor(Theme::IconsBaseColor));
|
|
||||||
toolBar->addAction(gaIcon, tr("Edit global annotation for current file."), [&](){
|
|
||||||
ModelNode node = currentDesignDocument()->rewriterView()->rootModelNode();
|
|
||||||
|
|
||||||
if (node.isValid()) {
|
|
||||||
m_globalAnnotationEditor.setModelNode(node);
|
|
||||||
m_globalAnnotationEditor.showWidget();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
viewManager().enableWidgets();
|
viewManager().enableWidgets();
|
||||||
@@ -500,6 +506,26 @@ void DesignModeWidget::toolBarOnGoForwardClicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DesignModeWidget::canGoForward()
|
||||||
|
{
|
||||||
|
return m_canGoForward;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesignModeWidget::canGoBack()
|
||||||
|
{
|
||||||
|
return m_canGoBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADS::DockManager *DesignModeWidget::dockManager() const
|
||||||
|
{
|
||||||
|
return m_dockManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalAnnotationEditor &DesignModeWidget::globalAnnotationEditor()
|
||||||
|
{
|
||||||
|
return m_globalAnnotationEditor;
|
||||||
|
}
|
||||||
|
|
||||||
DesignDocument *DesignModeWidget::currentDesignDocument() const
|
DesignDocument *DesignModeWidget::currentDesignDocument() const
|
||||||
{
|
{
|
||||||
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
|
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument();
|
||||||
@@ -515,11 +541,14 @@ void DesignModeWidget::setupNavigatorHistory(Core::IEditor *editor)
|
|||||||
if (!m_keepNavigatorHistory)
|
if (!m_keepNavigatorHistory)
|
||||||
addNavigatorHistoryEntry(editor->document()->filePath());
|
addNavigatorHistoryEntry(editor->document()->filePath());
|
||||||
|
|
||||||
const bool canGoBack = m_navigatorHistoryCounter > 0;
|
m_canGoBack = m_navigatorHistoryCounter > 0;
|
||||||
const bool canGoForward = m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1);
|
m_canGoForward = m_navigatorHistoryCounter < (m_navigatorHistory.size() - 1);
|
||||||
m_toolBar->setCanGoBack(canGoBack);
|
m_toolBar->setCanGoBack(m_canGoBack);
|
||||||
m_toolBar->setCanGoForward(canGoForward);
|
m_toolBar->setCanGoForward(m_canGoForward);
|
||||||
m_toolBar->setCurrentEditor(editor);
|
if (!ToolBar::isVisible())
|
||||||
|
m_toolBar->setCurrentEditor(editor);
|
||||||
|
|
||||||
|
emit navigationHistoryChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignModeWidget::addNavigatorHistoryEntry(const Utils::FilePath &fileName)
|
void DesignModeWidget::addNavigatorHistoryEntry(const Utils::FilePath &fileName)
|
||||||
@@ -576,6 +605,8 @@ void DesignModeWidget::initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_initStatus = Initialized;
|
m_initStatus = Initialized;
|
||||||
|
|
||||||
|
emit initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -64,12 +64,23 @@ public:
|
|||||||
|
|
||||||
static QWidget *createProjectExplorerWidget(QWidget *parent);
|
static QWidget *createProjectExplorerWidget(QWidget *parent);
|
||||||
|
|
||||||
private:
|
|
||||||
enum InitializeStatus { NotInitialized, Initializing, Initialized };
|
|
||||||
|
|
||||||
void toolBarOnGoBackClicked();
|
void toolBarOnGoBackClicked();
|
||||||
void toolBarOnGoForwardClicked();
|
void toolBarOnGoForwardClicked();
|
||||||
|
|
||||||
|
bool canGoForward();
|
||||||
|
bool canGoBack();
|
||||||
|
|
||||||
|
ADS::DockManager *dockManager() const;
|
||||||
|
|
||||||
|
GlobalAnnotationEditor &globalAnnotationEditor();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void navigationHistoryChanged();
|
||||||
|
void initialized();
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum InitializeStatus { NotInitialized, Initializing, Initialized };
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
bool isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const;
|
bool isInNodeDefinition(int nodeOffset, int nodeLength, int cursorPos) const;
|
||||||
QmlDesigner::ModelNode nodeForPosition(int cursorPos) const;
|
QmlDesigner::ModelNode nodeForPosition(int cursorPos) const;
|
||||||
@@ -96,6 +107,9 @@ private:
|
|||||||
ADS::DockManager *m_dockManager = nullptr;
|
ADS::DockManager *m_dockManager = nullptr;
|
||||||
ADS::DockWidget *m_outputPaneDockWidget = nullptr;
|
ADS::DockWidget *m_outputPaneDockWidget = nullptr;
|
||||||
GlobalAnnotationEditor m_globalAnnotationEditor;
|
GlobalAnnotationEditor m_globalAnnotationEditor;
|
||||||
|
|
||||||
|
bool m_canGoForward = false;
|
||||||
|
bool m_canGoBack = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "qmldesignerprojectmanager.h"
|
#include "qmldesignerprojectmanager.h"
|
||||||
#include "quick2propertyeditorview.h"
|
#include "quick2propertyeditorview.h"
|
||||||
#include "settingspage.h"
|
#include "settingspage.h"
|
||||||
|
#include <toolbar.h>
|
||||||
|
|
||||||
#include <colortool/colortool.h>
|
#include <colortool/colortool.h>
|
||||||
#include <connectionview.h>
|
#include <connectionview.h>
|
||||||
@@ -92,7 +93,7 @@ public:
|
|||||||
return {"QmlDesigner.Wizards.Enterprise"};
|
return {"QmlDesigner.Wizards.Enterprise"};
|
||||||
}
|
}
|
||||||
QSet<Utils::Id> availablePlatforms() const override { return {}; }
|
QSet<Utils::Id> availablePlatforms() const override { return {}; }
|
||||||
QString displayNameForPlatform(Utils::Id id) const override { return {}; }
|
QString displayNameForPlatform(Utils::Id) const override { return {}; }
|
||||||
};
|
};
|
||||||
|
|
||||||
QString normalizeIdentifier(const QString &string)
|
QString normalizeIdentifier(const QString &string)
|
||||||
@@ -270,6 +271,11 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
Core::AsynchronousMessageBox::warning(composedTitle, description.toString());
|
Core::AsynchronousMessageBox::warning(composedTitle, description.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (QmlProjectManager::QmlProject::isQtDesignStudio()) {
|
||||||
|
ToolBar::create();
|
||||||
|
ToolBar::createStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ QByteArray ZoomPreviewAction::category() const
|
|||||||
|
|
||||||
QByteArray ZoomPreviewAction::menuId() const
|
QByteArray ZoomPreviewAction::menuId() const
|
||||||
{
|
{
|
||||||
return QByteArray();
|
return "PreviewZoom";
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZoomPreviewAction::priority() const
|
int ZoomPreviewAction::priority() const
|
||||||
|
|||||||
Reference in New Issue
Block a user