1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 /*
3     Rosegarden
4     A MIDI and audio sequencer and musical notation editor.
5     Copyright 2000-2021 the Rosegarden development team.
6 
7     Other copyrights also apply to some parts of this work.  Please
8     see the AUTHORS file and individual file headers for details.
9 
10     This program is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License as
12     published by the Free Software Foundation; either version 2 of the
13     License, or (at your option) any later version.  See the file
14     COPYING included with this distribution for more information.
15 */
16 
17 #ifndef RG_LAYOUT_ENGINE_H
18 #define RG_LAYOUT_ENGINE_H
19 
20 #include "RulerScale.h"
21 
22 namespace Rosegarden {
23 
24 class ViewSegment;
25 class TimeSignature;
26 
27 
28 /**
29  * Base classes for layout engines.  The intention is that
30  * different sorts of renderers (piano-roll, score etc) can be
31  * implemented by simply plugging different implementations
32  * of ViewSegment and LayoutEngine into a single view class.
33  */
34 class LayoutEngine
35 {
36 public:
LayoutEngine()37     LayoutEngine() { }
~LayoutEngine()38     virtual ~LayoutEngine() { }
39 
40     /**
41      * Resets internal data stores for all segments
42      */
43     virtual void reset() = 0;
44 
45     /**
46      * Precomputes layout data for a single segment, updating any
47      * internal data stores associated with that segment and updating
48      * any layout-related properties in the events on the segment's
49      * segment.
50      *
51      * If full == true, a complete rescan of the entire composition is
52      * in progress and the segment is known to be contained completely
53      * within the start to end time range (which may extend beyond the
54      * segment at either end).  Otherwise, the start to end time
55      * represents the modified range of the segment.
56      */
57     virtual void scanViewSegment(ViewSegment &viewSegment,
58 				 timeT startTime,
59 				 timeT endTime,
60                                  bool full) = 0;
61 
62     /**
63      * Computes any layout data that may depend on the results of
64      * scanning more than one segment.  This may mean doing most of
65      * the layout (likely for horizontal layout) or nothing at all
66      * (likely for vertical layout).
67      *
68      * If full == true, a complete relayout of the entire composition
69      * is in progress and the segment is known to be contained
70      * completely within the start to end time range (which may extend
71      * beyond the segment at either end).  Otherwise, the start to end
72      * time represents the modified range of the segment.
73      */
74     virtual void finishLayout(timeT startTime,
75                               timeT endTime,
76                               bool full) = 0;
77 
getStatus()78     unsigned int getStatus() const { return m_status; }
79 
80 protected:
81     unsigned int m_status;
82 };
83 
84 
85 class HorizontalLayoutEngine : public LayoutEngine,
86 				public RulerScale
87 {
88 public:
HorizontalLayoutEngine(Composition * c)89     HorizontalLayoutEngine(Composition *c) : LayoutEngine(), RulerScale(c) { }
~HorizontalLayoutEngine()90     ~HorizontalLayoutEngine() override { }
91 
92     /**
93      * Sets a page width for the layout.
94      *
95      * A layout implementation does not have to use this.  Some might
96      * use it (for example) to ensure that bar lines fall precisely at
97      * the right-hand margin of each page.  The computed x-coordinates
98      * will still require to be wrapped into lines by the segment or
99      * view implementation, however.
100      *
101      * A width of zero indicates no requirement for division into
102      * pages.
103      */
setPageWidth(double)104     virtual void setPageWidth(double) { /* default: ignore it */ }
105 
106     /**
107      * Returns the number of the first visible bar line on the given
108      * segment
109      */
getFirstVisibleBarOnViewSegment(ViewSegment &)110     virtual int getFirstVisibleBarOnViewSegment(ViewSegment &) const {
111         return  getFirstVisibleBar();
112     }
113 
114     /**
115      * Returns the number of the last visible bar line on the given
116      * segment
117      */
getLastVisibleBarOnViewSegment(ViewSegment &)118     virtual int getLastVisibleBarOnViewSegment(ViewSegment &) const {
119         return  getLastVisibleBar();
120     }
121 
122     /**
123      * Returns true if the specified bar has the correct length
124      */
isBarCorrectOnViewSegment(ViewSegment &,int)125     virtual bool isBarCorrectOnViewSegment(ViewSegment &, int/* barNo */) const {
126         return true;
127     }
128 
129     /**
130      * Returns true if there is a new time signature in the given bar,
131      * setting timeSignature appropriately and setting timeSigX to its
132      * x-coord
133      */
getTimeSignaturePosition(ViewSegment &,int,TimeSignature &,double &)134     virtual bool getTimeSignaturePosition
135     (ViewSegment &, int /* barNo */, TimeSignature &, double &/* timeSigX */) const {
136         return 0;
137     }
138 };
139 
140 
141 
142 class VerticalLayoutEngine : public LayoutEngine
143 {
144 public:
VerticalLayoutEngine()145     VerticalLayoutEngine() { }
~VerticalLayoutEngine()146     ~VerticalLayoutEngine() override { }
147 
148     // I don't think we need to add anything here for now
149 };
150 
151 }
152 
153 
154 #endif
155