Merge pull request #9824 from Eism/accessibility_widget_dialogs_part5

[MU4] Accessibility. Master palette
This commit is contained in:
Elnur Ismailzada 2021-11-25 00:30:11 -08:00 committed by GitHub
commit 64da4a2dff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 821 additions and 202 deletions

View file

@ -186,7 +186,10 @@ bool AccessibleItem::accessibleState(State st) const
switch (st) {
case IAccessible::State::Enabled: return true;
case IAccessible::State::Active: return true;
case IAccessible::State::Focused: return accessibleRoot()->focusedElement() == this;
case IAccessible::State::Focused: {
auto root = accessibleRoot();
return root ? root->focusedElement() == this : false;
}
case IAccessible::State::Selected: return m_element->selected();
default:
break;

View file

@ -721,8 +721,8 @@ Score* EngravingObject::score(bool required) const
}
if (required) {
IF_ASSERT_FAILED(sc) {
}
// IF_ASSERT_FAILED(sc) {
// }
}
return sc;

View file

@ -409,6 +409,7 @@ Score::~Score()
qDeleteAll(_parts);
qDeleteAll(_staves);
qDeleteAll(_pages);
_masterScore = 0;
imageStore.clearUnused();

View file

@ -26,6 +26,7 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/iaccessible.h
${CMAKE_CURRENT_LIST_DIR}/iaccessibilitycontroller.h
${CMAKE_CURRENT_LIST_DIR}/iaccessibilityconfiguration.h
${CMAKE_CURRENT_LIST_DIR}/iqaccessibleinterfaceregister.h
${CMAKE_CURRENT_LIST_DIR}/internal/accessibilitycontroller.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/accessibilitycontroller.h
@ -35,6 +36,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/accessibleiteminterface.h
${CMAKE_CURRENT_LIST_DIR}/internal/accessibilityconfiguration.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/accessibilityconfiguration.h
${CMAKE_CURRENT_LIST_DIR}/internal/qaccessibleinterfaceregister.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/qaccessibleinterfaceregister.h
)
include(${PROJECT_SOURCE_DIR}/build/module.cmake)

View file

@ -28,6 +28,7 @@
#include "internal/accessibilitycontroller.h"
#include "internal/accessibilityconfiguration.h"
#include "internal/qaccessibleinterfaceregister.h"
using namespace mu::accessibility;
using namespace mu::modularity;
@ -41,4 +42,16 @@ void AccessibilityModule::registerExports()
{
ioc()->registerExport<IAccessibilityConfiguration>(moduleName(), new AccessibilityConfiguration());
ioc()->registerExport<IAccessibilityController>(moduleName(), std::make_shared<AccessibilityController>());
ioc()->registerExport<IQAccessibleInterfaceRegister>(moduleName(), new QAccessibleInterfaceRegister());
}
void AccessibilityModule::resolveImports()
{
auto accr = ioc()->resolve<IQAccessibleInterfaceRegister>(moduleName());
if (accr) {
#ifdef Q_OS_MAC
accr->registerInterfaceGetter("QQuickWindow", AccessibilityController::accessibleInterface);
#endif
accr->registerInterfaceGetter("mu::accessibility::AccessibleObject", AccessibleObject::accessibleInterface);
}
}

View file

@ -32,6 +32,7 @@ public:
std::string moduleName() const override;
void registerExports() override;
void resolveImports() override;
};
}

View file

@ -41,26 +41,27 @@
using namespace mu::accessibility;
AccessibleObject* s_rootObject = nullptr;
std::shared_ptr<IQAccessibleInterfaceRegister> accessibleInterfaceRegister = nullptr;
AccessibilityController::~AccessibilityController()
{
unreg(this);
}
QAccessibleInterface* AccessibilityController::accessibleInterface(QObject*)
{
return static_cast<QAccessibleInterface*>(new AccessibleItemInterface(s_rootObject));
}
static QAccessibleInterface* muAccessibleFactory(const QString& classname, QObject* object)
{
#ifdef Q_OS_MAC
if (classname == QLatin1String("QQuickWindow")) {
return static_cast<QAccessibleInterface*>(new AccessibleItemInterface(s_rootObject));
if (!accessibleInterfaceRegister) {
accessibleInterfaceRegister = mu::modularity::ioc()->resolve<IQAccessibleInterfaceRegister>("accessibility");
}
#endif
if (classname == QLatin1String("mu::accessibility::AccessibleObject")) {
AccessibleObject* aobj = qobject_cast<AccessibleObject*>(object);
IF_ASSERT_FAILED(aobj) {
return nullptr;
}
return static_cast<QAccessibleInterface*>(new AccessibleItemInterface(aobj));
auto interfaceGetter = accessibleInterfaceRegister->interfaceGetter(classname);
if (interfaceGetter) {
return interfaceGetter(object);
}
return nullptr;

View file

@ -34,7 +34,8 @@
#include "modularity/ioc.h"
#include "ui/imainwindow.h"
#include "ui/iinteractiveprovider.h"
#include "accessibility/iaccessibilityconfiguration.h"
#include "../iaccessibilityconfiguration.h"
#include "../iqaccessibleinterfaceregister.h"
class QAccessibleInterface;
class QAccessibleEvent;
@ -47,14 +48,17 @@ namespace mu::accessibility {
class AccessibilityController : public IAccessibilityController, public IAccessible, public async::Asyncable,
public std::enable_shared_from_this<AccessibilityController>
{
INJECT(accessibility, IAccessibilityConfiguration, configuration)
INJECT(accessibility, ui::IMainWindow, mainWindow)
INJECT(accessibility, ui::IInteractiveProvider, interactiveProvider)
INJECT(accessibility, IAccessibilityConfiguration, configuration)
INJECT_STATIC(accessibility, IQAccessibleInterfaceRegister, accessibleInterfaceRegister)
public:
AccessibilityController() = default;
~AccessibilityController();
static QAccessibleInterface* accessibleInterface(QObject* object);
// IAccessibilityController
void reg(IAccessible* item) override;
void unreg(IAccessible* item) override;

View file

@ -22,6 +22,9 @@
#include "accessibleobject.h"
#include "accessibilitycontroller.h"
#include "accessibleiteminterface.h"
#include "log.h"
using namespace mu::accessibility;
@ -32,6 +35,16 @@ AccessibleObject::AccessibleObject(IAccessible* item)
m_item = item;
}
QAccessibleInterface* AccessibleObject::accessibleInterface(QObject* object)
{
AccessibleObject* accessibleObject = qobject_cast<AccessibleObject*>(object);
IF_ASSERT_FAILED(accessibleObject) {
return nullptr;
}
return static_cast<QAccessibleInterface*>(new AccessibleItemInterface(accessibleObject));
}
void AccessibleObject::setController(std::shared_ptr<AccessibilityController> controller)
{
m_controller = controller;

View file

@ -23,6 +23,7 @@
#define MU_ACCESSIBILITY_ACCESSIBLEOBJECT_H
#include <QObject>
#include <QAccessibleInterface>
#include "../iaccessible.h"
namespace mu::accessibility {
@ -33,6 +34,8 @@ class AccessibleObject : public QObject
public:
explicit AccessibleObject(IAccessible* item);
static QAccessibleInterface* accessibleInterface(QObject* object);
void setController(std::shared_ptr<AccessibilityController> controller);
const std::shared_ptr<AccessibilityController>& controller() const;

View file

@ -0,0 +1,44 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "qaccessibleinterfaceregister.h"
#include "log.h"
using namespace mu::accessibility;
void QAccessibleInterfaceRegister::registerInterfaceGetter(const QString& className, const InterfaceGetter& interfaceGetter)
{
IF_ASSERT_FAILED(!m_interfaceHash.contains(className)) {
LOGW() << "class name " << className << " already register. Will be rewrite";
}
m_interfaceHash[className] = interfaceGetter;
}
IQAccessibleInterfaceRegister::InterfaceGetter QAccessibleInterfaceRegister::interfaceGetter(const QString& className) const
{
if (!m_interfaceHash.contains(className)) {
return InterfaceGetter();
}
return m_interfaceHash[className];
}

View file

@ -0,0 +1,39 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_QACCESSIBLEINTERFACEREGISTER_H
#define MU_UI_QACCESSIBLEINTERFACEREGISTER_H
#include "iqaccessibleinterfaceregister.h"
namespace mu::accessibility {
class QAccessibleInterfaceRegister : public IQAccessibleInterfaceRegister
{
public:
void registerInterfaceGetter(const QString& className, const InterfaceGetter& interfaceGetter) override;
InterfaceGetter interfaceGetter(const QString& className) const override;
private:
QHash<QString, InterfaceGetter> m_interfaceHash;
};
}
#endif // MU_UI_QACCESSIBLEINTERFACEREGISTER_H

View file

@ -0,0 +1,44 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_IQACCESSIBLEINTERFACEREGISTER_H
#define MU_UI_IQACCESSIBLEINTERFACEREGISTER_H
#include "modularity/imoduleexport.h"
#include <QAccessibleInterface>
namespace mu::accessibility {
class IQAccessibleInterfaceRegister : MODULE_EXPORT_INTERFACE
{
INTERFACE_ID(IQAccessibleInterfaceRegister)
public:
virtual ~IQAccessibleInterfaceRegister() = default;
using InterfaceGetter = std::function<QAccessibleInterface* (QObject*)>;
virtual void registerInterfaceGetter(const QString& className, const InterfaceGetter& interfaceGetter) = 0;
virtual InterfaceGetter interfaceGetter(const QString& className) const = 0;
};
}
#endif // MU_UI_IQACCESSIBLEINTERFACEREGISTER_H

View file

@ -55,7 +55,12 @@ void InteractiveProvider::raiseWindowInStack(QObject* newActiveWindow)
}
for (int i = 0; i < m_stack.size(); ++i) {
if (m_stack[i].window == newActiveWindow) {
bool found = m_stack[i].window == newActiveWindow;
if (m_stack[i].window->isWidgetType()) {
found = newActiveWindow->objectName() == (m_stack[i].window->objectName() + "Window");
}
if (found) {
ObjectInfo info = m_stack.takeAt(i);
m_stack.push(info);
notifyAboutCurrentUriChanged();
@ -396,12 +401,6 @@ RetVal<InteractiveProvider::OpenData> InteractiveProvider::openWidgetDialog(cons
fillData(dialog, q);
if (dialog->result()) {
QMetaType::destroy(widgetMetaTypeId, widgetClassPtr);
result.ret = make_ret(Ret::Code::Cancel);
return result;
}
connect(dialog, &QDialog::finished, [this, objectId, dialog](int code) {
QVariantMap status;

View file

@ -1,4 +1,4 @@
/*
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
@ -512,6 +512,11 @@ void UiTheme::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption
} break;
case QStyle::PE_FrameFocusRect: {
bool isTreeWidget = option->styleObject->inherits("QTreeWidget");
if (isTreeWidget) {
drawRoundedRect(painter, option->rect, 1, NO_FILL, QPen(fontPrimaryColor(), navCtrlBorderWidth()));
}
//! NOTE: need for removing frame focus recangle
} break;

View file

@ -2006,7 +2006,7 @@ void NotationInteraction::movePitch(MoveDirection d, PitchMode mode)
}
QList<Note*> el = score()->selection().uniqueNotes();
IF_ASSERT_FAILED(!el.isEmpty()) {
if (el.isEmpty()) {
return;
}

View file

@ -44,8 +44,8 @@ using namespace mu;
using namespace mu::palette;
using namespace Ms;
Palette::Palette(Type t)
: m_type(t)
Palette::Palette(Type t, QObject* parent)
: QObject(parent), m_type(t)
{
static int id = 0;
m_id = QString::number(++id);
@ -90,7 +90,7 @@ PaletteCellPtr Palette::insertElement(size_t idx, ElementPtr element, const QStr
element->layout();
}
PaletteCellPtr cell = std::make_shared<PaletteCell>(element, name, mag);
PaletteCellPtr cell = std::make_shared<PaletteCell>(element, name, mag, this);
auto cellHandler = cellHandlerByPaletteType(m_type);
if (cellHandler) {
@ -108,7 +108,7 @@ PaletteCellPtr Palette::appendElement(ElementPtr element, const QString& name, q
element->layout();
}
PaletteCellPtr cell = std::make_shared<PaletteCell>(element, name, mag);
PaletteCellPtr cell = std::make_shared<PaletteCell>(element, name, mag, this);
auto cellHandler = cellHandlerByPaletteType(m_type);
if (cellHandler) {
@ -257,7 +257,7 @@ bool Palette::read(XmlReader& e)
} else if (tag == "editable") {
m_isEditable = e.readBool();
} else if (tag == "Cell") {
PaletteCellPtr cell = std::make_shared<PaletteCell>();
PaletteCellPtr cell = std::make_shared<PaletteCell>(this);
if (!cell->read(e)) {
continue;
}

View file

@ -44,7 +44,7 @@ namespace mu::palette {
class Palette;
using PalettePtr = std::shared_ptr<Palette>;
class Palette
class Palette : public QObject
{
Q_GADGET
@ -83,7 +83,7 @@ public:
};
Q_ENUM(Type)
explicit Palette(Type t = Type::Custom);
explicit Palette(Type t = Type::Custom, QObject* parent = nullptr);
QString id() const;

View file

@ -31,6 +31,11 @@
#include "engraving/libmscore/textbase.h"
#include "engraving/libmscore/factory.h"
#include "engraving/accessibility/accessibleitem.h"
#include "view/widgets/palettewidget.h"
#include "log.h"
#include "translation.h"
using namespace mu::palette;
@ -56,18 +61,29 @@ static bool needsStaff(ElementPtr e)
}
}
PaletteCell::PaletteCell()
PaletteCell::PaletteCell(QObject* parent)
: QObject(parent)
{
id = makeId();
}
PaletteCell::PaletteCell(ElementPtr e, const QString& _name, qreal _mag)
: element(e), name(_name), mag(_mag)
PaletteCell::PaletteCell(ElementPtr e, const QString& _name, qreal _mag, QObject* parent)
: QObject(parent), element(e), name(_name), mag(_mag)
{
id = makeId();
drawStaff = needsStaff(element);
}
QAccessibleInterface* PaletteCell::accessibleInterface(QObject* object)
{
PaletteCell* cell = qobject_cast<PaletteCell*>(object);
IF_ASSERT_FAILED(cell) {
return nullptr;
}
return static_cast<QAccessibleInterface*>(new AccessiblePaletteCellInterface(cell));
}
QString PaletteCell::makeId()
{
static unsigned int id = 0;
@ -284,3 +300,97 @@ QByteArray PaletteCell::toMimeData() const
{
return Ms::toMimeData(this);
}
AccessiblePaletteCellInterface::AccessiblePaletteCellInterface(PaletteCell* cell)
{
m_cell = cell;
}
bool AccessiblePaletteCellInterface::isValid() const
{
return m_cell != nullptr;
}
QObject* AccessiblePaletteCellInterface::object() const
{
return m_cell;
}
QAccessibleInterface* AccessiblePaletteCellInterface::childAt(int, int) const
{
return nullptr;
}
QAccessibleInterface* AccessiblePaletteCellInterface::parent() const
{
auto paletteWidget = parentWidget();
if (!paletteWidget) {
return nullptr;
}
return QAccessible::queryAccessibleInterface(paletteWidget);
}
QAccessibleInterface* AccessiblePaletteCellInterface::child(int) const
{
return nullptr;
}
int AccessiblePaletteCellInterface::childCount() const
{
return 0;
}
int AccessiblePaletteCellInterface::indexOfChild(const QAccessibleInterface*) const
{
return -1;
}
QString AccessiblePaletteCellInterface::text(QAccessible::Text t) const
{
switch (t) {
case QAccessible::Text::Name:
return m_cell->element->accessibleInfo();
default:
break;
}
return QString();
}
void AccessiblePaletteCellInterface::setText(QAccessible::Text, const QString&)
{
}
QRect AccessiblePaletteCellInterface::rect() const
{
return QRect();
}
QAccessible::Role AccessiblePaletteCellInterface::role() const
{
return QAccessible::ListItem;
}
QAccessible::State AccessiblePaletteCellInterface::state() const
{
QAccessible::State state;
state.invisible = false;
state.invalid = false;
state.disabled = false;
state.focusable = true;
state.focused = m_cell->focused;
return state;
}
QObject* AccessiblePaletteCellInterface::parentWidget() const
{
auto palette = m_cell->parent();
if (!palette) {
return nullptr;
}
return palette->parent();
}

View file

@ -24,6 +24,8 @@
#include "libmscore/engravingitem.h"
#include <QAccessibleInterface>
#include "modularity/ioc.h"
#include "ui/iuiactionsregister.h"
@ -33,31 +35,44 @@ class XmlWriter;
}
namespace mu::palette {
struct PaletteCell;
class PaletteCell;
using PaletteCellPtr = std::shared_ptr<PaletteCell>;
using PaletteCellConstPtr = std::shared_ptr<const PaletteCell>;
struct PaletteCell
class AccessiblePaletteCellInterface : public QAccessibleInterface
{
public:
AccessiblePaletteCellInterface(PaletteCell* cell);
bool isValid() const override;
QObject* object() const override;
QAccessibleInterface* childAt(int x, int y) const override;
QAccessibleInterface* parent() const override;
QAccessibleInterface* child(int index) const override;
int childCount() const override;
int indexOfChild(const QAccessibleInterface*) const override;
QString text(QAccessible::Text t) const override;
void setText(QAccessible::Text t, const QString& text) override;
QRect rect() const override;
QAccessible::Role role() const override;
QAccessible::State state() const override;
private:
QObject* parentWidget() const;
PaletteCell* m_cell = nullptr;
};
class PaletteCell : public QObject
{
Q_OBJECT
INJECT_STATIC(palette, mu::ui::IUiActionsRegister, actionsRegister)
explicit PaletteCell();
PaletteCell(Ms::ElementPtr e, const QString& _name, qreal _mag = 1.0);
public:
explicit PaletteCell(QObject* parent = nullptr);
PaletteCell(Ms::ElementPtr e, const QString& _name, qreal _mag = 1.0, QObject* parent = nullptr);
Ms::ElementPtr element;
Ms::ElementPtr untranslatedElement;
QString id;
QString name; // used for tool tip
bool drawStaff { false };
double xoffset { 0.0 }; // in spatium units of "gscore"
double yoffset { 0.0 };
qreal mag { 1.0 };
bool readOnly { false };
bool visible { true };
bool custom { false };
bool active { false };
static QAccessibleInterface* accessibleInterface(QObject* object);
static constexpr const char* mimeDataFormat = "application/musescore/palette/cell";
@ -74,6 +89,23 @@ struct PaletteCell
static PaletteCellPtr fromMimeData(const QByteArray& data);
static PaletteCellPtr fromElementMimeData(const QByteArray& data);
Ms::ElementPtr element;
Ms::ElementPtr untranslatedElement;
QString id;
QString name; // used for tool tip
bool drawStaff { false };
double xoffset { 0.0 }; // in spatium units of "gscore"
double yoffset { 0.0 };
qreal mag { 1.0 };
bool readOnly { false };
bool visible { true };
bool custom { false };
bool active { false };
bool focused { false };
private:
static QString makeId();
};

View file

@ -94,34 +94,19 @@ void PaletteElementEditor::open()
return;
}
QWidget* editor = nullptr;
using Type = Palette::Type;
switch (_type) {
case Type::KeySig: {
KeyEditor* keyEditor = new KeyEditor();
keyEditor->showKeyPalette(false);
connect(keyEditor, &KeyEditor::keySigAdded, this, &PaletteElementEditor::onElementAdded);
editor = keyEditor;
interactive()->open("musescore://notation/keysignatures?sync=false&showKeyPalette=false");
}
break;
case Type::TimeSig: {
TimeDialog* timeEditor = new TimeDialog();
timeEditor->showTimePalette(false);
connect(timeEditor, &TimeDialog::timeSigAdded, this, &PaletteElementEditor::onElementAdded);
editor = timeEditor;
interactive()->open("musescore://notation/timesignatures?sync=false&showTimePalette=false");
}
break;
default:
break;
}
if (!editor) {
return;
}
editor->setAttribute(Qt::WA_DeleteOnClose);
editor->show();
}
// ========================================================

View file

@ -30,12 +30,14 @@
#include "ui/iuiengine.h"
#include "ui/iinteractiveuriregister.h"
#include "ui/iuiactionsregister.h"
#include "accessibility/iqaccessibleinterfaceregister.h"
#include "internal/paletteconfiguration.h"
#include "internal/paletteuiactions.h"
#include "internal/paletteactionscontroller.h"
#include "internal/paletteworkspacesetup.h"
#include "internal/paletteprovider.h"
#include "internal/palettecell.h"
#include "view/paletterootmodel.h"
#include "view/palettepropertiesmodel.h"
@ -46,10 +48,13 @@
#include "view/widgets/specialcharactersdialog.h"
#include "view/widgets/editdrumsetdialog.h"
#include "view/widgets/timesignaturepropertiesdialog.h"
#include "view/widgets/keyedit.h"
#include "view/widgets/timedialog.h"
using namespace mu::palette;
using namespace mu::modularity;
using namespace mu::ui;
using namespace mu::accessibility;
static std::shared_ptr<Ms::PaletteProvider> s_paletteProvider = std::make_shared<Ms::PaletteProvider>();
static std::shared_ptr<PaletteActionsController> s_actionsController = std::make_shared<PaletteActionsController>();
@ -99,6 +104,18 @@ void PaletteModule::resolveImports()
ir->registerUri(Uri("musescore://palette/cellproperties"),
ContainerMeta(ContainerType::QmlDialog, "MuseScore/Palette/PaletteCellPropertiesDialog.qml"));
ir->registerUri(Uri("musescore://notation/keysignatures"),
ContainerMeta(ContainerType::QWidgetDialog, qRegisterMetaType<Ms::KeyEditor>("KeySignaturesDialog")));
ir->registerUri(Uri("musescore://notation/timesignatures"),
ContainerMeta(ContainerType::QWidgetDialog, qRegisterMetaType<Ms::TimeDialog>("TimeSignaturesDialog")));
}
auto accr = ioc()->resolve<IQAccessibleInterfaceRegister>(moduleName());
if (accr) {
accr->registerInterfaceGetter("mu::palette::PaletteWidget", PaletteWidget::accessibleInterface);
accr->registerInterfaceGetter("mu::palette::PaletteCell", PaletteCell::accessibleInterface);
}
}

View file

@ -313,7 +313,11 @@ StyledPopupView {
navigation.name: "elementEditorButton"
navigation.column: 1
navigation.row: 101 // after deleteButton
onClicked: root.elementEditor.open()
onClicked: {
root.elementEditor.open()
Qt.callLater(root.close)
}
}
}
}

View file

@ -472,7 +472,10 @@ bool PaletteTreeModel::setData(const QModelIndex& index, const QVariant& value,
if (!newCell) {
return false;
}
*cell = *newCell;
cell->element = newCell->element;
cell->untranslatedElement = newCell->untranslatedElement;
cell->name = newCell->name;
cell->id = newCell->id;
emit dataChanged(index, index);
return true;
};
@ -505,10 +508,20 @@ bool PaletteTreeModel::setData(const QModelIndex& index, const QVariant& value,
if (!newCell) {
return false;
}
*cell = *newCell;
cell->element = newCell->element;
cell->untranslatedElement = newCell->untranslatedElement;
cell->name = newCell->name;
cell->id = newCell->id;
} else if (map.contains(mu::commonscene::MIME_SYMBOL_FORMAT)) {
const QByteArray elementMimeData = map[mu::commonscene::MIME_SYMBOL_FORMAT].toByteArray();
*cell = *PaletteCell::fromElementMimeData(elementMimeData);
PaletteCellPtr newCell = PaletteCell::fromElementMimeData(elementMimeData);
cell->element = newCell->element;
cell->untranslatedElement = newCell->untranslatedElement;
cell->name = newCell->name;
cell->id = newCell->id;
cell->custom = true; // mark the updated cell custom
} else {
return false;
@ -837,7 +850,7 @@ bool PaletteTreeModel::insertRows(int row, int count, const QModelIndex& parent)
beginInsertRows(parent, row, row + count - 1);
for (int i = 0; i < count; ++i) {
PaletteCellPtr cell = std::make_shared<PaletteCell>();
PaletteCellPtr cell = std::make_shared<PaletteCell>(palette);
palette->insertCell(row, cell);
}
endInsertRows();

View file

@ -259,7 +259,14 @@ EditDrumsetDialog::EditDrumsetDialog(QWidget* parent)
Q_ASSERT(pitchList->topLevelItemCount() > 0);
pitchList->setCurrentItem(pitchList->topLevelItem(0));
pitchList->setFocus();
quarterCmb->setAccessibleName(quarterLbl->text() + " " + quarterCmb->currentText());
halfCmb->setAccessibleName(halfLbl->text() + " " + halfCmb->currentText());
wholeCmb->setAccessibleName(wholeLbl->text() + " " + wholeCmb->currentText());
doubleWholeCmb->setAccessibleName(doubleWholeLbl->text() + " " + doubleWholeCmb->currentText());
//! NOTE: It is necessary for the correct start of navigation in the dialog
setFocus();
}
EditDrumsetDialog::EditDrumsetDialog(const EditDrumsetDialog& other)

View file

@ -91,6 +91,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>name</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
@ -108,6 +111,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>noteHead</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
@ -130,6 +136,9 @@
<property name="text">
<string>Quarter note</string>
</property>
<property name="buddy">
<cstring>quarterCmb</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
@ -140,6 +149,9 @@
<property name="text">
<string>Half note</string>
</property>
<property name="buddy">
<cstring>halfCmb</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
@ -150,6 +162,9 @@
<property name="text">
<string>Whole note</string>
</property>
<property name="buddy">
<cstring>wholeCmb</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
@ -160,6 +175,9 @@
<property name="text">
<string>Double whole note</string>
</property>
<property name="buddy">
<cstring>doubleWholeCmb</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
@ -222,6 +240,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>voice</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
@ -262,6 +283,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>staffLine</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
@ -285,6 +309,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>shortcut</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
@ -345,6 +372,9 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>stemDirection</cstring>
</property>
</widget>
</item>
<item row="3" column="1">

View file

@ -45,6 +45,8 @@
#include "palettewidget.h"
#include "internal/palettecreator.h"
#include "log.h"
using namespace mu;
using namespace mu::engraving;
using namespace mu::palette;
@ -288,53 +290,69 @@ KeyEditor::KeyEditor(QWidget* parent)
setupUi(this);
setWindowTitle(mu::qtrc("palette", "Key signatures"));
QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// create key signature palette
QLayout* l = new QVBoxLayout();
l->setContentsMargins(0, 0, 0, 0);
frame->setLayout(l);
QLayout* layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
keySigframe->setLayout(layout);
sp = new PaletteWidget(PaletteCreator::newKeySigPalette(), this);
sp->setReadOnly(false);
m_keySigPaletteWidget = new PaletteWidget(this);
m_keySigPaletteWidget->setPalette(PaletteCreator::newKeySigPalette());
m_keySigPaletteWidget->setReadOnly(false);
_keyPalette = new PaletteScrollArea(sp);
QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_keyPalette->setSizePolicy(policy);
_keyPalette->setRestrictHeight(false);
m_keySigArea = new PaletteScrollArea(m_keySigPaletteWidget);
m_keySigArea->setSizePolicy(policy);
m_keySigArea->setRestrictHeight(false);
m_keySigArea->setFocusProxy(m_keySigPaletteWidget);
m_keySigArea->setFocusPolicy(Qt::TabFocus);
l->addWidget(_keyPalette);
layout->addWidget(m_keySigArea);
// create accidental palette
l = new QVBoxLayout();
l->setContentsMargins(0, 0, 0, 0);
frame_3->setLayout(l);
sp1 = new PaletteWidget(PaletteCreator::newAccidentalsPalette(), this);
qreal adj = sp1->mag();
sp1->setGridSize(sp1->gridWidth() / adj, sp1->gridHeight() / adj);
sp1->setMag(1.0);
PaletteScrollArea* accPalette = new PaletteScrollArea(sp1);
QSizePolicy policy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
accPalette->setSizePolicy(policy1);
accPalette->setRestrictHeight(false);
layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
accidentalsFrame->setLayout(layout);
l->addWidget(accPalette);
m_accidentalsPaletteWidget = new PaletteWidget(this);
m_accidentalsPaletteWidget->setPalette(PaletteCreator::newAccidentalsPalette());
qreal adj = m_accidentalsPaletteWidget->mag();
m_accidentalsPaletteWidget->setGridSize(m_accidentalsPaletteWidget->gridWidth() / adj, m_accidentalsPaletteWidget->gridHeight() / adj);
m_accidentalsPaletteWidget->setMag(1.0);
PaletteScrollArea* accidentalsPaletteArea = new PaletteScrollArea(m_accidentalsPaletteWidget);
accidentalsPaletteArea->setSizePolicy(policy);
accidentalsPaletteArea->setRestrictHeight(false);
accidentalsPaletteArea->setFocusProxy(m_accidentalsPaletteWidget);
accidentalsPaletteArea->setFocusPolicy(Qt::TabFocus);
layout->addWidget(accidentalsPaletteArea);
connect(addButton, &QPushButton::clicked, this, &KeyEditor::addClicked);
connect(clearButton, &QPushButton::clicked, this, &KeyEditor::clearClicked);
connect(sp, &PaletteWidget::changed, this, &KeyEditor::setDirty);
connect(m_keySigPaletteWidget, &PaletteWidget::changed, this, &KeyEditor::setDirty);
//
// set all "buildin" key signatures to read only
//
int n = sp->actualCellCount();
int n = m_keySigPaletteWidget->actualCellCount();
for (int i = 0; i < n; ++i) {
sp->setCellReadOnly(i, true);
m_keySigPaletteWidget->setCellReadOnly(i, true);
}
if (!configuration()->useFactorySettings()) {
sp->readFromFile(configuration()->keySignaturesDirPath().toQString());
m_keySigPaletteWidget->readFromFile(configuration()->keySignaturesDirPath().toQString());
}
//! NOTE: It is necessary for the correct start of navigation in the dialog
setFocus();
}
KeyEditor::KeyEditor(const KeyEditor& widget)
: KeyEditor(widget.parentWidget())
{
}
//---------------------------------------------------------
@ -366,8 +384,8 @@ void KeyEditor::addClicked()
}
auto ks = Factory::makeKeySig(gpaletteScore->dummy()->segment());
ks->setKeySigEvent(e);
sp->appendElement(ks, "custom");
_dirty = true;
m_keySigPaletteWidget->appendElement(ks, "custom");
m_dirty = true;
emit keySigAdded(ks);
}
@ -384,9 +402,9 @@ void KeyEditor::clearClicked()
// showKeyPalette
//---------------------------------------------------------
void KeyEditor::showKeyPalette(bool val)
void KeyEditor::setShowKeyPalette(bool showKeyPalette)
{
_keyPalette->setVisible(val);
m_keySigArea->setVisible(showKeyPalette);
}
//---------------------------------------------------------
@ -397,5 +415,10 @@ void KeyEditor::save()
{
QDir dir;
dir.mkpath(configuration()->keySignaturesDirPath().toQString());
sp->writeToFile(configuration()->keySignaturesDirPath().toQString());
m_keySigPaletteWidget->writeToFile(configuration()->keySignaturesDirPath().toQString());
}
bool KeyEditor::showKeyPalette() const
{
return m_keySigArea->isVisible();
}

View file

@ -39,26 +39,36 @@ class KeyEditor : public QWidget, Ui::KeyEdit
{
Q_OBJECT
Q_PROPERTY(bool showKeyPalette READ showKeyPalette WRITE setShowKeyPalette)
INJECT(palette, mu::palette::IPaletteConfiguration, configuration)
mu::palette::PaletteScrollArea* _keyPalette = nullptr;
mu::palette::PaletteWidget* sp = nullptr;
mu::palette::PaletteWidget* sp1 = nullptr;
bool _dirty = false;
public:
KeyEditor(QWidget* parent = 0);
KeyEditor(const KeyEditor& widget);
bool dirty() const { return m_dirty; }
void save();
bool showKeyPalette() const;
public slots:
void setShowKeyPalette(bool showKeyPalette);
private slots:
void addClicked();
void clearClicked();
void setDirty() { _dirty = true; }
void setDirty() { m_dirty = true; }
signals:
void keySigAdded(const std::shared_ptr<KeySig>);
public:
KeyEditor(QWidget* parent = 0);
bool dirty() const { return _dirty; }
void showKeyPalette(bool val);
void save();
private:
mu::palette::PaletteScrollArea* m_keySigArea = nullptr;
mu::palette::PaletteWidget* m_keySigPaletteWidget = nullptr;
mu::palette::PaletteWidget* m_accidentalsPaletteWidget = nullptr;
bool m_dirty = false;
};
} // namespace Ms
#endif

View file

@ -19,7 +19,7 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QFrame" name="frame">
<widget class="QFrame" name="keySigframe">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -67,7 +67,7 @@
</widget>
</item>
<item>
<widget class="QFrame" name="frame_3">
<widget class="QFrame" name="accidentalsFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>

View file

@ -71,14 +71,17 @@ QString MasterPalette::selectedPaletteName() const
// addPalette
//---------------------------------------------------------
void MasterPalette::addPalette(PaletteWidget* sp)
void MasterPalette::addPalette(PalettePtr palette)
{
sp->setReadOnly(true);
PaletteScrollArea* psa = new PaletteScrollArea(sp);
PaletteWidget* widget = new PaletteWidget(this);
widget->setReadOnly(true);
widget->setPalette(palette);
PaletteScrollArea* psa = new PaletteScrollArea(widget);
psa->setRestrictHeight(false);
QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(sp->name()));
QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(widget->name()));
item->setData(0, Qt::UserRole, stack->count());
item->setText(0, mu::qtrc("palette", sp->name().toUtf8().data()).replace("&&", "&"));
item->setText(0, mu::qtrc("palette", widget->name().toUtf8().data()).replace("&&", "&"));
stack->addWidget(psa);
treeWidget->addTopLevelItem(item);
}
@ -96,7 +99,7 @@ MasterPalette::MasterPalette(QWidget* parent)
treeWidget->clear();
addPalette(new PaletteWidget(PaletteCreator::newClefsPalette(), this));
addPalette(PaletteCreator::newClefsPalette());
m_keyEditor = new KeyEditor;
m_keyItem = new QTreeWidgetItem();
@ -110,27 +113,27 @@ MasterPalette::MasterPalette(QWidget* parent)
stack->addWidget(m_timeDialog);
treeWidget->addTopLevelItem(m_timeItem);
addPalette(new PaletteWidget(PaletteCreator::newBracketsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newAccidentalsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newArticulationsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newOrnamentsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newBreathPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newGraceNotePalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newNoteHeadsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newLinesPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newBarLinePalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newArpeggioPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newTremoloPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newTextPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newTempoPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newDynamicsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newFingeringPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newRepeatsPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newFretboardDiagramPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newAccordionPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newBagpipeEmbellishmentPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newLayoutPalette(), this));
addPalette(new PaletteWidget(PaletteCreator::newBeamPalette(), this));
addPalette(PaletteCreator::newBracketsPalette());
addPalette(PaletteCreator::newAccidentalsPalette());
addPalette(PaletteCreator::newArticulationsPalette());
addPalette(PaletteCreator::newOrnamentsPalette());
addPalette(PaletteCreator::newBreathPalette());
addPalette(PaletteCreator::newGraceNotePalette());
addPalette(PaletteCreator::newNoteHeadsPalette());
addPalette(PaletteCreator::newLinesPalette());
addPalette(PaletteCreator::newBarLinePalette());
addPalette(PaletteCreator::newArpeggioPalette());
addPalette(PaletteCreator::newTremoloPalette());
addPalette(PaletteCreator::newTextPalette());
addPalette(PaletteCreator::newTempoPalette());
addPalette(PaletteCreator::newDynamicsPalette());
addPalette(PaletteCreator::newFingeringPalette());
addPalette(PaletteCreator::newRepeatsPalette());
addPalette(PaletteCreator::newFretboardDiagramPalette());
addPalette(PaletteCreator::newAccordionPalette());
addPalette(PaletteCreator::newBagpipeEmbellishmentPalette());
addPalette(PaletteCreator::newLayoutPalette());
addPalette(PaletteCreator::newBeamPalette());
m_symbolItem = new QTreeWidgetItem();
m_idxAllSymbols = stack->count();

View file

@ -27,6 +27,8 @@
#include "ui_masterpalette.h"
#include "palettewidget.h"
namespace mu::palette {
class PaletteWidget;
}
@ -64,7 +66,7 @@ private slots:
void closeEvent(QCloseEvent* event) override;
private:
void addPalette(mu::palette::PaletteWidget* sp);
void addPalette(mu::palette::PalettePtr palette);
void retranslate(bool firstTime = false);
TimeDialog* m_timeDialog = nullptr;

View file

@ -55,9 +55,11 @@
#include "engraving/style/defaultstyle.h"
#include "engraving/style/style.h"
#include "engraving/compat/dummyelement.h"
#include "engraving/accessibility/accessibleitem.h"
#include "internal/palettecelliconengine.h"
#include "log.h"
#include "translation.h"
using namespace mu;
@ -67,21 +69,43 @@ using namespace mu::framework;
using namespace mu::draw;
using namespace Ms;
PaletteWidget::PaletteWidget(PalettePtr palette, QWidget* parent)
PaletteWidget::PaletteWidget(QWidget* parent)
: QWidget(parent)
{
m_palette = palette;
m_palette = std::make_shared<Palette>();
//! NOTE: need for accessibility
m_palette->setParent(this);
setObjectName("PaletteWidget_" + name());
setMouseTracking(true);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Ignored);
setReadOnly(false);
setMouseTracking(true);
}
PaletteWidget::PaletteWidget(QWidget* parent)
: PaletteWidget(std::make_shared<Palette>(), parent)
void PaletteWidget::setPalette(PalettePtr palette)
{
if (!palette) {
return;
}
m_palette = palette;
setObjectName("PaletteWidget_" + name());
//! NOTE: need for accessibility
m_palette->setParent(this);
update();
}
QAccessibleInterface* PaletteWidget::accessibleInterface(QObject* object)
{
PaletteWidget* widget = qobject_cast<PaletteWidget*>(object);
IF_ASSERT_FAILED(widget) {
return nullptr;
}
return static_cast<QAccessibleInterface*>(new AccessiblePaletteWidget(widget));
}
QString PaletteWidget::name() const
@ -320,7 +344,13 @@ int PaletteWidget::selectedIdx() const
void PaletteWidget::setSelected(int idx)
{
if (m_selectedIdx == idx) {
return;
}
int previous = m_selectedIdx;
m_selectedIdx = idx;
emit selectedChanged(idx, previous);
}
int PaletteWidget::currentIdx() const
@ -632,6 +662,10 @@ QSize PaletteWidget::sizeHint() const
bool PaletteWidget::event(QEvent* ev)
{
if (!m_palette) {
return false;
}
int hgridM = gridWidthScaled();
int vgridM = gridHeightScaled();
// disable mouse hover when keyboard navigation is enabled
@ -942,6 +976,22 @@ void PaletteWidget::paintEvent(QPaintEvent* /*event*/)
RectF r = RectF::fromQRectF(rectForCellAt(idx));
QColor c(configuration()->accentColor());
PaletteCellPtr currentCell = actualCellsList().at(idx);
if (!currentCell) {
continue;
}
if (currentCell->focused) {
painter.setPen(QColor(uiConfiguration()->currentTheme().values[ui::FONT_PRIMARY_COLOR].toString()));
painter.setBrush(QColor(Qt::transparent));
int borderWidth = uiConfiguration()->currentTheme().values[ui::NAVIGATION_CONTROL_BORDER_WIDTH].toInt();
qreal border = borderWidth / 2;
painter.drawRoundedRect(r.adjusted(border, border, -border, -border), borderWidth, borderWidth);
r.adjust(borderWidth, borderWidth, -borderWidth, -borderWidth);
}
if (idx == m_selectedIdx) {
c.setAlphaF(0.5);
painter.fillRect(r, c);
@ -953,11 +1003,6 @@ void PaletteWidget::paintEvent(QPaintEvent* /*event*/)
painter.fillRect(r, c);
}
PaletteCellPtr currentCell = actualCellsList().at(idx);
if (!currentCell) {
continue;
}
draw::Pen pen(configuration()->elementsColor());
pen.setWidthF(engraving::DefaultStyle::defaultStyle().styleS(Sid::staffLineWidth).val() * magS);
painter.setPen(pen);
@ -1166,23 +1211,19 @@ void PaletteScrollArea::keyPressEvent(QKeyEvent* event)
} else if (idx >= p->actualCellCount()) {
idx = 0;
}
p->setSelected(idx);
p->setCurrentIdx(idx);
// set widget name to name of selected element
// we could set the description, but some screen readers ignore it
QString name = p->cellAt(idx)->translatedName();
setAccessibleName(name);
QAccessibleEvent aev(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&aev);
p->update();
break;
return;
}
case Qt::Key_Enter:
case Qt::Key_Return:
if (!p->isApplyingElementsDisabled()) {
p->applyCurrentElementToScore();
}
break;
return;
default:
break;
}
@ -1200,3 +1241,94 @@ void PaletteScrollArea::resizeEvent(QResizeEvent* re)
setMaximumHeight(h + 6);
}
}
#include "log.h"
AccessiblePaletteWidget::AccessiblePaletteWidget(PaletteWidget* palette)
: QAccessibleWidget(palette)
{
m_palette = palette;
connect(m_palette, &PaletteWidget::selectedChanged, this, [this](int index, int previous){
PaletteCellPtr curCell = m_palette->cellAt(index);
PaletteCellPtr previousCell = m_palette->cellAt(previous);
if (previousCell) {
previousCell->focused = false;
QAccessible::State qstate;
qstate.active = false;
qstate.focused = false;
qstate.selected = false;
QAccessibleEvent ev(previousCell.get(), QAccessible::Focus);
QAccessible::updateAccessibility(&ev);
}
if (curCell) {
curCell->focused = true;
QAccessible::State qstate;
qstate.active = true;
qstate.focused = true;
qstate.selected = true;
QAccessibleEvent ev(curCell.get(), QAccessible::Focus);
QAccessible::updateAccessibility(&ev);
}
});
}
QObject* AccessiblePaletteWidget::object() const
{
return m_palette;
}
QAccessibleInterface* AccessiblePaletteWidget::child(int index) const
{
PaletteCellPtr cell = m_palette->cellAt(index);
if (!cell) {
return nullptr;
}
return QAccessible::queryAccessibleInterface(cell.get());
}
int AccessiblePaletteWidget::childCount() const
{
return m_palette->actualCellCount();
}
int AccessiblePaletteWidget::indexOfChild(const QAccessibleInterface* child) const
{
for (int i = 0; i < childCount(); ++i) {
auto childAccessible = QAccessible::queryAccessibleInterface(m_palette->cellAt(i).get());
if (childAccessible == child) {
return i;
}
}
return -1;
}
QAccessible::Role AccessiblePaletteWidget::role() const
{
return QAccessible::StaticText;
}
QAccessible::State AccessiblePaletteWidget::state() const
{
QAccessible::State state = QAccessibleWidget::state();
state.selectable = true;
state.active = true;
state.focusable = true;
state.focused = m_palette->hasFocus();
return state;
}
QAccessibleInterface* AccessiblePaletteWidget::focusChild() const
{
int selectIndex = m_palette->selectedIdx();
return QAccessible::queryAccessibleInterface(m_palette->cellAt(selectIndex).get());
}

View file

@ -24,14 +24,16 @@
#define MU_PALETTE_PALETTEWIDGET_H
#include <QScrollArea>
#include <QAccessibleWidget>
#include "internal/palette.h"
#include "../../internal/palette.h"
#include "engraving/libmscore/engravingitem.h"
#include "modularity/ioc.h"
#include "ipaletteconfiguration.h"
#include "../../ipaletteconfiguration.h"
#include "ui/iuiactionsregister.h"
#include "ui/iuiconfiguration.h"
#include "context/iglobalcontext.h"
#include "iinteractive.h"
@ -42,6 +44,26 @@ class XmlReader;
}
namespace mu::palette {
class PaletteWidget;
class AccessiblePaletteWidget : public QObject, public QAccessibleWidget
{
Q_OBJECT
public:
AccessiblePaletteWidget(PaletteWidget* palette);
QObject* object() const override;
QAccessibleInterface* child(int index) const override;
int childCount() const override;
int indexOfChild(const QAccessibleInterface* child) const override;
QAccessible::Role role() const override;
QAccessible::State state() const override;
QAccessibleInterface* focusChild() const override;
private:
PaletteWidget* m_palette = nullptr;
};
class PaletteWidget : public QWidget
{
Q_OBJECT
@ -50,10 +72,14 @@ class PaletteWidget : public QWidget
INJECT_STATIC(palette, ui::IUiActionsRegister, actionsRegister)
INJECT_STATIC(palette, context::IGlobalContext, globalContext)
INJECT(palette, framework::IInteractive, interactive)
INJECT(palette, ui::IUiConfiguration, uiConfiguration)
public:
PaletteWidget(QWidget* parent = nullptr);
PaletteWidget(PalettePtr palette, QWidget* parent = nullptr);
void setPalette(PalettePtr palette);
static QAccessibleInterface* accessibleInterface(QObject* object);
QString name() const;
void setName(const QString& name);
@ -135,6 +161,7 @@ public:
signals:
void changed();
void boxClicked(int index);
void selectedChanged(int index, int previous);
private:
bool event(QEvent*) override;
@ -169,7 +196,7 @@ private:
void applyElementAtPosition(QPoint pos, Qt::KeyboardModifiers modifiers);
void applyElementAtIndex(int index, Qt::KeyboardModifiers modifiers = {});
PalettePtr m_palette;
PalettePtr m_palette = nullptr;
std::vector<PaletteCellPtr> m_filteredCells; // used for filter & backup

View file

@ -45,7 +45,7 @@ extern MasterScore* gpaletteScore;
void SymbolDialog::createSymbolPalette()
{
sp = new PaletteWidget();
m_symbolsWidget = new PaletteWidget(this);
createSymbols();
}
@ -59,14 +59,14 @@ void SymbolDialog::createSymbols()
const ScoreFont* f = &ScoreFont::scoreFonts()[currentIndex];
// init the font if not done yet
ScoreFont::fontByName(f->name());
sp->clear();
m_symbolsWidget->clear();
for (auto name : (*mu::smuflRanges())[range]) {
SymId id = SymNames::symIdByName(name);
if (search->text().isEmpty()
|| SymNames::translatedUserNameForSymId(id).contains(search->text(), Qt::CaseInsensitive)) {
auto s = std::make_shared<Symbol>(gpaletteScore->dummy());
s->setSym(SymId(id), f);
sp->appendElement(s, SymNames::translatedUserNameForSymId(SymId(id)));
m_symbolsWidget->appendElement(s, SymNames::translatedUserNameForSymId(SymId(id)));
}
}
}
@ -91,21 +91,26 @@ SymbolDialog::SymbolDialog(const QString& s, QWidget* parent)
}
fontList->setCurrentIndex(currentIndex);
QLayout* l = new QVBoxLayout();
frame->setLayout(l);
QLayout* layout = new QVBoxLayout();
frame->setLayout(layout);
createSymbolPalette();
QScrollArea* sa = new PaletteScrollArea(sp);
l->addWidget(sa);
QScrollArea* symbolsArea = new PaletteScrollArea(m_symbolsWidget);
symbolsArea->setFocusProxy(m_symbolsWidget);
symbolsArea->setFocusPolicy(Qt::TabFocus);
layout->addWidget(symbolsArea);
sp->setAcceptDrops(false);
sp->setDrawGrid(true);
sp->setSelectable(true);
m_symbolsWidget->setAcceptDrops(false);
m_symbolsWidget->setDrawGrid(true);
m_symbolsWidget->setSelectable(true);
connect(systemFlag, &QCheckBox::stateChanged, this, &SymbolDialog::systemFlagChanged);
connect(fontList, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SymbolDialog::systemFontChanged);
sa->setWidget(sp);
symbolsArea->setWidget(m_symbolsWidget);
//! NOTE: It is necessary for the correct start of navigation in the dialog
setFocus();
}
//---------------------------------------------------------
@ -115,8 +120,8 @@ SymbolDialog::SymbolDialog(const QString& s, QWidget* parent)
void SymbolDialog::systemFlagChanged(int state)
{
bool sysFlag = state == Qt::Checked;
for (int i = 0; i < sp->actualCellCount(); ++i) {
ElementPtr e = sp->elementForCellAt(i);
for (int i = 0; i < m_symbolsWidget->actualCellCount(); ++i) {
ElementPtr e = m_symbolsWidget->elementForCellAt(i);
if (e && e->type() == ElementType::SYMBOL) {
std::dynamic_pointer_cast<Symbol>(e)->setSystemFlag(sysFlag);
}

View file

@ -39,11 +39,8 @@ class EngravingItem;
class SymbolDialog : public QWidget, Ui::SymbolDialogBase
{
Q_OBJECT
QString range;
mu::palette::PaletteWidget* sp;
void createSymbolPalette();
void createSymbols();
public:
SymbolDialog(const QString&, QWidget* parent = 0);
private slots:
void systemFlagChanged(int);
@ -55,8 +52,12 @@ protected:
virtual void changeEvent(QEvent* event);
void retranslate() { retranslateUi(this); }
public:
SymbolDialog(const QString&, QWidget* parent = 0);
private:
void createSymbolPalette();
void createSymbols();
QString range;
mu::palette::PaletteWidget* m_symbolsWidget = nullptr;
};
}

View file

@ -91,6 +91,9 @@
<property name="text">
<string>Font:</string>
</property>
<property name="buddy">
<cstring>fontList</cstring>
</property>
</widget>
</item>
<item>

View file

@ -50,7 +50,8 @@ TimeDialog::TimeDialog(QWidget* parent)
l->setContentsMargins(0, 0, 0, 0);
frame->setLayout(l);
sp = new PaletteWidget(PaletteCreator::newTimePalette(), this);
sp = new PaletteWidget(this);
sp->setPalette(PaletteCreator::newTimePalette());
sp->setReadOnly(false);
sp->setSelectable(true);
@ -82,6 +83,24 @@ TimeDialog::TimeDialog(QWidget* parent)
sp->elementForCellAt(2)->layout();
sp->setSelected(2);
paletteChanged(2);
//! NOTE: It is necessary for the correct start of navigation in the dialog
setFocus();
}
TimeDialog::TimeDialog(const TimeDialog& dialog)
: TimeDialog(dialog.parentWidget())
{
}
bool TimeDialog::dirty() const
{
return _dirty;
}
bool TimeDialog::showTimePalette() const
{
return _timePalette->isVisible();
}
//---------------------------------------------------------
@ -111,7 +130,7 @@ void TimeDialog::addClicked()
// showTimePalette
//---------------------------------------------------------
void TimeDialog::showTimePalette(bool val)
void TimeDialog::setShowTimePalette(bool val)
{
_timePalette->setVisible(val);
}
@ -253,3 +272,8 @@ void TimeDialog::textChanged()
Fraction sig(zNominal->value(), denominator());
groups->setSig(sig, Groups::endings(sig), zText->text(), nText->text());
}
void TimeDialog::setDirty()
{
_dirty = true;
}

View file

@ -43,14 +43,17 @@ class TimeDialog : public QWidget, Ui::TimeDialogBase
{
Q_OBJECT
Q_PROPERTY(bool showTimePalette READ showTimePalette WRITE setShowTimePalette)
INJECT(palette, mu::palette::IPaletteConfiguration, configuration)
mu::palette::PaletteScrollArea* _timePalette = nullptr;
mu::palette::PaletteWidget* sp = nullptr;
bool _dirty = false;
public:
TimeDialog(QWidget* parent = 0);
TimeDialog(const TimeDialog& dialog);
int denominator() const;
int denominator2Idx(int) const;
bool dirty() const;
bool showTimePalette() const;
void save();
private slots:
void addClicked();
@ -58,16 +61,19 @@ private slots:
void nChanged(int);
void paletteChanged(int idx);
void textChanged();
void setDirty() { _dirty = true; }
void setDirty();
void setShowTimePalette(bool val);
signals:
void timeSigAdded(const std::shared_ptr<TimeSig>);
public:
TimeDialog(QWidget* parent = 0);
bool dirty() const { return _dirty; }
void showTimePalette(bool val);
void save();
private:
int denominator() const;
int denominator2Idx(int) const;
mu::palette::PaletteScrollArea* _timePalette = nullptr;
mu::palette::PaletteWidget* sp = nullptr;
bool _dirty = false;
};
}

View file

@ -56,6 +56,9 @@
<property name="text">
<string>Value:</string>
</property>
<property name="buddy">
<cstring>zNominal</cstring>
</property>
</widget>
</item>
<item>
@ -94,6 +97,9 @@
<property name="text">
<string>/</string>
</property>
<property name="buddy">
<cstring>nNominal</cstring>
</property>
</widget>
</item>
<item>
@ -158,6 +164,9 @@
<property name="text">
<string>Text:</string>
</property>
<property name="buddy">
<cstring>zText</cstring>
</property>
</widget>
</item>
<item>
@ -190,6 +199,9 @@
<property name="text">
<string>/</string>
</property>
<property name="buddy">
<cstring>nText</cstring>
</property>
</widget>
</item>
<item>