LCOV - code coverage report
Current view: top level - src/engraving/dom - tuplet.h Coverage Total Hit
Test: filtered_coverage.info Lines: 86.0 % 43 37
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              : #pragma once
      24              : 
      25              : #include <set>
      26              : 
      27              : #include "durationelement.h"
      28              : #include "property.h"
      29              : #include "../types/types.h"
      30              : 
      31              : namespace mu::engraving {
      32              : class Text;
      33              : class Spanner;
      34              : 
      35              : //------------------------------------------------------------------------
      36              : //   @@ Tuplet
      37              : //!     Example of 1/8 triplet:
      38              : //!       _baseLen     = 1/8  (tuplet is measured in eighth notes)
      39              : //!       _ratio       = 3/2  (3 eighth tuplet notes played in the space of 2 regular eighth notes)
      40              : //!
      41              : //!    Entire tuplet has a duration of _baseLen * _ratio.denominator().
      42              : //!    A single tuplet note has duration of _baseLen * _ratio.denominator() / _ratio.numerator().
      43              : //------------------------------------------------------------------------
      44              : 
      45              : class Tuplet final : public DurationElement
      46              : {
      47         1708 :     OBJECT_ALLOCATOR(engraving, Tuplet)
      48          100 :     DECLARE_CLASSOF(ElementType::TUPLET)
      49              : 
      50              : public:
      51              :     Tuplet(DummyParentOr<Measure> parent);
      52              :     Tuplet(const Tuplet&);
      53              :     ~Tuplet();
      54              : 
      55              :     void setOwnershipParent(DummyParentOr<Measure> parent);
      56              : 
      57           48 :     Tuplet* clone() const override { return new Tuplet(*this); }
      58              :     void setTrack(track_idx_t val) override;
      59              : 
      60              :     void add(EngravingItem*) override;
      61              :     void remove(EngravingItem*) override;
      62              : 
      63        34674 :     Text* number() const { return m_number; }
      64         1058 :     void setNumber(Text* t) { m_number = t; }
      65              :     void resetNumberProperty();
      66              :     static void resetNumberProperty(Text* number);
      67              : 
      68              :     bool isEditable() const override;
      69              :     void startDragGrip(EditData&) override;
      70              :     void dragGrip(EditData&) override;
      71              : 
      72              :     void setSelected(bool f) override;
      73              : 
      74          741 :     Measure* measure() const override { return toMeasure(ownershipParent()); }
      75              : 
      76         3991 :     TupletNumberType numberType() const { return m_numberType; }
      77          148 :     TupletBracketType bracketType() const { return m_bracketType; }
      78         1525 :     void setNumberType(TupletNumberType val) { m_numberType = val; }
      79         1267 :     void setBracketType(TupletBracketType val) { m_bracketType = val; }
      80         7019 :     bool hasBracket() const { return m_hasBracket; }
      81         2029 :     void setHasBracket(bool b) { m_hasBracket = b; }
      82            0 :     Spatium bracketWidth() const { return m_bracketWidth; }
      83         1054 :     void setBracketWidth(Spatium s) { m_bracketWidth = s; }
      84              : 
      85       203730 :     const Fraction& ratio() const { return m_ratio; }
      86         1014 :     void setRatio(const Fraction& r) { m_ratio = r; }
      87              : 
      88            3 :     void setUserPoint1(PointF p) { m_userP1 = p; }
      89            3 :     void setUserPoint2(PointF p) { m_userP2 = p; }
      90              : 
      91        47776 :     const std::vector<DurationElement*>& elements() const { return m_currentElements; }
      92           18 :     void clear() { m_currentElements.clear(); }
      93         4164 :     bool contains(const DurationElement* el) const
      94              :     {
      95         4164 :         return std::find(m_currentElements.begin(), m_currentElements.end(), el) != m_currentElements.end();
      96              :     }
      97              : 
      98              :     void scanElements(std::function<void(EngravingItem*)> func) override;
      99              : 
     100              :     void reset() override;
     101              : 
     102         2512 :     TDuration baseLen() const { return m_baseLen; }
     103         1103 :     void setBaseLen(const TDuration& d) { m_baseLen = d; }
     104              : 
     105              :     void dump() const override;
     106              : 
     107         1303 :     void setDirection(DirectionV d) { m_direction = d; }
     108         2726 :     DirectionV direction() const { return m_direction; }
     109        18462 :     bool isUp() const { return m_isUp; }
     110         2029 :     void setIsUp(bool val) { m_isUp = val; }
     111         1798 :     bool isSmall() const { return m_isSmall; }
     112         3414 :     void setIsSmall(bool val) { m_isSmall = val; }
     113         4173 :     Fraction tick() const override { return m_tick; }
     114              :     Fraction rtick() const override;
     115         1114 :     void setTick(const Fraction& v) { m_tick = v; }
     116              :     Fraction elementsDuration();
     117              :     void sortElements();
     118              :     bool cross() const;
     119              :     staff_idx_t vStaffIdx() const override;
     120              : 
     121            0 :     const PointF& p1() const { return m_p1; }
     122        51824 :     PointF& p1() { return m_p1; }
     123         2029 :     void setP1(const PointF& p) { m_p1 = p; }
     124            0 :     const PointF& p2() const { return m_p2; }
     125        38315 :     PointF& p2() { return m_p2; }
     126         2029 :     void setP2(const PointF& p) { m_p2 = p; }
     127              : 
     128         2029 :     const PointF& userP1() const { return m_userP1; }
     129         2029 :     const PointF& userP2() const { return m_userP2; }
     130              : 
     131              :     void setVisible(bool f) override;
     132              :     void setColor(const Color& col) override;
     133              : 
     134              :     EngravingObject* propertyDelegate(Pid id) const override;
     135              :     PropertyValue getProperty(Pid propertyId) const override;
     136              :     bool setProperty(Pid propertyId, const PropertyValue& v) override;
     137              :     PropertyValue propertyDefault(Pid id) const override;
     138              : 
     139            0 :     bool needStartEditingAfterSelecting() const override { return true; }
     140              :     int gripsCount() const override;
     141            0 :     Grip initialEditModeGrip() const override { return Grip::MIDDLE; }
     142            0 :     Grip defaultGrip() const override { return Grip::MIDDLE; }
     143              :     std::vector<PointF> gripsPositions(const EditData&) const override;
     144              : 
     145              :     void sanitizeTuplet();
     146              :     void addMissingElements();
     147              : 
     148              :     bool calcHasBracket(const DurationElement* cr1, const DurationElement* cr2) const;
     149              : 
     150              :     static int computeTupletDenominator(int numerator, Fraction totalDuration);
     151              : 
     152              :     PointF bracketL[4];
     153              :     PointF bracketR[3];
     154              : 
     155              :     EngravingItem* nextElement() override;
     156              :     EngravingItem* prevElement() override;
     157              : 
     158              : private:
     159              : 
     160              :     friend class DurationElement;
     161              : 
     162              :     void addDurationElement(DurationElement* de);
     163              :     void removeDurationElement(DurationElement* de);
     164              : 
     165              :     Fraction addMissingElement(const Fraction& startTick, const Fraction& endTick);
     166              : 
     167              :     // All DurationElements where `tuplet()` returns this tuplet
     168              :     std::set<DurationElement*> m_allElements;
     169              : 
     170              :     // Those DurationElements that are currently really part of this tuplet
     171              :     std::vector<DurationElement*> m_currentElements;
     172              : 
     173              :     bool m_beingDestructed = false;
     174              : 
     175              :     DirectionV m_direction = DirectionV::AUTO;
     176              :     TupletNumberType m_numberType = TupletNumberType::SHOW_NUMBER;
     177              :     TupletBracketType m_bracketType = TupletBracketType::AUTO_BRACKET;
     178              :     Spatium m_bracketWidth;
     179              : 
     180              :     bool m_hasBracket = false;
     181              :     Fraction m_ratio;
     182              :     TDuration m_baseLen;        // 1/8 for a triplet of 1/8
     183              : 
     184              :     bool m_isUp = true;
     185              :     bool m_isSmall = true;
     186              : 
     187              :     Fraction m_tick;
     188              : 
     189              :     PointF m_p1, m_p2;
     190              :     PointF m_userP1, m_userP2;      // user offset
     191              : 
     192              :     Text* m_number = nullptr;
     193              : };
     194              : }
        

Generated by: LCOV version 2.0-1