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