1 /*
2  * Hydrogen
3  * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4  *
5  * http://www.hydrogen-music.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY, without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 #ifndef ACTION_H
23 #define ACTION_H
24 #include <hydrogen/object.h>
25 #include <map>
26 #include <string>
27 #include <cassert>
28 
29 using namespace std;
30 
31 
32 class Action : public H2Core::Object {
33 	H2_OBJECT
34 	public:
35 		Action( QString );
36 
setParameter1(QString text)37 		void setParameter1( QString text ){
38 			parameter1 = text;
39 		}
40 
setParameter2(QString text)41 		void setParameter2( QString text ){
42 			parameter2 = text;
43 		}
44 
getParameter1()45 		QString getParameter1(){
46 			return parameter1;
47 		}
48 
getParameter2()49 		QString getParameter2(){
50 			return parameter2;
51 		}
52 
getType()53 		QString getType(){
54 			return type;
55 		}
56 
57 	private:
58 		QString type;
59 		QString parameter1;
60 		QString parameter2;
61 };
62 
63 namespace H2Core
64 {
65 	class Hydrogen;
66 }
67 
68 class MidiActionManager : public H2Core::Object
69 {
70 	H2_OBJECT
71 	private:
72 		/**
73 		 * Object holding the current MidiActionManager
74 		 * singleton. It is initialized with NULL, set with
75 		 * create_instance(), and accessed with
76 		 * get_instance().
77 		 */
78 		static MidiActionManager *__instance;
79 
80 		/**
81 		 * Holds the names of all Action identfiers which Hydrogen is
82 		 * able to interpret.
83 		 */
84 		QStringList actionList;
85 
86 		/**
87 		 * Contains all information to find a particular object in a
88 		 * list of objects, like an effect among all LADSPA effects
89 		 * present or an individual sample.
90 		 */
91 		struct targeted_element {
92 			/**First level index, like the ID of an Effect or and InstrumentComponent.*/
93 			int _id;
94 			/**Second level index, like the ID of an InstrumentLayer.*/
95 			int _subId;
96 		};
97 
98 		typedef bool (MidiActionManager::*action_f)(Action * , H2Core::Hydrogen * , targeted_element );
99 		/**
100 		 * Holds all Action identifiers which Hydrogen is able to
101 		 * interpret.
102 		 *
103 		 * It holds pointer to member function.
104 		 */
105 		map<string, pair<action_f, targeted_element> > actionMap;
106 
107 		bool play(Action * , H2Core::Hydrogen * , targeted_element );
108 		bool play_stop_pause_toggle(Action * , H2Core::Hydrogen * , targeted_element );
109 		bool stop(Action * , H2Core::Hydrogen * , targeted_element );
110 		bool pause(Action * , H2Core::Hydrogen * , targeted_element );
111 		bool record_ready(Action * , H2Core::Hydrogen * , targeted_element );
112 		bool record_strobe_toggle(Action * , H2Core::Hydrogen * , targeted_element );
113 		bool record_strobe(Action * , H2Core::Hydrogen * , targeted_element );
114 		bool record_exit(Action * , H2Core::Hydrogen * , targeted_element );
115 		bool mute(Action * , H2Core::Hydrogen * , targeted_element );
116 		bool unmute(Action * , H2Core::Hydrogen * , targeted_element );
117 		bool mute_toggle(Action * , H2Core::Hydrogen * , targeted_element );
118 		bool strip_mute_toggle(Action * , H2Core::Hydrogen * , targeted_element );
119 		bool strip_solo_toggle(Action * , H2Core::Hydrogen * , targeted_element );
120 		bool next_bar(Action * , H2Core::Hydrogen * , targeted_element );
121 		bool previous_bar(Action * , H2Core::Hydrogen * , targeted_element );
122 		bool bpm_increase(Action * , H2Core::Hydrogen * , targeted_element );
123 		bool bpm_decrease(Action * , H2Core::Hydrogen * , targeted_element );
124 		bool bpm_cc_relative(Action * , H2Core::Hydrogen * , targeted_element );
125 		bool bpm_fine_cc_relative(Action * , H2Core::Hydrogen * , targeted_element );
126 		bool master_volume_relative(Action * , H2Core::Hydrogen * , targeted_element );
127 		bool master_volume_absolute(Action * , H2Core::Hydrogen * , targeted_element );
128 		bool strip_volume_relative(Action * , H2Core::Hydrogen * , targeted_element );
129 		bool strip_volume_absolute(Action * , H2Core::Hydrogen * , targeted_element );
130 		bool effect_level_relative(Action * , H2Core::Hydrogen * , targeted_element );
131 		bool effect_level_absolute(Action * , H2Core::Hydrogen * , targeted_element );
132 		bool select_next_pattern(Action * , H2Core::Hydrogen * , targeted_element );
133 		bool select_only_next_pattern(Action * , H2Core::Hydrogen * , targeted_element );
134 		bool select_next_pattern_cc_absolute(Action * , H2Core::Hydrogen * , targeted_element );
135 		bool select_next_pattern_promptly(Action * , H2Core::Hydrogen * , targeted_element );
136 		bool select_next_pattern_relative(Action * , H2Core::Hydrogen * , targeted_element );
137 		bool select_and_play_pattern(Action * , H2Core::Hydrogen * , targeted_element );
138 		bool pan_relative(Action * , H2Core::Hydrogen * , targeted_element );
139 		bool pan_absolute(Action * , H2Core::Hydrogen * , targeted_element );
140 		bool filter_cutoff_level_absolute(Action * , H2Core::Hydrogen * , targeted_element );
141 		bool beatcounter(Action * , H2Core::Hydrogen * , targeted_element );
142 		bool tap_tempo(Action * , H2Core::Hydrogen * , targeted_element );
143 		bool playlist_song(Action * , H2Core::Hydrogen * , targeted_element );
144 		bool playlist_next_song(Action * , H2Core::Hydrogen * , targeted_element );
145 		bool playlist_previous_song(Action * , H2Core::Hydrogen * , targeted_element );
146 		bool toggle_metronome(Action * , H2Core::Hydrogen * , targeted_element );
147 		bool select_instrument(Action * , H2Core::Hydrogen * , targeted_element );
148 		bool undo_action(Action * , H2Core::Hydrogen * , targeted_element );
149 		bool redo_action(Action * , H2Core::Hydrogen * , targeted_element );
150 		bool gain_level_absolute(Action * , H2Core::Hydrogen * , targeted_element );
151 		bool pitch_level_absolute(Action * , H2Core::Hydrogen * , targeted_element );
152 
153 		// Actions required for session management.
154 		/**
155 		 * Create an empty Song which will be stored at to the path
156 		 * provided in @a pAction.
157 		 *
158 		 * This will be done without immediately and without saving
159 		 * the current #Song. All unsaved changes will be lost! In
160 		 * addition, the new Song won't be saved by this function. You
161 		 * can do so using save_song().
162 		 *
163 		 * The intended use of this function for session
164 		 * management. Therefore the function will *not* store the
165 		 * provided in Preferences::m_lastSongFilename and thus
166 		 * Hydrogen does not resumes with the particular #Song upon
167 		 * restarting.
168 		 *
169 		 * Right now the function is only able to handle the provided
170 		 * path as is. Therefore it is important to provide an absolute
171 		 * path to a .h2song file.
172 		 *
173 		 * \param pAction Action "NEW_SONG" uniquely triggering this function.
174 		 * \param pHydrogen Pointer to the instance of the Hydrogen singleton.
175 		 * \param element Unused.
176 		 * \return true on success
177 		 */
178 		bool new_song(Action* pAction, H2Core::Hydrogen* pHydrogen, targeted_element element);
179 		/**
180 		 * Opens the Song specified in the path provided in @a
181 		 * pAction.
182 		 *
183 		 * This will be done without immediately and without saving
184 		 * the current #Song. All unsaved changes will be lost!
185 		 *
186 		 * The intended use of this function for session
187 		 * management. Therefore the function will *not* store the
188 		 * provided in Preferences::m_lastSongFilename and thus
189 		 * Hydrogen does not resumes with the particular #Song upon
190 		 * restarting.
191 		 *
192 		 * Right now the function is only able to handle the provided
193 		 * path as is. Therefore it is important to provide an absolute
194 		 * path to a .h2song file.
195 		 *
196 		 * \param pAction Action "OPEN_SONG" uniquely triggering this function.
197 		 * \param pHydrogen Pointer to the instance of the Hydrogen singleton.
198 		 * \param element Unused.
199 		 * \return true on success
200 		 */
201 		bool open_song(Action* pAction, H2Core::Hydrogen* pHydrogen, targeted_element element);
202 		/**
203 		 * Saves the current #Song.
204 		 *
205 		 * The intended use of this function for session
206 		 * management. Therefore the function will *not* store the
207 		 * provided in Preferences::m_lastSongFilename and thus
208 		 * Hydrogen does not resumes with the particular #Song upon
209 		 * restarting.
210 		 *
211 		 * \param pAction Action "SAVE_SONG" uniquely triggering this function.
212 		 * \param pHydrogen Pointer to the instance of the Hydrogen singleton.
213 		 * \param element Unused.
214 		 * \return true on success
215 		 */
216 		bool save_song(Action* pAction, H2Core::Hydrogen* pHydrogen, targeted_element element);
217 		/**
218 		 * Saves the current Song to the path provided in @a pAction.
219 		 *
220 		 * The intended use of this function for session
221 		 * management. Therefore the function will *not* store the
222 		 * provided in Preferences::m_lastSongFilename and thus
223 		 * Hydrogen does not resumes with the particular #Song upon
224 		 * restarting.
225 		 *
226 		 * \param pAction Action "SAVE_SONG_AS" uniquely triggering this function.
227 		 * \param pHydrogen Pointer to the instance of the Hydrogen singleton.
228 		 * \param element Unused.
229 		 * \return true on success
230 		 */
231 		bool save_song_as(Action* pAction, H2Core::Hydrogen* pHydrogen, targeted_element element);
232 		/**
233 		 * Triggers the shutdown of Hydrogen.
234 		 *
235 		 * This will be done without immediately and without saving
236 		 * the current #Song. All unsaved changes will be lost!
237 		 *
238 		 * The shutdown will only be triggered if
239 		 * Hydrogen::m_bActiveGUI is true and the Qt5 GUI is present.
240 		 *
241 		 * \param pAction Action "QUIT" uniquely triggering this function.
242 		 * \param pHydrogen Pointer to the instance of the Hydrogen singleton.
243 		 * \param element Unused.
244 		 * \return true on success
245 		 */
246 		bool quit(Action* pAction, H2Core::Hydrogen* pHydrogen, targeted_element element);
247 
248 		QStringList eventList;
249 
250 		int m_nLastBpmChangeCCParameter;
251 
252 		/**
253 		 * Checks the path of the .h2song provided via OSC.
254 		 *
255 		 * It will be checked whether @a songPath
256 		 * - is absolute
257 		 * - has the '.h2song' suffix
258 		 * - is writable (if it exists)
259 		 *
260 		 * \param songPath Absolute path to an .h2song file.
261 		 * \return true - if valid.
262 		 */
263 		bool isSongPathValid( const QString& songPath );
264 
265 	public:
266 
267 		/**
268 		 * The handleAction method is the heart of the
269 		 * MidiActionManager class. It executes the operations that
270 		 * are needed to carry the desired action.
271 		 */
272 		bool handleAction( Action * );
273 		/**
274 		 * If #__instance equals 0, a new MidiActionManager
275 		 * singleton will be created and stored in it.
276 		 *
277 		 * It is called in H2Core::Hydrogen::create_instance().
278 		 */
279 		static void create_instance();
280 		/**
281 		 * Returns a pointer to the current MidiActionManager
282 		 * singleton stored in #__instance.
283 		 */
get_instance()284 		static MidiActionManager* get_instance() { assert(__instance); return __instance; }
285 
getActionList()286 		QStringList getActionList(){
287 			return actionList;
288 		}
289 
getEventList()290 		QStringList getEventList(){
291 			return eventList;
292 		}
293 
294 		MidiActionManager();
295 		~MidiActionManager();
296 };
297 #endif
298