Merge pull request #5353 from dmitrio95/palette4-squashed

Palettes redesign, part 4
This commit is contained in:
anatoly-os 2019-09-30 22:56:16 +02:00 committed by GitHub
commit 7b2b7af7ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 244 additions and 108 deletions

View file

@ -1783,6 +1783,8 @@ MuseScore::MuseScore()
menuDebug->addAction(a);
a = getAction("relayout");
menuDebug->addAction(a);
a = getAction("qml-reload-source");
menuDebug->addAction(a);
Workspace::addMenuAndString(menuDebug, "menu-debug");
#endif
@ -1973,6 +1975,12 @@ MuseScore::~MuseScore()
autoUpdater->cleanup();
delete synti;
// A crash is possible if paletteWorkspace gets
// deleted before paletteWidget, so force the widget
// be deleted before paletteWorkspace.
delete paletteWidget;
paletteWidget = nullptr;
}
//---------------------------------------------------------
@ -5868,29 +5876,20 @@ void MuseScore::cmd(QAction* a)
}
if (cmdn == "toggle-palette") {
showPalette(a->isChecked());
#if 0
PaletteBox* pb = mscore->getPaletteBox();
QLineEdit* sb = pb->searchBox();
if (a->isChecked()) {
lastFocusWidget = QApplication::focusWidget();
sb->setFocus();
if (pb->noSelection())
pb->setKeyboardNavigation(false);
else
pb->setKeyboardNavigation(true);
paletteWidget->activateSearchBox();
}
else {
if (lastFocusWidget)
lastFocusWidget->setFocus();
}
#endif
return;
}
if (cmdn == "palette-search") {
// TODO: use new search box, or rename command to just "palette"
showPalette(true);
if (paletteWidget)
paletteWidget->setFocus();
paletteWidget->activateSearchBox();
return;
}
if (cmdn == "apply-current-palette-element") {
@ -6449,6 +6448,20 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
cs->update();
}
}
else if (cmd == "qml-reload-source") {
const QList<QmlDockWidget*> qmlWidgets = findChildren<QmlDockWidget*>();
const QString oldPrefix = QmlDockWidget::qmlSourcePrefix();
useSourceQmlFiles = true;
const QString newPrefix = QmlDockWidget::qmlSourcePrefix();
getQmlUiEngine()->clearComponentCache();
for (QmlDockWidget* w : qmlWidgets) {
const QString urlString = w->source().toString().replace(oldPrefix, newPrefix);
w->setSource(QUrl(urlString));
}
}
#endif
else {
if (cv) {

View file

@ -50,7 +50,7 @@ void PaletteCellPropertiesDialog::fillControlsWithData()
ui->yoffset->setValue(cell->yoffset);
ui->scale->setValue(cell->mag);
ui->drawStaff->setChecked(cell->drawStaff);
ui->name->setText(cell->name);
ui->name->setText(cell->translatedName());
}
PaletteCellPropertiesDialog::~PaletteCellPropertiesDialog()
@ -68,13 +68,15 @@ void PaletteCellPropertiesDialog::drawStaffCheckBoxChanged(int state)
{
isDrawStaffCheckBoxChanged = (state != drawStaffCheckboxInitialState);
cell->drawStaff = ui->drawStaff->isChecked();
cell->custom = true;
emit changed();
}
void PaletteCellPropertiesDialog::nameChanged(const QString &text)
{
isNameChanged = (text != initialName);
cell->name = text;
isNameChanged = (text != initialTranslatedName);
cell->name = isNameChanged ? text : initialName; // preserve old name if possible to keep translations
// don't mark cell custom if only its name gets changed
emit changed();
}
@ -83,6 +85,7 @@ void PaletteCellPropertiesDialog::xOffsetChanged(double xOffset)
//see https://doc.qt.io/qt-5/qtglobal.html#qFuzzyCompare to clarify using 1.f below
isXOffsetChanged = !qFuzzyCompare((1.f + xOffset), (1.f + initialXOffset));
cell->xoffset = xOffset;
cell->custom = true;
emit changed();
}
@ -91,6 +94,7 @@ void PaletteCellPropertiesDialog::yOffsetChanged(double yOffset)
//see https://doc.qt.io/qt-5/qtglobal.html#qFuzzyCompare to clarify using 1.f below
isYOffsetChanged = !qFuzzyCompare((1.f + yOffset), (1.f + initialYOffset));
cell->yoffset = yOffset;
cell->custom = true;
emit changed();
}
@ -99,6 +103,7 @@ void PaletteCellPropertiesDialog::scaleChanged(double scale)
//see https://doc.qt.io/qt-5/qtglobal.html#qFuzzyCompare to clarify using 1.f below
isScaleChanged = !qFuzzyCompare((1.f + scale), (1.f + initialScale));
cell->mag = scale;
cell->custom = true;
emit changed();
}
/*
@ -140,9 +145,11 @@ void PaletteCellPropertiesDialog::setInitialProperties()
{
drawStaffCheckboxInitialState = cell->drawStaff ? Qt::Checked : Qt::Unchecked;
initialName = cell->name;
initialTranslatedName = cell->translatedName();
initialYOffset = cell->yoffset;
initialXOffset = cell->xoffset;
initialScale = cell->mag;
initialCustomState = cell->custom;
}
bool PaletteCellPropertiesDialog::areInitialPropertiesChanged() const
@ -157,6 +164,7 @@ void PaletteCellPropertiesDialog::applyInitialPropertiesToThePalette()
cell->xoffset = initialXOffset;
cell->yoffset = initialYOffset;
cell->mag = initialScale;
cell->custom = initialCustomState;
}
} // namespace Ms

View file

@ -53,9 +53,11 @@ class PaletteCellPropertiesDialog : public QDialog {
int drawStaffCheckboxInitialState = 0;
QString initialName;
QString initialTranslatedName;
double initialXOffset = 0.f;
double initialYOffset = 0.f;
double initialScale = 0.f;
bool initialCustomState = false;
public:
PaletteCellPropertiesDialog(PaletteCell* p, QWidget* parent = 0);

View file

@ -65,7 +65,7 @@ PalettePropertiesDialog::~PalettePropertiesDialog()
void PalettePropertiesDialog::fillControlsWithData()
{
ui->name->setText(palette->name());
ui->name->setText(palette->translatedName());
const QSize grid = palette->gridSize();
ui->cellWidth->setValue(grid.width());
ui->cellHeight->setValue(grid.height());
@ -95,8 +95,8 @@ void PalettePropertiesDialog::gridCheckBoxChanged(int state)
void PalettePropertiesDialog::nameChanged(const QString &text)
{
isNameChanged = (text != initialName);
palette->setName(ui->name->text());
isNameChanged = (text != initialTranslatedName);
palette->setName(isNameChanged ? ui->name->text() : initialName); // preserve old name if possible to keep translations
emit changed();
}
@ -168,6 +168,7 @@ void PalettePropertiesDialog::setInitialProperties()
{
gridCheckboxInitialState = palette->drawGrid() ? Qt::Checked : Qt::Unchecked;
initialName = palette->name();
initialTranslatedName = palette->translatedName();
initialWidth = palette->gridSize().width();
initialHeight = palette->gridSize().height();
initialOffset = palette->yOffset();

View file

@ -56,6 +56,7 @@ class PalettePropertiesDialog : public QDialog {
int gridCheckboxInitialState = 0;
QString initialName;
QString initialTranslatedName;
int initialWidth = 0;
int initialHeight = 0;
double initialOffset = 0.f;

View file

@ -227,7 +227,7 @@ QVariant PaletteTreeModel::data(const QModelIndex& index, int role) const
switch (role) {
case Qt::DisplayRole:
case Qt::AccessibleTextRole:
return qApp->translate("Palette", pp->name().toUtf8());
return pp->translatedName();
case VisibleRole:
return pp->visible();
case CustomRole:

View file

@ -159,6 +159,8 @@ class PalettePanel {
const QString& name() const { return _name; }
void setName(const QString& str) { _name = str; }
QString translatedName() const { return qApp->translate("Palette", name().toUtf8()); }
QSize gridSize() const { return _gridSize; }
void setGrid(QSize s) { _gridSize = s; }
void setGrid(int w, int h) { _gridSize = QSize(w, h); }

View file

@ -71,7 +71,7 @@ PaletteWidget::PaletteWidget(PaletteWorkspace* w, QQmlEngine* e, QWidget* parent
setupStyle();
ctx->setContextProperty("mscore", qmlInterface);
setSource(QUrl("qrc:/qml/palettes/PalettesWidget.qml"));
setSource(QUrl(qmlSourcePrefix() + "qml/palettes/PalettesWidget.qml"));
singlePaletteAction = new QAction(this);
singlePaletteAction->setCheckable(true);
@ -121,6 +121,16 @@ void PaletteWidget::setupStyle()
qmlInterface->setPaletteBackground(QColor("#f9f9f9"));
}
//---------------------------------------------------------
// PaletteWidget::activateSearchBox
//---------------------------------------------------------
void PaletteWidget::activateSearchBox()
{
ensureQmlViewFocused();
qmlInterface->requestPaletteSearch();
}
//---------------------------------------------------------
// PaletteWidget::showEvent
//---------------------------------------------------------

View file

@ -48,6 +48,7 @@ class PaletteQmlInterface : public QObject
signals:
void paletteWorkspaceChanged();
void paletteBackgroundChanged();
void paletteSearchRequested();
public:
PaletteQmlInterface(PaletteWorkspace* workspace, QmlNativeToolTip* t, QObject* parent = nullptr);
@ -59,6 +60,8 @@ class PaletteQmlInterface : public QObject
QColor paletteBackground() const { return _paletteBackground; }
void setPaletteBackground(const QColor& val);
void requestPaletteSearch() { emit paletteSearchRequested(); }
Q_INVOKABLE Qt::KeyboardModifiers keyboardModifiers() const { return QGuiApplication::keyboardModifiers(); }
};
@ -87,6 +90,8 @@ class PaletteWidget : public QmlDockWidget
PaletteWidget(PaletteWorkspace* w, QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
PaletteWidget(PaletteWorkspace* w, QQmlEngine* e, QWidget* parent, Qt::WindowFlags flags = Qt::WindowFlags());
void activateSearchBox();
void showEvent(QShowEvent* event) override;
void changeEvent(QEvent* evt) override;
};

View file

@ -298,7 +298,7 @@ AbstractPaletteController::RemoveAction UserPaletteController::showHideOrDeleteD
msg.setText(question);
msg.setTextFormat(Qt::PlainText);
QPushButton* deleteButton = msg.addButton(tr("Delete permanently"), QMessageBox::DestructiveRole);
QPushButton* hideButton = msg.addButton(tr("Keep a copy"), QMessageBox::AcceptRole);
QPushButton* hideButton = msg.addButton(tr("Hide"), QMessageBox::AcceptRole);
msg.addButton(QMessageBox::Cancel);
msg.setDefaultButton(hideButton);
@ -333,7 +333,7 @@ AbstractPaletteController::RemoveAction UserPaletteController::queryRemoveAction
}
if (visible)
return showHideOrDeleteDialog(tr("Do you want to permanently delete this custom palette cell or keep a copy in the library?"));
return showHideOrDeleteDialog(tr("Do you want to hide this custom palette cell or permanently delete it?"));
else {
const auto answer = QMessageBox::question(
nullptr,
@ -351,7 +351,7 @@ AbstractPaletteController::RemoveAction UserPaletteController::queryRemoveAction
}
else {
if (visible && custom)
return showHideOrDeleteDialog(tr("Do you want to permanently delete this custom palette or keep a copy in the \"More Palettes\" list?"));
return showHideOrDeleteDialog(tr("Do you want to hide this custom palette or permanently delete it?"));
return RemoveAction::Hide;
}
}

View file

@ -16,10 +16,9 @@
<file>qml/palettes/utils.js</file>
<file>qml/palettes/icons/arrow_drop_down.png</file>
<file>qml/palettes/icons/arrow_right_black.png</file>
<file>qml/palettes/icons/backspace.png</file>
<file>qml/palettes/icons/clear.png</file>
<file>qml/palettes/icons/delete.png</file>
<file>qml/palettes/icons/more.png</file>
<file>qml/palettes/icons/pin.png</file>
<file>qml/palettes/icons/search.png</file>
</qresource>
</RCC>

View file

@ -33,7 +33,7 @@ class QmlNativeToolTip : public QObject {
Q_PROPERTY(QString text READ text WRITE setText)
QWidget* _widget;
QQuickItem* _item = nullptr;
QPointer<QQuickItem> _item = nullptr;
QString _text;
QString _lastShownText;
QTimer _timer;

View file

@ -49,65 +49,42 @@ StyledPopup {
implicitHeight: column.height + topPadding + bottomPadding
property bool enablePaletteAnimations: false // disabled by default to avoid unnecessary "add" animations on opening this popup at first time
property bool pinned: false
signal addElementsRequested(var mimeDataList)
signal pinPopupRequested(bool pin)
Column {
id: column
width: parent.width
spacing: 8
StyledButton {
id: addToPaletteButton
width: parent.width
Row {
StyledButton {
id: addToPaletteButton
width: column.width - pinButton.width
text: qsTr("Add to %1").arg(paletteName)
enabled: moreElementsPopup.paletteEditingEnabled && (masterPaletteSelectionModel.hasSelection || customPaletteSelectionModel.hasSelection)
text: qsTr("Add to %1").arg(paletteName)
enabled: moreElementsPopup.paletteEditingEnabled && (masterPaletteSelectionModel.hasSelection || customPaletteSelectionModel.hasSelection)
onClicked: {
function collectMimeData(palette, selection) {
const selectedList = selection.selectedIndexes;
var mimeArr = [];
for (var i = 0; i < selectedList.length; i++) {
const mimeData = palette.paletteModel.data(selectedList[i], PaletteTreeModel.MimeDataRole);
mimeArr.push(mimeData);
}
return mimeArr;
onClicked: {
function collectMimeData(palette, selection) {
const selectedList = selection.selectedIndexes;
var mimeArr = [];
for (var i = 0; i < selectedList.length; i++) {
const mimeData = palette.paletteModel.data(selectedList[i], PaletteTreeModel.MimeDataRole);
mimeArr.push(mimeData);
}
const mimeMasterPalette = collectMimeData(masterPalette, masterPaletteSelectionModel);
const mimeCustomPalette = collectMimeData(customPalette, customPaletteSelectionModel);
masterPaletteSelectionModel.clear();
customPaletteSelectionModel.clear();
if (mimeMasterPalette.length)
addElementsRequested(mimeMasterPalette);
if (mimeCustomPalette.length)
addElementsRequested(mimeCustomPalette);
return mimeArr;
}
}
const mimeMasterPalette = collectMimeData(masterPalette, masterPaletteSelectionModel);
const mimeCustomPalette = collectMimeData(customPalette, customPaletteSelectionModel);
StyledToolButton {
id: pinButton
height: addToPaletteButton.height
width: height
checkable: true
checked: moreElementsPopup.pinned
flat: !checked
masterPaletteSelectionModel.clear();
customPaletteSelectionModel.clear();
onCheckedChanged: moreElementsPopup.pinPopupRequested(checked)
padding: 4
contentItem: StyledIcon {
source: "icons/pin.png"
}
if (mimeMasterPalette.length)
addElementsRequested(mimeMasterPalette);
if (mimeCustomPalette.length)
addElementsRequested(mimeCustomPalette);
}
}
@ -178,6 +155,8 @@ StyledPopup {
)
width: parent.contentWidth
ScrollBar.vertical: ScrollBar { enabled: masterPalette.height < masterPalette.implicitHeight }
// TODO: change settings to "hidden" model?
cellSize: moreElementsPopup.cellSize
drawGrid: moreElementsPopup.drawGrid
@ -262,6 +241,12 @@ StyledPopup {
}
}
Item {
// spacer item, adds extra spacing before "drag items..." text
width: 1
height: 2 - column.spacing
}
Text {
id: bottomText
width: parent.width
@ -274,6 +259,12 @@ StyledPopup {
font.pointSize: globalStyle.font.pointSize * 0.8
}
Item {
// spacer item, adds extra spacing after "drag items..." text
width: 1
height: 2 - column.spacing
}
StyledButton {
id: elementEditorButton
visible: moreElementsPopup.elementEditor && moreElementsPopup.elementEditor.valid

View file

@ -142,6 +142,8 @@ GridView {
drawGrid: parent.drawGrid && !parent.empty
offsetX: parent.contentX
offsetY: parent.contentY
cellWidth: parent.cellWidth
cellHeight: parent.cellHeight
DropArea {
id: paletteDropArea
@ -167,7 +169,7 @@ GridView {
if (placeholder.active && placeholder.index == idx)
return;
placeholder.makePlaceholder(idx, { decoration: "#eeeeee", toolTip: "placeholder", cellActive: false, mimeData: {} });
placeholder.makePlaceholder(idx, { decoration: "#eeeeee", toolTip: "placeholder", accessibleText: "", cellActive: false, mimeData: {} });
}
onEntered: {
@ -251,7 +253,7 @@ GridView {
visible: parent.empty
font: globalStyle.font
text: paletteController && paletteController.canDropElements
? qsTr("Drag and drop any element here")
? qsTr("Drag and drop any element here\n(Use %1+Shift to add custom element from the score)").arg(Qt.platform.os === "osx" ? "Cmd" : "Ctrl")
: qsTr("No elements")
verticalAlignment: Text.AlignVCenter
color: "grey"
@ -362,7 +364,7 @@ GridView {
onHoveredChanged: {
if (hovered) {
mscore.tooltip.item = paletteCell;
mscore.tooltip.text = model.toolTip;
mscore.tooltip.text = paletteCell.toolTip ? paletteCell.toolTip : "";
} else if (mscore.tooltip.item == paletteCell)
mscore.tooltip.item = null;
}
@ -436,17 +438,9 @@ GridView {
acceptedButtons: Qt.RightButton
onClicked: {
if (!paletteView.paletteController.canEdit(paletteView.paletteRootIndex))
return;
contextMenu.modelIndex = paletteCell.modelIndex;
if (contextMenu.popup) // Menu.popup() is available since Qt 5.10 only
contextMenu.popup();
else {
contextMenu.x = mouseX;
contextMenu.y = mouseY;
contextMenu.open();
}
contextMenu.canEdit = paletteView.paletteController.canEdit(paletteView.paletteRootIndex);
contextMenu.popup();
}
}
@ -486,8 +480,15 @@ GridView {
Menu {
id: contextMenu
property var modelIndex: null
property bool canEdit: true
MenuItem {
enabled: contextMenu.canEdit
text: qsTr("Delete")
onTriggered: paletteView.paletteController.remove(contextMenu.modelIndex)
}
MenuItem {
enabled: contextMenu.canEdit
text: qsTr("Properties…")
onTriggered: paletteView.paletteController.editCellProperties(contextMenu.modelIndex)
}

View file

@ -22,9 +22,11 @@ import QtQuick.Controls 2.0
Canvas {
property bool drawGrid: false
readonly property real verticalGridWidth: parent.stretchWidth ? (width - (width % parent.cellWidth)) : width
readonly property real verticalGridWidth: parent.stretchWidth ? (width - (width % cellWidth)) : width
property real offsetX: 0.
property real offsetY: 0.
property int cellWidth: 24
property int cellHeight: 24
property color background: mscore.paletteBackground
@ -48,22 +50,32 @@ Canvas {
requestPaint();
}
onCellWidthChanged: {
if (visible && drawGrid)
requestPaint();
}
onCellHeightChanged: {
if (visible && drawGrid)
requestPaint();
}
function doDrawGrid(ctx) {
ctx.lineWidth = 1;
ctx.strokeStyle = "gray";
ctx.beginPath();
const offX = offsetX % parent.cellWidth;
const ncols = Math.ceil((verticalGridWidth - offX) / parent.cellWidth) + (offX ? 1 : 0);
const offX = offsetX % cellWidth;
const ncols = Math.ceil((verticalGridWidth - offX) / cellWidth) + (offX ? 1 : 0);
for (var i = 1; i < ncols; ++i) {
const x = i * parent.cellWidth - offX;
const x = i * cellWidth - offX;
ctx.moveTo(x, 0);
ctx.lineTo(x, height);
}
const offY = offsetY % parent.cellHeight;
const nrows = Math.ceil((height - offY) / parent.cellHeight) + (offY ? 1 : 0);
const offY = offsetY % cellHeight;
const nrows = Math.ceil((height - offY) / cellHeight) + (offY ? 1 : 0);
for (var i = 1; i < nrows; ++i) {
const y = i * parent.cellHeight - offY;
const y = i * cellHeight - offY;
ctx.moveTo(0, y);
ctx.lineTo(width, y);
}

View file

@ -61,7 +61,6 @@ ListView {
}
property var expandedPopupIndex: null // TODO: or use selection model? That would allow to preserve popups on removing palettes
property bool popupPinned: false
onExpandedPopupIndexChanged: {
if (footerItem)
@ -128,7 +127,14 @@ ListView {
NumberAnimation { property: "y"; duration: 150 }
}
ScrollBar.vertical: ScrollBar {}
ScrollBar.vertical: ScrollBar {
id: scrollbar
readonly property color baseColor: (globalStyle.base.hslLightness > 0.5) ? "#28282a" : "#d7d7d5"
readonly property color pressedColor: "#bdbebf"
Component.onCompleted: contentItem.color = Qt.binding(function() { return scrollbar.pressed ? baseColor : "#bdbebf"; })
}
maximumFlickVelocity: 1500
@ -168,6 +174,11 @@ ListView {
paletteSelectionModel.setCurrentIndex(modelIndex, cmd);
paletteTree.currentIndex = index;
}
onDoubleClicked: {
forceActiveFocus();
paletteSelectionModel.setCurrentIndex(modelIndex, ItemSelectionModel.Deselect);
toggleExpand();
}
background: Rectangle {
visible: !control.Drag.active
@ -306,6 +317,8 @@ ListView {
}
custom: model.custom
unresolved: control.DelegateModel.isUnresolved
onToggleExpandRequested: {
paletteTree.currentIndex = control.rowIndex;
control.toggleExpand();
@ -379,15 +392,12 @@ ListView {
visible: control.popupExpanded
maxHeight: Math.min(0.75 * paletteTree.height, 500)
y: mainPaletteContainer.y + mainPaletteContainer.height
y: mainPaletteContainer.y + mainPaletteContainer.height + Utils.style.popupMargin
width: parent.width
modal: false
focus: true
closePolicy: paletteTree.popupPinned ? Popup.NoAutoClose : (Popup.CloseOnEscape | Popup.CloseOnPressOutside | Popup.CloseOnPressOutsideParent)
pinned: paletteTree.popupPinned
onPinPopupRequested: paletteTree.popupPinned = pin
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside | Popup.CloseOnPressOutsideParent
// TODO: change settings to "hidden" model?
cellSize: control.cellSize
@ -459,8 +469,7 @@ ListView {
onHasFocusChanged: {
if (!palettesWidget.hasFocus) {
paletteSelectionModel.clear();
if (!popupPinned)
expandedPopupIndex = null;
expandedPopupIndex = null;
}
}
}

View file

@ -21,6 +21,8 @@ import QtQuick 2.8
import QtQuick.Controls 2.1
import MuseScore.Palette 3.3
import "utils.js" as Utils
Item {
id: header
@ -71,7 +73,7 @@ Item {
flat: true
onClicked: searchTextInput.clear()
padding: 8
padding: 4
text: qsTr("Clear search text")
@ -84,7 +86,7 @@ Item {
}
contentItem: StyledIcon {
source: "icons/backspace.png"
source: "icons/clear.png"
}
}
}
@ -95,7 +97,7 @@ Item {
visible: false
y: morePalettesButton.y + morePalettesButton.height
y: morePalettesButton.y + morePalettesButton.height + Utils.style.popupMargin
width: parent.width
maxHeight: paletteTree.height * 0.8
@ -116,4 +118,9 @@ Item {
palettePopup.visible = false;
}
}
Connections {
target: mscore
onPaletteSearchRequested: searchTextInput.forceActiveFocus()
}
}

View file

@ -45,9 +45,9 @@ ToolButton {
color: button.highlighted || button.visualFocus
? (button.down ? globalStyle.button : Qt.lighter(globalStyle.button, 1.2))
: (button.down ? Qt.darker(globalStyle.button, 1.2) : globalStyle.button)
border {
color: "#aeaeae"
width: button.flat ? 0 : 1
}
// border {
// color: globalStyle.buttonText
// width: 1
// }
}
}

View file

@ -30,6 +30,7 @@ Item {
property bool hidePaletteElementVisible
property bool editingEnabled: true
property bool custom: false
property bool unresolved: false
signal toggleExpandRequested()
signal enableEditingToggled(bool val)
@ -46,7 +47,7 @@ Item {
id: paletteExpandArrow
z: 1000
width: height
visible: paletteHeader.text.length // TODO: make a separate palette placeholder component
visible: !paletteHeader.unresolved // TODO: make a separate palette placeholder component
text: paletteHeader.expanded ? qsTr("Collapse") : qsTr("Expand")
padding: 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

View file

@ -19,6 +19,10 @@
.pragma library
var style = {
popupMargin: 3
}
function stretched(cw, w) {
return cw + (w % cw) / Math.floor(w / cw);
}

View file

@ -27,6 +27,10 @@
namespace Ms {
#ifndef NDEBUG
bool useSourceQmlFiles = false;
#endif
//---------------------------------------------------------
// FocusChainBreak
//---------------------------------------------------------
@ -189,6 +193,16 @@ QQuickView* QmlDockWidget::getView()
return _view;
}
//---------------------------------------------------------
// QmlDockWidget::ensureQmlViewFocused
//---------------------------------------------------------
void QmlDockWidget::ensureQmlViewFocused()
{
if (_view && !_view->activeFocusItem())
widget()->setFocus();
}
//---------------------------------------------------------
// QmlDockWidget::setupStyle
//---------------------------------------------------------
@ -205,6 +219,23 @@ void QmlDockWidget::setupStyle()
rootContext()->setContextProperty("globalStyle", qmlStyle);
}
//---------------------------------------------------------
// QmlDockWidget::qmlSourcePrefix
//---------------------------------------------------------
QString QmlDockWidget::qmlSourcePrefix()
{
#ifndef NDEBUG
if (useSourceQmlFiles) {
const QFileInfo fi(__FILE__);
const QDir mscoreDir = fi.absoluteDir();
return QUrl::fromLocalFile(mscoreDir.absolutePath()).toString() + '/';
}
#endif
static const QString qmlResourcesRoot("qrc:/");
return qmlResourcesRoot;
}
//---------------------------------------------------------
// QmlDockWidget::setSource
//---------------------------------------------------------
@ -219,6 +250,15 @@ void QmlDockWidget::setSource(const QUrl& url)
view->setResizeMode(QQuickView::SizeRootObjectToView);
}
//---------------------------------------------------------
// QmlDockWidget::source
//---------------------------------------------------------
QUrl QmlDockWidget::source() const
{
return _view ? _view->source() : QUrl();
}
//---------------------------------------------------------
// QmlDockWidget::changeEvent
//---------------------------------------------------------
@ -234,5 +274,18 @@ void QmlDockWidget::changeEvent(QEvent* evt)
break;
}
}
}
//---------------------------------------------------------
// QmlDockWidget::resizeEvent
//---------------------------------------------------------
void QmlDockWidget::resizeEvent(QResizeEvent* evt)
{
QDockWidget::resizeEvent(evt);
// update() call prevents QML content from being drawn
// at incorrect position when maximizing/demaximizing
// MuseScore window (Qt 5.9 only?)
if (_view)
_view->update();
}
}

View file

@ -22,6 +22,10 @@
namespace Ms {
#ifndef NDEBUG
extern bool useSourceQmlFiles;
#endif
//---------------------------------------------------------
// FocusChainBreak
//---------------------------------------------------------
@ -127,18 +131,21 @@ class QmlDockWidget : public QDockWidget
protected:
QSize initialViewSize() const { return _view ? _view->initialSize() : QSize(); }
void ensureQmlViewFocused();
public:
QmlDockWidget(QQmlEngine* e = nullptr, QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
QmlDockWidget(QQmlEngine* e, const QString& title, QWidget* parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
static QString qmlSourcePrefix();
void setSource(const QUrl& url);
void source();
QUrl source() const;
QQmlContext* rootContext() { return getView()->rootContext(); }
QQuickItem* rootObject() { return getView()->rootObject(); }
void changeEvent(QEvent* evt) override;
void resizeEvent(QResizeEvent* evt) override;
};
}

View file

@ -3806,6 +3806,16 @@ Shortcut Shortcut::_sc[] = {
Icons::Invalid_ICON,
Qt::ApplicationShortcut
},
{
MsWidget::MAIN_WINDOW,
STATE_ALL,
"qml-reload-source",
"Reload QML code",
"Reload QML code",
0,
Icons::Invalid_ICON,
Qt::ApplicationShortcut
},
#endif
};