Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow reversal of hook flags within Inspector: Chord #25938

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/engraving/api/v1/elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class EngravingItem : public apiv1::ScoreElement
API_PROPERTY(articulationAnchor, ARTICULATION_ANCHOR)
API_PROPERTY(direction, DIRECTION)
API_PROPERTY(stemDirection, STEM_DIRECTION)
API_PROPERTY(hookReversed, HOOK_REVERSED)
API_PROPERTY(noStem, NO_STEM)
API_PROPERTY(slurDirection, SLUR_DIRECTION)
API_PROPERTY(leadingSpace, LEADING_SPACE)
Expand Down
38 changes: 24 additions & 14 deletions src/engraving/dom/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ Chord::Chord(Segment* parent)
m_stem = 0;
m_hook = 0;
m_stemDirection = DirectionV::AUTO;
m_hookIsReversed = false;
m_arpeggio = 0;
m_spanArpeggio = 0;
m_endsNoteAnchoredLine = false;
Expand Down Expand Up @@ -297,15 +298,16 @@ Chord::Chord(const Chord& c, bool link)
m_arpeggio = 0;
m_stemSlash = 0;

m_spanArpeggio = c.m_spanArpeggio;
m_graceIndex = c.m_graceIndex;
m_noStem = c.m_noStem;
m_showStemSlash = c.m_showStemSlash;
m_playEventType = c.m_playEventType;
m_stemDirection = c.m_stemDirection;
m_noteType = c.m_noteType;
m_crossMeasure = CrossMeasure::UNKNOWN;
m_combineVoice = c.m_combineVoice;
m_spanArpeggio = c.m_spanArpeggio;
m_graceIndex = c.m_graceIndex;
m_noStem = c.m_noStem;
m_showStemSlash = c.m_showStemSlash;
m_playEventType = c.m_playEventType;
m_stemDirection = c.m_stemDirection;
m_hookIsReversed = c.m_hookIsReversed;
m_noteType = c.m_noteType;
m_crossMeasure = CrossMeasure::UNKNOWN;
m_combineVoice = c.m_combineVoice;

if (c.m_stem) {
add(Factory::copyStem(*(c.m_stem)));
Expand Down Expand Up @@ -2087,8 +2089,10 @@ PropertyValue Chord::getProperty(Pid propertyId) const
case Pid::SHOW_STEM_SLASH: return showStemSlash();
case Pid::SMALL: return isSmall();
case Pid::STEM_DIRECTION: return PropertyValue::fromValue<DirectionV>(stemDirection());
case Pid::PLAY: return isChordPlayable();
case Pid::COMBINE_VOICE: return PropertyValue::fromValue<AutoOnOff>(combineVoice());
case Pid::PLAY: return isChordPlayable();
case Pid::COMBINE_VOICE: return PropertyValue::fromValue<AutoOnOff>(combineVoice());
case Pid::HOOK_REVERSED: return hookIsReversed();

default:
return ChordRest::getProperty(propertyId);
}
Expand All @@ -2102,11 +2106,13 @@ PropertyValue Chord::propertyDefault(Pid propertyId) const
{
switch (propertyId) {
case Pid::NO_STEM: return false;
case Pid::SHOW_STEM_SLASH: return noteType() == NoteType::ACCIACCATURA;
case Pid::SHOW_STEM_SLASH: return noteType() & NoteType::ACCIACCATURA;
Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Dec 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, fixes a Visual Studio warning

case Pid::SMALL: return false;
case Pid::STEM_DIRECTION: return PropertyValue::fromValue<DirectionV>(DirectionV::AUTO);
case Pid::PLAY: return true;
case Pid::COMBINE_VOICE: return AutoOnOff::AUTO;
case Pid::PLAY: return true;
case Pid::COMBINE_VOICE: return AutoOnOff::AUTO;
case Pid::HOOK_REVERSED: return false;

default:
return ChordRest::propertyDefault(propertyId);
}
Expand Down Expand Up @@ -2137,6 +2143,10 @@ bool Chord::setProperty(Pid propertyId, const PropertyValue& v)
case Pid::COMBINE_VOICE:
setCombineVoice(v.value<AutoOnOff>());
break;
case Pid::HOOK_REVERSED:
setHookReversed(v.toBool());
break;

default:
return ChordRest::setProperty(propertyId, v);
}
Expand Down
4 changes: 4 additions & 0 deletions src/engraving/dom/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ class Chord final : public ChordRest

Note* firstGraceOrNote();

bool hookIsReversed() const { return hook() ? m_hookIsReversed : false; }
void setHookReversed(bool v) { m_hookIsReversed = v; }

#ifndef ENGRAVING_NO_ACCESSIBILITY
AccessibleItemPtr createAccessible() override;
#endif
Expand Down Expand Up @@ -354,6 +357,7 @@ class Chord final : public ChordRest

Stem* m_stem = nullptr;
Hook* m_hook = nullptr;
bool m_hookIsReversed = false;
StemSlash* m_stemSlash = nullptr; // for grace notes
bool m_showStemSlash = false;

Expand Down
5 changes: 5 additions & 0 deletions src/engraving/dom/engravingitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,11 @@ void EngravingItem::undoAddElement(EngravingItem* element, bool addToLinkedStave
// drawSymbol
//---------------------------------------------------------

void EngravingItem::drawSymbolReversed(SymId id, Painter* p, const PointF& o, double scale) const
{
score()->engravingFont()->drawReversed(id, p, magS() * scale, o);
}

void EngravingItem::drawSymbol(SymId id, Painter* p, const PointF& o, double scale) const
{
score()->engravingFont()->draw(id, p, magS() * scale, o);
Expand Down
1 change: 1 addition & 0 deletions src/engraving/dom/engravingitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ class EngravingItem : public EngravingObject
bool custom(Pid) const;
virtual bool isUserModified() const;

void drawSymbolReversed(SymId id, muse::draw::Painter* p, const PointF& o = PointF(), double scale = 1.0) const;
void drawSymbol(SymId id, muse::draw::Painter* p, const PointF& o = PointF(), double scale = 1.0) const;
void drawSymbols(const SymIdList&, muse::draw::Painter* p, const PointF& o = PointF(), double scale = 1.0) const;
void drawSymbols(const SymIdList&, muse::draw::Painter* p, const PointF& o, const SizeF& scale) const;
Expand Down
1 change: 1 addition & 0 deletions src/engraving/dom/property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ static constexpr PropertyMetaData propertyList[] = {
{ Pid::DIRECTION, false, "direction", P_TYPE::DIRECTION_V, PropertyGroup::POSITION, DUMMY_QT_TR_NOOP("propertyName", "direction") },
{ Pid::STEM_DIRECTION, false, "StemDirection", P_TYPE::DIRECTION_V, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "stem direction") },
{ Pid::NO_STEM, false, "noStem", P_TYPE::INT, PropertyGroup::APPEARANCE, DUMMY_QT_TR_NOOP("propertyName", "no stem") },
{ Pid::HOOK_REVERSED, false, "hookReverse", P_TYPE::BOOL, PropertyGroup::POSITION, DUMMY_QT_TR_NOOP("propertyName", "reverse hook") },
Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Dec 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better "hookReversed" or even "reversedHook" (requires changes elsewhere too) and "reversed hook"

{ Pid::SLUR_DIRECTION, false, "up", P_TYPE::DIRECTION_V, PropertyGroup::POSITION, DUMMY_QT_TR_NOOP("propertyName", "up") },
{ Pid::LEADING_SPACE, false, "leadingSpace", P_TYPE::SPATIUM, PropertyGroup::POSITION, DUMMY_QT_TR_NOOP("propertyName", "leading space") },
{ Pid::MIRROR_HEAD, false, "mirror", P_TYPE::DIRECTION_H, PropertyGroup::POSITION, DUMMY_QT_TR_NOOP("propertyName", "mirror") },
Expand Down
1 change: 1 addition & 0 deletions src/engraving/dom/property.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ enum class Pid {
DIRECTION,
STEM_DIRECTION,
NO_STEM,
HOOK_REVERSED,
SLUR_DIRECTION,
LEADING_SPACE,
MIRROR_HEAD,
Expand Down
1 change: 1 addition & 0 deletions src/engraving/iengravingfont.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class IEngravingFont
virtual PointF smuflAnchor(SymId symId, SmuflAnchorId anchorId, double mag) const = 0;

// Draw
virtual void drawReversed(SymId id, muse::draw::Painter* p, double mag, const PointF& pos) const = 0;
virtual void draw(SymId id, muse::draw::Painter* p, double mag, const PointF& pos, const double angle = 0) const = 0;
virtual void draw(SymId id, muse::draw::Painter* p, const SizeF& mag, const PointF& pos, const double angle = 0) const = 0;
virtual void draw(const SymIdList& ids, muse::draw::Painter* p, double mag, const PointF& pos, const double angle = 0) const = 0;
Expand Down
9 changes: 9 additions & 0 deletions src/engraving/internal/engravingfont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,15 @@ PointF EngravingFont::smuflAnchor(SymId symId, SmuflAnchorId anchorId, double ma
// Draw
// =============================================

void EngravingFont::drawReversed(SymId id, Painter* painter, double mag, const PointF& pos) const
{
double worldScale = painter->worldTransform().m11();
painter->save();
painter->scale(-1.0, +1.0);
draw(id, painter, SizeF(mag, mag), pos, worldScale);
painter->restore();
}

void EngravingFont::draw(SymId id, Painter* painter, const SizeF& mag, const PointF& pos, const double angle) const
{
const Sym& sym = this->sym(id);
Expand Down
1 change: 1 addition & 0 deletions src/engraving/internal/engravingfont.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class EngravingFont : public IEngravingFont, public muse::Injectable
PointF smuflAnchor(SymId symId, SmuflAnchorId anchorId, double mag) const override;

// Draw
void drawReversed(SymId id, muse::draw::Painter*, double mag, const PointF& pos) const override;
void draw(SymId id, muse::draw::Painter* p, double mag, const PointF& pos, const double angle = 0) const override;
void draw(SymId id, muse::draw::Painter* p, const SizeF& mag, const PointF& pos, const double angle = 0) const override;

Expand Down
9 changes: 8 additions & 1 deletion src/engraving/rendering/score/tdraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1933,7 +1933,14 @@ void TDraw::draw(const Hook* item, Painter* painter)
}

painter->setPen(item->curColor());
item->drawSymbol(item->sym(), painter);
if (item->chord()->hookIsReversed()) {
double scale = 1.0;
double dx = item->chord()->hook()->width() + (1.5 * item->chord()->stem()->lineWidthMag());
PointF offset = PointF(-dx, 0.0);
item->drawSymbolReversed(item->sym(), painter, offset, scale);
} else {
item->drawSymbol(item->sym(), painter);
}
}

void TDraw::draw(const Image* item, Painter* painter)
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/rendering/score/tlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5356,7 +5356,7 @@ void TLayout::layoutStem(const Stem* item, Stem::LayoutData* ldata, const Layout
}
}

double lineWidthCorrection = item->lineWidthMag() * 0.5;
double lineWidthCorrection = !item->chord()->hookIsReversed() ? item->lineWidthMag() * 0.5 : -item->chord()->hook()->width();
double lineX = isTabStaff ? 0.0 : _up * lineWidthCorrection;

LineF line = LineF(lineX, y1, lineX, y2);
Expand Down
2 changes: 2 additions & 0 deletions src/engraving/rw/read410/tread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2698,6 +2698,8 @@ bool TRead::readProperties(Chord* ch, XmlReader& e, ReadContext& ctx)
TRead::read(ss, e, ctx);
ch->add(ss);
} else if (TRead::readProperty(ch, tag, e, ctx, Pid::STEM_DIRECTION)) {
} else if (tag == "hookReverse") {
ch->setHookReversed(e.readBool());
Copy link
Contributor Author

@Jojo-Schmitz Jojo-Schmitz Dec 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this needs to get added to read302.cpp too, in order to be able to read this from 3.7 scores?

} else if (tag == "noStem") {
ch->setNoStem(e.readInt());
} else if (tag == "showStemSlash") {
Expand Down
9 changes: 7 additions & 2 deletions src/engraving/rw/write/twrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,8 +919,13 @@ void TWrite::write(const Chord* item, XmlWriter& xml, WriteContext& ctx)
} else if (item->stem() && (item->stem()->isUserModified() || !item->stem()->userLength().isZero())) {
write(item->stem(), xml, ctx);
}
if (item->hook() && item->hook()->isUserModified()) {
write(item->hook(), xml, ctx);
if (item->hook()) {
if (item->hook()->isUserModified()) {
write(item->hook(), xml, ctx);
}
if (item->hookIsReversed()) {
writeProperty(item, xml, Pid::HOOK_REVERSED);
}
}
if (item->showStemSlash() && item->isUserModified()) {
xml.tag("showStemSlash", item->showStemSlash());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void ChordSettingsModel::requestElements()
void ChordSettingsModel::loadProperties()
{
loadPropertyItem(m_isStemless);
loadPropertyItem(m_isHookReversed);
loadPropertyItem(m_showStemSlash);
loadPropertyItem(m_combineVoice);
updateShowStemSlashVisible();
Expand All @@ -64,6 +65,7 @@ void ChordSettingsModel::loadProperties()
void ChordSettingsModel::resetProperties()
{
m_isStemless->resetToDefault();
m_isHookReversed->resetToDefault();
m_showStemSlash->resetToDefault();
updateShowStemSlashEnabled();
}
Expand All @@ -73,6 +75,11 @@ PropertyItem* ChordSettingsModel::isStemless() const
return m_isStemless;
}

PropertyItem* ChordSettingsModel::isReversedHook() const
{
return m_isHookReversed;
}

PropertyItem* ChordSettingsModel::showStemSlash() const
{
return m_showStemSlash;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ChordSettingsModel : public AbstractInspectorModel
Q_OBJECT

Q_PROPERTY(PropertyItem * isStemless READ isStemless CONSTANT)
Q_PROPERTY(PropertyItem * isReversedHook READ isReversedHook CONSTANT)
Q_PROPERTY(PropertyItem * showStemSlash READ showStemSlash CONSTANT)
Q_PROPERTY(PropertyItem * combineVoice READ combineVoice CONSTANT)

Expand All @@ -40,6 +41,7 @@ class ChordSettingsModel : public AbstractInspectorModel
explicit ChordSettingsModel(QObject* parent, IElementRepositoryService* repository);

PropertyItem* isStemless() const;
PropertyItem* isReversedHook() const;
PropertyItem* showStemSlash() const;
PropertyItem* combineVoice() const;

Expand All @@ -63,9 +65,10 @@ public slots:
void updateShowStemSlashVisible();
void updateShowStemSlashEnabled();

PropertyItem* m_isStemless = nullptr;
PropertyItem* m_showStemSlash = nullptr;
PropertyItem* m_combineVoice = nullptr;
PropertyItem* m_isStemless = nullptr;
PropertyItem* m_isHookReversed = nullptr;
PropertyItem* m_showStemSlash = nullptr;
PropertyItem* m_combineVoice = nullptr;

bool m_showStemSlashVisible = false;
bool m_showStemSlashEnabled = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ FocusableItem {

spacing: 12

PropertyCheckBox {
text: qsTrc("inspector", "Reversed hook")
propertyItem: root.chordModel ? root.chordModel.isReverseHook : null

navigationName: "Reversed hook"
navigationPanel: root.navigationPanel
navigationRowStart: root.navigationRowStart + 1
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't seem to work at all...

Item {
height: childrenRect.height
width: parent.width
Expand Down