LCOV - code coverage report
Current view: top level - src/engraving/dom - tremolosinglechord.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 64.0 % 139 89
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              : 
      23              : #include "tremolosinglechord.h"
      24              : 
      25              : #include "draw/types/transform.h"
      26              : 
      27              : #include "types/typesconv.h"
      28              : 
      29              : #include "style/style.h"
      30              : 
      31              : #include "rendering/score/beamtremololayout.h"
      32              : 
      33              : #include "beam.h"
      34              : #include "chord.h"
      35              : #include "stem.h"
      36              : #include "system.h"
      37              : #include "stafftype.h"
      38              : 
      39              : #include "log.h"
      40              : 
      41              : using namespace mu;
      42              : using namespace muse::draw;
      43              : using namespace mu::engraving;
      44              : 
      45              : namespace mu::engraving {
      46          164 : TremoloSingleChord::TremoloSingleChord(DummyParentOr<Chord> parent)
      47          164 :     : EngravingItem(ElementType::TREMOLO_SINGLECHORD, parent, ElementFlag::MOVABLE | ElementFlag::ON_STAFF)
      48              : {
      49          164 : }
      50              : 
      51            3 : TremoloSingleChord::TremoloSingleChord(const TremoloSingleChord& t)
      52            3 :     : EngravingItem(t)
      53              : {
      54            3 :     setTremoloType(t.tremoloType());
      55            3 :     m_durationType = t.m_durationType;
      56            3 : }
      57              : 
      58          276 : TremoloSingleChord::~TremoloSingleChord()
      59              : {
      60              :     //
      61              :     // delete all references from chords
      62              :     //
      63          138 :     if (chord() && chord()->tremoloSingleChord() == this) {
      64            0 :         chord()->setTremoloSingleChord(nullptr);
      65              :     }
      66          276 : }
      67              : 
      68         3248 : double TremoloSingleChord::chordMag() const
      69              : {
      70         3248 :     return chord() ? chord()->intrinsicMag() : 1.0;
      71              : }
      72              : 
      73         1152 : double TremoloSingleChord::minHeight() const
      74              : {
      75         1152 :     const double sw = style().styleS(Sid::tremoloLineWidth).val() * chordMag();
      76         1152 :     const double td = style().styleS(Sid::tremoloDistance).val() * chordMag();
      77         1152 :     return (lines() - 1) * td + sw;
      78              : }
      79              : 
      80              : //---------------------------------------------------------
      81              : //   drag
      82              : //---------------------------------------------------------
      83              : 
      84            0 : RectF TremoloSingleChord::drag(EditData& ed)
      85              : {
      86            0 :     return EngravingItem::drag(ed);
      87              : }
      88              : 
      89              : //---------------------------------------------------------
      90              : //   setTremoloType
      91              : //---------------------------------------------------------
      92              : 
      93          166 : void TremoloSingleChord::setTremoloType(TremoloType t)
      94              : {
      95          166 :     m_tremoloType = t;
      96          166 :     switch (tremoloType()) {
      97           31 :     case TremoloType::R16:
      98              :     case TremoloType::C16:
      99           31 :         m_lines = 2;
     100           31 :         break;
     101           36 :     case TremoloType::R32:
     102              :     case TremoloType::C32:
     103           36 :         m_lines = 3;
     104           36 :         break;
     105           14 :     case TremoloType::R64:
     106              :     case TremoloType::C64:
     107           14 :         m_lines = 4;
     108           14 :         break;
     109            0 :     case TremoloType::R128:
     110              :     case TremoloType::C128:
     111            0 :         m_lines = 5;
     112            0 :         break;
     113            0 :     case TremoloType::R256:
     114              :     case TremoloType::C256:
     115            0 :         m_lines = 6;
     116            0 :         break;
     117           85 :     default:
     118           85 :         m_lines = 1;
     119           85 :         break;
     120              :     }
     121              : 
     122          166 :     styleChanged();
     123          166 : }
     124              : 
     125              : //---------------------------------------------------------
     126              : //   spatiumChanged
     127              : //---------------------------------------------------------
     128              : 
     129            0 : void TremoloSingleChord::spatiumChanged(double oldValue, double newValue)
     130              : {
     131            0 :     EngravingItem::spatiumChanged(oldValue, newValue);
     132            0 :     computeShape();
     133            0 : }
     134              : 
     135              : //---------------------------------------------------------
     136              : //   localSpatiumChanged
     137              : //    the scale of a staff changed
     138              : //---------------------------------------------------------
     139              : 
     140            0 : void TremoloSingleChord::localSpatiumChanged(double oldValue, double newValue)
     141              : {
     142            0 :     EngravingItem::localSpatiumChanged(oldValue, newValue);
     143            0 :     computeShape();
     144            0 : }
     145              : 
     146              : //---------------------------------------------------------
     147              : //   styleChanged
     148              : //    the scale of a staff changed
     149              : //---------------------------------------------------------
     150              : 
     151          274 : void TremoloSingleChord::styleChanged()
     152              : {
     153          274 :     EngravingItem::styleChanged();
     154          274 :     computeShape();
     155          274 : }
     156              : 
     157           65 : staff_idx_t TremoloSingleChord::vStaffIdx() const
     158              : {
     159           65 :     return chord() ? chord()->vStaffIdx() : EngravingItem::vStaffIdx();
     160              : }
     161              : 
     162              : //---------------------------------------------------------
     163              : //   basePath
     164              : //---------------------------------------------------------
     165              : 
     166         1008 : PainterPath TremoloSingleChord::basePath(double /*stretch*/) const
     167              : {
     168         1008 :     if (isBuzzRoll()) {
     169           64 :         return PainterPath();
     170              :     }
     171              : 
     172          944 :     const double sp = spatium() * chordMag();
     173              : 
     174          944 :     double w2  = sp * style().styleS(Sid::tremoloWidth).val() * .5;
     175          944 :     double lw  = sp * style().styleS(Sid::tremoloLineWidth).val();
     176          944 :     double td  = sp * style().styleS(Sid::tremoloDistance).val();
     177              : 
     178          944 :     PainterPath ppath;
     179              : 
     180              :     // first line
     181          944 :     ppath.addRect(-w2, 0.0, 2.0 * w2, lw);
     182          944 :     double ty = td;
     183              : 
     184              :     // other lines
     185         1921 :     for (int i = 1; i < m_lines; i++) {
     186          977 :         ppath.addRect(-w2, ty, 2.0 * w2, lw);
     187          977 :         ty += td;
     188              :     }
     189              : 
     190          944 :     Transform shearTransform;
     191          944 :     shearTransform.shear(0.0, -(lw / 2.0) / w2);
     192          944 :     ppath = shearTransform.map(ppath);
     193              : 
     194          944 :     return ppath;
     195          944 : }
     196              : 
     197          686 : void TremoloSingleChord::computeShape()
     198              : {
     199          686 :     if (isBuzzRoll()) {
     200           90 :         setbbox(symBbox(SymId::buzzRoll));
     201              :     } else {
     202          596 :         m_path = basePath();
     203          596 :         setbbox(m_path.boundingRect());
     204              :     }
     205          686 : }
     206              : 
     207            0 : TDuration TremoloSingleChord::durationType() const
     208              : {
     209            0 :     return m_durationType;
     210              : }
     211              : 
     212           89 : void TremoloSingleChord::setDurationType(TDuration d)
     213              : {
     214           89 :     if (m_durationType == d) {
     215            0 :         return;
     216              :     }
     217              : 
     218           89 :     m_durationType = d;
     219           89 :     styleChanged();
     220              : }
     221              : 
     222              : //---------------------------------------------------------
     223              : //   tremoloLen
     224              : //---------------------------------------------------------
     225              : 
     226            0 : Fraction TremoloSingleChord::tremoloLen() const
     227              : {
     228            0 :     Fraction f;
     229            0 :     switch (lines()) {
     230            0 :     case 1: f.set(1, 8);
     231            0 :         break;
     232            0 :     case 2: f.set(1, 16);
     233            0 :         break;
     234            0 :     case 3: f.set(1, 32);
     235            0 :         break;
     236            0 :     case 4: f.set(1, 64);
     237            0 :         break;
     238            0 :     case 5: f.set(1, 128);
     239            0 :         break;
     240            0 :     case 6: f.set(1, 256);
     241            0 :         break;
     242              :     }
     243            0 :     return f;
     244              : }
     245              : 
     246              : //---------------------------------------------------------
     247              : //   subtypeName
     248              : //---------------------------------------------------------
     249              : 
     250            1 : TranslatableString TremoloSingleChord::subtypeUserName() const
     251              : {
     252            1 :     return TConv::userName(tremoloType());
     253              : }
     254              : 
     255              : //---------------------------------------------------------
     256              : //   accessibleInfo
     257              : //---------------------------------------------------------
     258              : 
     259            0 : String TremoloSingleChord::accessibleInfo() const
     260              : {
     261            0 :     return String(u"%1: %2").arg(EngravingItem::accessibleInfo(), translatedSubtypeUserName());
     262              : }
     263              : 
     264              : //---------------------------------------------------------
     265              : //   getProperty
     266              : //---------------------------------------------------------
     267              : 
     268         1211 : PropertyValue TremoloSingleChord::getProperty(Pid propertyId) const
     269              : {
     270         1211 :     switch (propertyId) {
     271          110 :     case Pid::TREMOLO_TYPE:
     272          110 :         return int(m_tremoloType);
     273          110 :     case Pid::PLAY:
     274          110 :         return m_playTremolo;
     275          991 :     default:
     276          991 :         break;
     277              :     }
     278          991 :     return EngravingItem::getProperty(propertyId);
     279              : }
     280              : 
     281              : //---------------------------------------------------------
     282              : //   setProperty
     283              : //---------------------------------------------------------
     284              : 
     285            1 : bool TremoloSingleChord::setProperty(Pid propertyId, const PropertyValue& val)
     286              : {
     287            1 :     switch (propertyId) {
     288            0 :     case Pid::TREMOLO_TYPE:
     289            0 :         setTremoloType(TremoloType(val.toInt()));
     290            0 :         break;
     291            0 :     case Pid::PLAY:
     292            0 :         setPlayTremolo(val.toBool());
     293            0 :         break;
     294            1 :     default:
     295            1 :         return EngravingItem::setProperty(propertyId, val);
     296              :     }
     297            0 :     triggerLayout();
     298            0 :     return true;
     299              : }
     300              : 
     301              : //---------------------------------------------------------
     302              : //   propertyDefault
     303              : //---------------------------------------------------------
     304              : 
     305         1210 : PropertyValue TremoloSingleChord::propertyDefault(Pid propertyId) const
     306              : {
     307         1210 :     switch (propertyId) {
     308          110 :     case Pid::PLAY:
     309          110 :         return true;
     310         1100 :     default:
     311         1100 :         return EngravingItem::propertyDefault(propertyId);
     312              :     }
     313              : }
     314              : 
     315              : //---------------------------------------------------------
     316              : //   scanElements
     317              : //---------------------------------------------------------
     318              : 
     319            0 : void TremoloSingleChord::scanElements(std::function<void(EngravingItem*)> func)
     320              : {
     321            0 :     if (chord() && chord()->tremoloChordType() == TremoloChordType::TremoloSecondChord) {
     322            0 :         return;
     323              :     }
     324            0 :     EngravingItem::scanElements(func);
     325              : }
     326              : }
        

Generated by: LCOV version 2.0-1