1 /* -----------------------------------------------------------------------------
2  *
3  * Giada - Your Hardcore Loopmachine
4  *
5  * -----------------------------------------------------------------------------
6  *
7  * Copyright (C) 2010-2020 Giovanni A. Zuliani | Monocasual
8  *
9  * This file is part of Giada - Your Hardcore Loopmachine.
10  *
11  * Giada - Your Hardcore Loopmachine is free software: you can
12  * redistribute it and/or modify it under the terms of the GNU General
13  * Public License as published by the Free Software Foundation, either
14  * version 3 of the License, or (at your option) any later version.
15  *
16  * Giada - Your Hardcore Loopmachine is distributed in the hope that it
17  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with Giada - Your Hardcore Loopmachine. If not, see
23  * <http://www.gnu.org/licenses/>.
24  *
25  * -------------------------------------------------------------------------- */
26 
27 
28 #include "core/const.h"
29 #include "core/graphics.h"
30 #include "core/clock.h"
31 #include "glue/main.h"
32 #include "glue/events.h"
33 #include "utils/gui.h"
34 #include "utils/string.h"
35 #include "gui/elems/basics/button.h"
36 #include "gui/elems/basics/choice.h"
37 #include "gui/dialogs/mainWindow.h"
38 #include "gui/dialogs/bpmInput.h"
39 #include "gui/dialogs/beatsInput.h"
40 #include "mainTimer.h"
41 
42 
43 extern giada::v::gdMainWindow* G_MainWin;
44 
45 
46 namespace giada {
47 namespace v
48 {
geMainTimer(int x,int y)49 geMainTimer::geMainTimer(int x, int y)
50 : gePack      (x, y, Direction::HORIZONTAL)
51 , m_bpm       (0, 0, 60, G_GUI_UNIT)
52 , m_meter     (0, 0, 60, G_GUI_UNIT)
53 , m_quantizer (0, 0, 60, G_GUI_UNIT, "", false)
54 , m_multiplier(0, 0, G_GUI_UNIT, G_GUI_UNIT, "", multiplyOff_xpm, multiplyOn_xpm)
55 , m_divider   (0, 0, G_GUI_UNIT, G_GUI_UNIT, "", divideOff_xpm, divideOn_xpm)
56 {
57 	add(&m_quantizer);
58 	add(&m_bpm);
59 	add(&m_meter);
60 	add(&m_multiplier);
61 	add(&m_divider);
62 
63 	resizable(nullptr);   // don't resize any widget
64 
65 	m_bpm.callback(cb_bpm, (void*)this);
66 	m_meter.callback(cb_meter, (void*)this);
67 	m_multiplier.callback(cb_multiplier, (void*)this);
68 	m_divider.callback(cb_divider, (void*)this);
69 
70 	m_quantizer.add("off", 0, cb_quantizer, (void*)this);
71 	m_quantizer.add("1\\/1", 0, cb_quantizer, (void*)this);
72 	m_quantizer.add("1\\/2", 0, cb_quantizer, (void*)this);
73 	m_quantizer.add("1\\/3", 0, cb_quantizer, (void*)this);
74 	m_quantizer.add("1\\/4", 0, cb_quantizer, (void*)this);
75 	m_quantizer.add("1\\/6", 0, cb_quantizer, (void*)this);
76 	m_quantizer.add("1\\/8", 0, cb_quantizer, (void*)this);
77 	m_quantizer.value(0); //  "off" by default
78 }
79 
80 
81 /* -------------------------------------------------------------------------- */
82 
83 
cb_bpm(Fl_Widget *,void * p)84 void geMainTimer::cb_bpm       (Fl_Widget* /*w*/, void* p) { ((geMainTimer*)p)->cb_bpm(); }
cb_meter(Fl_Widget *,void * p)85 void geMainTimer::cb_meter     (Fl_Widget* /*w*/, void* p) { ((geMainTimer*)p)->cb_meter(); }
cb_quantizer(Fl_Widget *,void * p)86 void geMainTimer::cb_quantizer (Fl_Widget* /*w*/, void* p) { ((geMainTimer*)p)->cb_quantizer(); }
cb_multiplier(Fl_Widget *,void * p)87 void geMainTimer::cb_multiplier(Fl_Widget* /*w*/, void* p) { ((geMainTimer*)p)->cb_multiplier(); }
cb_divider(Fl_Widget *,void * p)88 void geMainTimer::cb_divider   (Fl_Widget* /*w*/, void* p) { ((geMainTimer*)p)->cb_divider(); }
89 
90 
91 /* -------------------------------------------------------------------------- */
92 
93 
cb_bpm()94 void geMainTimer::cb_bpm()
95 {
96 	u::gui::openSubWindow(G_MainWin, new gdBpmInput(m_bpm.label()), WID_BPM);
97 }
98 
99 
100 /* -------------------------------------------------------------------------- */
101 
102 
cb_meter()103 void geMainTimer::cb_meter()
104 {
105 	u::gui::openSubWindow(G_MainWin, new gdBeatsInput(), WID_BEATS);
106 }
107 
108 
109 /* -------------------------------------------------------------------------- */
110 
111 
cb_quantizer()112 void geMainTimer::cb_quantizer()
113 {
114 	c::main::quantize(m_quantizer.value());
115 }
116 
117 
118 /* -------------------------------------------------------------------------- */
119 
120 
cb_multiplier()121 void geMainTimer::cb_multiplier()
122 {
123 	c::events::multiplyBeats();
124 }
125 
126 
127 /* -------------------------------------------------------------------------- */
128 
129 
cb_divider()130 void geMainTimer::cb_divider()
131 {
132 	c::events::divideBeats();
133 }
134 
135 
136 /* -------------------------------------------------------------------------- */
137 
138 
refresh()139 void geMainTimer::refresh()
140 {
141 	m_timer = c::main::getTimer();
142 
143 	if (m_timer.isRecordingInput) {
144 		m_bpm.deactivate();
145 		m_meter.deactivate();
146 		m_multiplier.deactivate();
147 		m_divider.deactivate();
148 	}
149 	else {
150 #if defined(G_OS_LINUX) || defined(G_OS_FREEBSD)
151 		/* Don't reactivate m_bpm when using JACK. It must stay disabled. */
152 		if (m_timer.isUsingJack)
153 			m_bpm.deactivate();
154 		else
155 			m_bpm.activate();
156 #else
157 		m_bpm.activate();
158 #endif
159 		m_meter.activate();
160 		m_multiplier.activate();
161 		m_divider.activate();
162 	}
163 }
164 
165 
166 /* -------------------------------------------------------------------------- */
167 
168 
rebuild()169 void geMainTimer::rebuild()
170 {
171 	m_timer = c::main::getTimer();
172 
173 	setBpm(m_timer.bpm);
174 	setMeter(m_timer.beats, m_timer.bars);
175 	setQuantizer(m_timer.quantize);
176 
177 #if defined(G_OS_LINUX) || defined(G_OS_FREEBSD)
178 	/* Can't change m_bpm from within Giada when using JACK. */
179 	if (m_timer.isUsingJack)
180 		m_bpm.deactivate();
181 #endif
182 }
183 
184 
185 /* -------------------------------------------------------------------------- */
186 
187 
setBpm(const char * v)188 void geMainTimer::setBpm(const char* v)
189 {
190 	m_bpm.copy_label(v);
191 }
192 
193 
setBpm(float v)194 void geMainTimer::setBpm(float v)
195 {
196 	m_bpm.copy_label(u::string::fToString((float) v, 1).c_str()); // Only 1 decimal place (e.g. 120.0)
197 }
198 
199 
200 /* -------------------------------------------------------------------------- */
201 
202 
setLock(bool v)203 void geMainTimer::setLock(bool v)
204 {
205   if (v) {
206     m_bpm.deactivate();
207     m_meter.deactivate();
208     m_multiplier.deactivate();
209     m_divider.deactivate();
210   }
211   else {
212     m_bpm.activate();
213     m_meter.activate();
214     m_multiplier.activate();
215     m_divider.activate();
216   }
217 }
218 
219 
220 /* -------------------------------------------------------------------------- */
221 
222 
setQuantizer(int q)223 void geMainTimer::setQuantizer(int q)
224 {
225 	m_quantizer.value(q);
226 }
227 
228 
229 /* -------------------------------------------------------------------------- */
230 
231 
setMeter(int beats,int bars)232 void geMainTimer::setMeter(int beats, int bars)
233 {
234 	std::string s = std::to_string(beats) + "/" + std::to_string(bars);
235 	m_meter.copy_label(s.c_str());
236 }
237 
238 }} // giada::v::
239