fix (mostly) measure lines and click box text and meter markings
[ardour.git] / libs / ardour / ardour / history.h
1 /*
2     Copyright (C) 2001 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #ifndef __ardour_history_h__
22 #define __ardour_history_h__
23
24 #include <list>
25 #include <sigc++/signal.h>
26
27 template<class T>
28 //struct History : public SigC::Object 
29 struct History : public sigc::trackable
30 {
31     typedef list<T *> StateList;
32     
33     StateList states;
34     StateList::iterator current;
35
36     History() { current = states.end(); }
37     ~History() { states.erase (states.begin(), states.end()); }
38
39     sigc::signal<void> CurrentChanged;
40
41     void clear () {
42             for (StateList::iterator i = states.begin(); i != states.end(); i++) {
43                     delete *i;
44             }
45             states.clear ();
46             current = states.end();
47             CurrentChanged();
48     }
49
50     void push (T *state) {
51             /* remove any "undone" history above the current location
52                in the history, before pushing new state. 
53             */
54             if (current != states.begin() && current != states.end()) {
55                     states.erase (states.begin(), current);
56             }
57             current = states.insert (states.begin(), state);
58             CurrentChanged ();
59     }
60
61     T *top() { 
62             if (current != states.end()) {
63                     return *current;
64             } else {
65                     return 0;
66             }
67     }
68
69     T *pop (bool remove) {
70         if (current == states.end()) {
71                 return 0;
72         }
73         
74         if (current == states.begin()) {
75                 return *current;
76         }
77         
78         current--;
79         T *state = *current;
80
81         if (remove) {
82                 states.erase (current);
83         }
84
85         CurrentChanged ();
86         return state;
87     }   
88
89     T *earlier (uint32_t n) {
90             StateList::iterator i;
91             
92             if (current == states.end()) {
93                     return 0;
94             }
95             
96             if (n == 0) {
97                     return *current;
98             }
99             
100             /* the list is in LIFO order, so move toward the end to go "earlier" */
101             
102             for (i = current; n && i != states.end(); i++, n--);
103             
104             if (i == states.end()) {
105                     return 0;
106             } else {
107                     current = i;
108                     CurrentChanged ();
109                     return *i;
110             }
111     }
112
113     T *later (uint32_t n) {
114             StateList::iterator i;
115             
116             if (current == states.end()) {
117                     return 0;
118             }
119             
120             if (n == 0) {
121                     return *current;
122             }
123             
124             /* the list is in LIFO order, so move toward the beginning to go "later" */
125             
126             for (i = current; n && i != states.begin(); i--, n--);
127             if (i != current) {
128                     current = i;
129                     CurrentChanged();
130             }
131             return *i;
132     }
133
134     T *nth (uint32_t n) {
135             StateList::iterator i;
136             
137             for (i = states.begin(); n && i != states.end(); n--, i++);
138             
139             if (i != states.end()) {
140                     if (i != current) {
141                             current = i;
142                             CurrentChanged ();
143                     }
144                     return *i;
145             } else {
146                     return 0;
147             }
148     }
149     
150 };
151
152 #endif /* __ardour_history_h__ */
153