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 <string>
29 #include <FL/Fl.H>
30 #include <FL/fl_draw.H>
31 #if defined(_WIN32)
32 #include "../ext/resource.h"
33 #elif defined(__linux__) || defined(__FreeBSD__)
34 #include <X11/xpm.h>
35 #endif
36 #include "core/mixer.h"
37 #include "core/mixerHandler.h"
38 #include "core/clock.h"
39 #include "core/plugins/pluginHost.h"
40 #include "core/conf.h"
41 #include "core/graphics.h"
42 #include "gui/dialogs/warnings.h"
43 #include "gui/dialogs/mainWindow.h"
44 #include "gui/dialogs/actionEditor/baseActionEditor.h"
45 #include "gui/dialogs/window.h"
46 #include "gui/dialogs/sampleEditor.h"
47 #include "gui/elems/mainWindow/mainIO.h"
48 #include "gui/elems/mainWindow/mainTimer.h"
49 #include "gui/elems/mainWindow/mainTransport.h"
50 #include "gui/elems/mainWindow/beatMeter.h"
51 #include "gui/elems/mainWindow/keyboard/keyboard.h"
52 #include "gui/elems/mainWindow/keyboard/channel.h"
53 #include "gui/elems/sampleEditor/waveTools.h"
54 #include "log.h"
55 #include "string.h"
56 #include "gui.h"
57
58
59 extern giada::v::gdMainWindow* G_MainWin;
60
61
62 namespace giada {
63 namespace u {
64 namespace gui
65 {
66 namespace
67 {
68 int blinker_ = 0;
69 } // {anonymous}
70
71
72 /* -------------------------------------------------------------------------- */
73 /* -------------------------------------------------------------------------- */
74 /* -------------------------------------------------------------------------- */
75
76
rebuildSubWindow(int wid)77 void rebuildSubWindow(int wid)
78 {
79 v::gdWindow* w = getSubwindow(G_MainWin, wid);
80 if(w != nullptr) // If its open
81 w->rebuild();
82 }
83
84
85 /* -------------------------------------------------------------------------- */
86
87
refreshSubWindow(int wid)88 void refreshSubWindow(int wid)
89 {
90 v::gdWindow* w = getSubwindow(G_MainWin, wid);
91 if(w != nullptr) // If its open
92 w->refresh();
93 }
94
95
96 /* -------------------------------------------------------------------------- */
97
98
refresh()99 void refresh()
100 {
101 /* Update dynamic elements inside main window: in and out meters, beat meter
102 and each channel. */
103
104 G_MainWin->refresh();
105
106 /* Compute timer for blinker. */
107
108 blinker_ = (blinker_ + 1) % 12;
109
110 /* Refresh Sample Editor (if open) for dynamic play head. */
111
112 refreshSubWindow(WID_SAMPLE_EDITOR);
113 }
114
115
116 /* -------------------------------------------------------------------------- */
117
118
rebuild()119 void rebuild()
120 {
121 G_MainWin->rebuild();
122 rebuildSubWindow(WID_FX_LIST);
123 rebuildSubWindow(WID_SAMPLE_EDITOR);
124 rebuildSubWindow(WID_ACTION_EDITOR);
125 }
126
127
128 /* -------------------------------------------------------------------------- */
129
130
shouldBlink()131 bool shouldBlink()
132 {
133 return blinker_ > 6;
134 }
135
136
137 /* -------------------------------------------------------------------------- */
138
139
updateStaticWidgets()140 void updateStaticWidgets()
141 {
142 using namespace giada::m;
143
144 G_MainWin->mainIO->setOutVol(mh::getOutVol());
145 G_MainWin->mainIO->setInVol(mh::getInVol());
146
147 #ifdef WITH_VST
148
149 // G_MainWin->mainIO->setMasterFxOutFull(pluginHost::getStack(pluginHost::StackType::MASTER_OUT).plugins.size() > 0);
150 // G_MainWin->mainIO->setMasterFxInFull(pluginHost::getStack(pluginHost::StackType::MASTER_IN).plugins.size() > 0);
151
152 #endif
153
154 G_MainWin->mainTimer->setMeter(clock::getBeats(), clock::getBars());
155 G_MainWin->mainTimer->setBpm(clock::getBpm());
156 G_MainWin->mainTimer->setQuantizer(clock::getQuantizerValue());
157 }
158
159
160 /* -------------------------------------------------------------------------- */
161
162
updateMainWinLabel(const std::string & s)163 void updateMainWinLabel(const std::string& s)
164 {
165 std::string out = std::string(G_APP_NAME) + " - " + s;
166 G_MainWin->copy_label(out.c_str());
167 }
168
169
170 /* -------------------------------------------------------------------------- */
171
172
setFavicon(v::gdWindow * w)173 void setFavicon(v::gdWindow* w)
174 {
175 #if defined(__linux__) || defined(__FreeBSD__)
176
177 fl_open_display();
178 Pixmap p, mask;
179 XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display),
180 (char **) giada_icon, &p, &mask, nullptr);
181 w->icon((char *)p);
182
183 #elif defined(_WIN32)
184
185 w->icon((char *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON1)));
186
187 #endif
188 }
189
190
191 /* -------------------------------------------------------------------------- */
192
193
openSubWindow(v::gdWindow * parent,v::gdWindow * child,int id)194 void openSubWindow(v::gdWindow* parent, v::gdWindow* child, int id)
195 {
196 if (parent->hasWindow(id)) {
197 u::log::print("[GU] parent has subwindow with id=%d, deleting\n", id);
198 parent->delSubWindow(id);
199 }
200 child->setId(id);
201 parent->addSubWindow(child);
202 }
203
204
205 /* -------------------------------------------------------------------------- */
206
207
refreshActionEditor()208 void refreshActionEditor()
209 {
210 v::gdBaseActionEditor* ae = static_cast<v::gdBaseActionEditor*>(G_MainWin->getChild(WID_ACTION_EDITOR));
211 if (ae != nullptr)
212 ae->rebuild();
213 }
214
215
216 /* -------------------------------------------------------------------------- */
217
218
getSubwindow(v::gdWindow * parent,int id)219 v::gdWindow* getSubwindow(v::gdWindow* parent, int id)
220 {
221 if (parent->hasWindow(id))
222 return parent->getChild(id);
223 else
224 return nullptr;
225 }
226
227
228 /* -------------------------------------------------------------------------- */
229
230
closeAllSubwindows()231 void closeAllSubwindows()
232 {
233 /* don't close WID_FILE_BROWSER, because it's the caller of this
234 * function */
235
236 G_MainWin->delSubWindow(WID_ACTION_EDITOR);
237 G_MainWin->delSubWindow(WID_SAMPLE_EDITOR);
238 G_MainWin->delSubWindow(WID_FX_LIST);
239 G_MainWin->delSubWindow(WID_FX);
240 }
241
242
243 /* -------------------------------------------------------------------------- */
244
245
getStringWidth(const std::string & s)246 int getStringWidth(const std::string& s)
247 {
248 int w = 0;
249 int h = 0;
250 fl_measure(s.c_str(), w, h);
251 return w;
252 }
253
254
255 /* -------------------------------------------------------------------------- */
256
257
removeFltkChars(const std::string & s)258 std::string removeFltkChars(const std::string& s)
259 {
260 std::string out = u::string::replace(s, "/", "-");
261 out = u::string::replace(out, "|", "-");
262 out = u::string::replace(out, "&", "-");
263 out = u::string::replace(out, "_", "-");
264 return out;
265 }
266
267
268 /* -------------------------------------------------------------------------- */
269
270
truncate(const std::string & s,Pixel width)271 std::string truncate(const std::string& s, Pixel width)
272 {
273 if (s.empty() || getStringWidth(s) <= width)
274 return s;
275
276 std::string tmp = s;
277 std::size_t size = tmp.size();
278
279 while (getStringWidth(tmp + "...") > width) {
280 if (size == 0)
281 return "";
282 tmp.resize(--size);
283 }
284
285 return tmp + "...";
286 }
287
288 /* -------------------------------------------------------------------------- */
289
290
centerWindowX(int w)291 int centerWindowX(int w)
292 {
293 return (Fl::w() / 2) - (w / 2);
294 }
295
296
centerWindowY(int h)297 int centerWindowY(int h)
298 {
299 return (Fl::h() / 2) - (h / 2);
300 }
301 }}} // giada::u::gui::
302