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