LCOV - code coverage report
Current view: top level - src/engraving/dom - stem.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 49.0 % 100 49
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #include "stem.h"
      23              : 
      24              : #include <cmath>
      25              : 
      26              : #include "../editing/elementeditdata.h"
      27              : 
      28              : #include "chord.h"
      29              : #include "hook.h"
      30              : #include "tremolosinglechord.h"
      31              : 
      32              : #include "log.h"
      33              : 
      34              : using namespace mu;
      35              : using namespace muse::draw;
      36              : using namespace mu::engraving;
      37              : 
      38              : static const ElementStyle stemStyle {
      39              :     { Sid::stemWidth, Pid::LINE_WIDTH }
      40              : };
      41              : 
      42        27509 : Stem::Stem(DummyParentOr<Chord> parent)
      43        27509 :     : EngravingItem(ElementType::STEM, parent)
      44              : {
      45        27509 :     initElementStyle(&stemStyle);
      46        27509 :     resetProperty(Pid::USER_LEN);
      47        27509 : }
      48              : 
      49            0 : EngravingItem* Stem::elementBase() const
      50              : {
      51            0 :     return chord();
      52              : }
      53              : 
      54        18862 : staff_idx_t Stem::vStaffIdx() const
      55              : {
      56        18862 :     return staffIdx() + chord()->staffMove();
      57              : }
      58              : 
      59       221035 : bool Stem::up() const
      60              : {
      61       221035 :     return chord() ? chord()->up() : true;
      62              : }
      63              : 
      64       164215 : void Stem::setBaseLength(Spatium baseLength)
      65              : {
      66       164215 :     m_baseLength = Spatium(std::abs(baseLength.val()));
      67       164215 : }
      68              : 
      69       393691 : double Stem::lineWidthMag() const
      70              : {
      71       393691 :     return absoluteFromSpatium(m_lineWidth) * chord()->intrinsicMag();
      72              : }
      73              : 
      74              : //! In chord coordinates
      75         4566 : PointF Stem::flagPosition() const
      76              : {
      77         4566 :     return pos() + PointF(ldata()->bbox().left(), up() ? -length() : length());
      78              : }
      79              : 
      80            0 : std::vector<PointF> Stem::gripsPositions(const EditData&) const
      81              : {
      82            0 :     return { pagePos() + ldata()->line.p2() };
      83              : }
      84              : 
      85            0 : void Stem::startEdit(EditData& ed)
      86              : {
      87            0 :     EngravingItem::startEdit(ed);
      88            0 :     ElementEditDataPtr eed = ed.getData(this);
      89            0 :     eed->pushProperty(Pid::USER_LEN);
      90            0 : }
      91              : 
      92            0 : void Stem::startDragGrip(EditData& ed)
      93              : {
      94            0 :     EngravingItem::startDragGrip(ed);
      95            0 :     ElementEditDataPtr eed = ed.getData(this);
      96            0 :     eed->pushProperty(Pid::USER_LEN);
      97            0 : }
      98              : 
      99            0 : void Stem::dragGrip(EditData& ed)
     100              : {
     101            0 :     double yDelta = up() ? -ed.delta.y() : ed.delta.y();
     102            0 :     m_userLength += Spatium::fromAbsolute(yDelta, spatium());
     103            0 :     Chord* c = chord();
     104            0 :     if (c->hook()) {
     105            0 :         c->hook()->move(PointF(0.0, ed.delta.y()));
     106              :     }
     107            0 :     triggerLayout();
     108            0 : }
     109              : 
     110            0 : void Stem::reset()
     111              : {
     112            0 :     undoChangeProperty(Pid::USER_LEN, 0.0_sp);
     113            0 :     EngravingItem::reset();
     114            0 : }
     115              : 
     116            8 : bool Stem::acceptDrop(EditData& data) const
     117              : {
     118            8 :     const EngravingItem* e = data.dropElement;
     119            8 :     switch (e->type()) {
     120            0 :     case ElementType::TREMOLO_SINGLECHORD:
     121            0 :         return item_cast<const TremoloSingleChord*>(e)->tremoloType() <= TremoloType::R256;
     122            8 :     default:
     123            8 :         break;
     124              :     }
     125              : 
     126            8 :     return false;
     127              : }
     128              : 
     129            0 : EngravingItem* Stem::drop(Transaction&, EditData& data)
     130              : {
     131            0 :     EngravingItem* e = data.dropElement;
     132            0 :     Chord* ch  = chord();
     133              : 
     134            0 :     switch (e->type()) {
     135            0 :     case ElementType::TREMOLO_SINGLECHORD:
     136            0 :         item_cast<TremoloSingleChord*>(e)->setOwnershipParent(ch);
     137            0 :         undoAddElement(e);
     138            0 :         return e;
     139            0 :     default:
     140            0 :         delete e;
     141            0 :         break;
     142              :     }
     143            0 :     return 0;
     144              : }
     145              : 
     146       117837 : PropertyValue Stem::getProperty(Pid propertyId) const
     147              : {
     148       117837 :     switch (propertyId) {
     149        33392 :     case Pid::LINE_WIDTH:
     150        33392 :         return lineWidth();
     151            3 :     case Pid::USER_LEN:
     152            3 :         return userLength();
     153            0 :     case Pid::STEM_DIRECTION:
     154            0 :         return PropertyValue::fromValue<DirectionV>(chord()->stemDirection());
     155            3 :     case Pid::APPEARANCE_LINKED_TO_MASTER:
     156            3 :         return chord() ? chord()->isPropertyLinkedToMaster(Pid::STEM_DIRECTION) : true;
     157        84439 :     default:
     158        84439 :         return EngravingItem::getProperty(propertyId);
     159              :     }
     160              : }
     161              : 
     162        55664 : bool Stem::setProperty(Pid propertyId, const PropertyValue& v)
     163              : {
     164        55664 :     switch (propertyId) {
     165        28004 :     case Pid::LINE_WIDTH:
     166        28004 :         setLineWidth(v.value<Spatium>());
     167        28004 :         break;
     168        27509 :     case Pid::USER_LEN:
     169        27509 :         setUserLength(v.value<Spatium>());
     170        27509 :         break;
     171            0 :     case Pid::STEM_DIRECTION:
     172            0 :         chord()->setStemDirection(v.value<DirectionV>());
     173            0 :         break;
     174            0 :     case Pid::APPEARANCE_LINKED_TO_MASTER:
     175            0 :         if (chord() && v.toBool() == true) {
     176            0 :             chord()->relinkPropertyToMaster(Pid::STEM_DIRECTION);
     177            0 :             break;
     178              :         }
     179              :     // fall through
     180              :     default:
     181          151 :         return EngravingItem::setProperty(propertyId, v);
     182              :     }
     183        55513 :     triggerLayout();
     184        55513 :     return true;
     185              : }
     186              : 
     187       144401 : PropertyValue Stem::propertyDefault(Pid id) const
     188              : {
     189       144401 :     switch (id) {
     190        27512 :     case Pid::USER_LEN:
     191        27512 :         return 0.0_sp;
     192            0 :     case Pid::STEM_DIRECTION:
     193            0 :         return PropertyValue::fromValue<DirectionV>(DirectionV::AUTO);
     194       116889 :     default:
     195       116889 :         return EngravingItem::propertyDefault(id);
     196              :     }
     197              : }
        

Generated by: LCOV version 2.0-1