Merge pull request #5353 from dmitrio95/palette4-squashed
Palettes redesign, part 4
This commit is contained in:
commit
7b2b7af7ad
26 changed files with 244 additions and 108 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 |
BIN
mscore/qml/palettes/icons/clear.png
Executable file
BIN
mscore/qml/palettes/icons/clear.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 253 B |
Binary file not shown.
Before Width: | Height: | Size: 458 B |
|
@ -19,6 +19,10 @@
|
|||
|
||||
.pragma library
|
||||
|
||||
var style = {
|
||||
popupMargin: 3
|
||||
}
|
||||
|
||||
function stretched(cw, w) {
|
||||
return cw + (w % cw) / Math.floor(w / cw);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue