1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 
19 #include "ChangingSegment.h"
20 
21 #include "SegmentRect.h"
22 #include "base/SnapGrid.h"
23 
24 #include <QRect>
25 
26 #include <math.h>
27 
28 
29 namespace Rosegarden
30 {
31 
32 
ChangingSegment(Segment & s,const SegmentRect & rect)33 ChangingSegment::ChangingSegment(Segment &s, const SegmentRect &rect)
34         : m_segment(s),
35         m_rect(rect),
36         m_z(0)
37 {}
38 
rect() const39 QRect ChangingSegment::rect() const
40 {
41     QRect res = m_rect.rect;
42 
43     // For repeating segments, use the base width
44     if (m_rect.isRepeating()) {
45         res.setWidth(m_rect.baseWidth);
46     }
47 
48     return res;
49 }
50 
getRepeatTimeAt(const SnapGrid & grid,const QPoint & pos)51 timeT ChangingSegment::getRepeatTimeAt(const SnapGrid &grid, const QPoint &pos)
52 {
53     timeT startTime = m_segment.getStartTime();
54     timeT repeatInterval = m_segment.getEndMarkerTime() - startTime;
55 
56     int repeatWidth = int(nearbyint(grid.getRulerScale()->getXForTime(repeatInterval)));
57 
58     int count = (pos.x() - rect().x()) / repeatWidth;
59 
60     // Let the caller know that the position was not within a repeat.
61     if (count == 0)
62         return 0;
63 
64     return startTime + count * repeatInterval;
65 }
66 
setStartTime(timeT time,const SnapGrid & grid)67 void ChangingSegment::setStartTime(timeT time, const SnapGrid &grid)
68 {
69     int x = int(nearbyint(grid.getRulerScale()->getXForTime(time)));
70 
71     int curX = rect().x();
72     m_rect.rect.setX(x);
73     if (m_rect.isRepeating()) {
74         int deltaX = curX - x;
75         int curW = m_rect.baseWidth;
76         m_rect.baseWidth = curW + deltaX;
77     }
78 }
79 
getStartTime(const SnapGrid & grid)80 timeT ChangingSegment::getStartTime(const SnapGrid &grid)
81 {
82     //return std::max(grid.snapX(item->rect().x()), 0L); - wrong, we can have negative start times,
83         // and if we do this we 'crop' segments when they are moved before the start of the composition
84 
85     return grid.snapX(m_rect.rect.x());
86 }
87 
setEndTime(timeT time,const SnapGrid & grid)88 void ChangingSegment::setEndTime(timeT time, const SnapGrid &grid)
89 {
90     int x = int(nearbyint(grid.getRulerScale()->getXForTime(time)));
91     QRect r = rect();
92     QPoint topRight = r.topRight();
93     topRight.setX(x);
94     r.setTopRight(topRight);
95     m_rect.rect.setWidth(r.width());
96 
97     if (m_rect.isRepeating()) {
98         m_rect.baseWidth = r.width();
99     }
100 }
101 
getEndTime(const SnapGrid & grid)102 timeT ChangingSegment::getEndTime(const SnapGrid &grid)
103 {
104     QRect itemRect = rect();
105 
106     return std::max(grid.snapX(itemRect.x() + itemRect.width()), 0L);
107 }
108 
getTrackPos(const SnapGrid & grid)109 int ChangingSegment::getTrackPos(const SnapGrid &grid)
110 {
111     return grid.getYBin(rect().y());
112 }
113 
114 
115 }
116