Merge pull request #12340 from shoogle/accessibility-element-info
Accessibility: Improve speech output for notes and common elements
This commit is contained in:
commit
222a8b6d6d
|
@ -25,14 +25,27 @@
|
|||
#include "../libmscore/score.h"
|
||||
#include "../libmscore/measure.h"
|
||||
|
||||
#include "translation.h"
|
||||
#include "log.h"
|
||||
|
||||
using namespace mu;
|
||||
using namespace mu::engraving;
|
||||
using namespace mu::accessibility;
|
||||
using namespace mu::engraving;
|
||||
|
||||
bool AccessibleItem::enabled = true;
|
||||
|
||||
static QString readable(QString s)
|
||||
{
|
||||
// Remove undesired pauses in screen reader speech output
|
||||
s.remove(u':');
|
||||
|
||||
// Handle desired pauses
|
||||
s.replace(u';', u','); // NVDA doesn't pause for semicolon
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
AccessibleItem::AccessibleItem(EngravingItem* e, Role role)
|
||||
: m_element(e), m_role(role)
|
||||
{
|
||||
|
@ -169,9 +182,15 @@ QString AccessibleItem::accessibleName() const
|
|||
QString staffInfo = root ? root->staffInfo() : "";
|
||||
QString barsAndBeats = m_element->formatBarsAndBeats();
|
||||
|
||||
return QString("%1%2%3").arg(!staffInfo.isEmpty() ? (staffInfo + "; ") : "")
|
||||
.arg(m_element->accessibleInfo().toQString())
|
||||
.arg(!barsAndBeats.isEmpty() ? ("; " + barsAndBeats) : "");
|
||||
barsAndBeats.remove(u';'); // Too many pauses in speech
|
||||
|
||||
QString name = QString("%1%2%3%4")
|
||||
.arg(!staffInfo.isEmpty() ? (staffInfo + "; ") : "")
|
||||
.arg(m_element->screenReaderInfo().toQString())
|
||||
.arg(m_element->visible() ? "" : " " + qtrc("engraving", "invisible"))
|
||||
.arg(!barsAndBeats.isEmpty() ? ("; " + barsAndBeats) : "");
|
||||
|
||||
return readable(name);
|
||||
}
|
||||
|
||||
QString AccessibleItem::accessibleDescription() const
|
||||
|
@ -185,7 +204,7 @@ QString AccessibleItem::accessibleDescription() const
|
|||
result = accessibleName() + " ";
|
||||
#endif
|
||||
|
||||
result += m_element->accessibleExtraInfo();
|
||||
result += readable(m_element->accessibleExtraInfo());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -683,7 +683,8 @@ String ChordRest::durationUserName() const
|
|||
tupletType = mtrc("engraving", "Nonuplet");
|
||||
break;
|
||||
default:
|
||||
tupletType = mtrc("engraving", "Custom tuplet");
|
||||
//: %1 is tuplet ratio numerator (i.e. the number of notes in the tuplet)
|
||||
tupletType = mtrc("engraving", "%1 note tuplet").arg(tuplet()->ratio().numerator());
|
||||
}
|
||||
}
|
||||
String dotString;
|
||||
|
|
|
@ -3332,7 +3332,15 @@ String Note::screenReaderInfo() const
|
|||
pitchName = mtrc("engraving", "%1; String: %2; Fret: %3")
|
||||
.arg(tpcUserName(true), String::number(string() + 1), String::number(fret()));
|
||||
} else {
|
||||
pitchName = tpcUserName(true);
|
||||
pitchName = _headGroup == NoteHeadGroup::HEAD_NORMAL
|
||||
? tpcUserName(true)
|
||||
//: head as in note head. %1 is head type (circle, cross, etc.). %2 is pitch (e.g. Db4).
|
||||
: mtrc("engraving", "%1 head %2").arg(subtypeName()).arg(tpcUserName(true));
|
||||
if (chord()->staffMove() < 0) {
|
||||
duration += u"; " + mtrc("engraving", "Cross-staff above");
|
||||
} else if (chord()->staffMove() > 0) {
|
||||
duration += u"; " + mtrc("engraving", "Cross-staff below");
|
||||
}
|
||||
}
|
||||
return String(u"%1 %2 %3%4").arg(noteTypeUserName(), pitchName, duration, (chord()->isGrace() ? u"" : String(u"; %1").arg(voice)));
|
||||
}
|
||||
|
|
|
@ -863,8 +863,14 @@ String Rest::screenReaderInfo() const
|
|||
{
|
||||
Measure* m = measure();
|
||||
bool voices = m ? m->hasVoices(staffIdx()) : false;
|
||||
String voice = voices ? mtrc("engraving", "Voice: %1").arg(track() % VOICES + 1) : u"";
|
||||
return String(u"%1 %2 %3").arg(EngravingItem::accessibleInfo(), durationUserName(), voice);
|
||||
String voice = voices ? (u"; " + mtrc("engraving", "Voice: %1").arg(track() % VOICES + 1)) : u"";
|
||||
String crossStaff;
|
||||
if (staffMove() < 0) {
|
||||
crossStaff = u"; " + mtrc("engraving", "Cross-staff above");
|
||||
} else if (staffMove() > 0) {
|
||||
crossStaff = u"; " + mtrc("engraving", "Cross-staff below");
|
||||
}
|
||||
return String(u"%1 %2%3%4").arg(EngravingItem::accessibleInfo(), durationUserName(), crossStaff, voice);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue