1 |
schoenebeck |
2610 |
/* |
2 |
schoenebeck |
3197 |
Copyright (c) 2014 - 2017 Christian Schoenebeck |
3 |
schoenebeck |
2610 |
|
4 |
|
|
This file is part of "gigedit" and released under the terms of the |
5 |
|
|
GNU General Public License version 2. |
6 |
|
|
*/ |
7 |
|
|
|
8 |
|
|
#include "scriptslots.h" |
9 |
|
|
#include "global.h" |
10 |
schoenebeck |
3364 |
#include "compat.h" |
11 |
schoenebeck |
2610 |
|
12 |
|
|
ScriptSlots::ScriptSlots() : |
13 |
schoenebeck |
3364 |
#if HAS_GTKMM_STOCK |
14 |
schoenebeck |
3158 |
m_closeButton(Gtk::Stock::CLOSE) |
15 |
schoenebeck |
3364 |
#else |
16 |
|
|
m_closeButton(_("_Close"), true) |
17 |
|
|
#endif |
18 |
schoenebeck |
2610 |
{ |
19 |
|
|
m_instrument = NULL; |
20 |
|
|
|
21 |
schoenebeck |
3364 |
#if !HAS_GTKMM_STOCK |
22 |
|
|
m_closeButton.set_icon_name("window-close"); |
23 |
|
|
#endif |
24 |
|
|
|
25 |
schoenebeck |
3225 |
if (!Settings::singleton()->autoRestoreWindowDimension) { |
26 |
|
|
set_default_size(460,300); |
27 |
|
|
set_position(Gtk::WIN_POS_MOUSE); |
28 |
|
|
} |
29 |
|
|
|
30 |
schoenebeck |
2610 |
add(m_vbox); |
31 |
|
|
|
32 |
|
|
m_generalInfoLabel.set_text(_( |
33 |
|
|
"Each row (\"slot\") references one instrument script that shall be " |
34 |
|
|
"executed by the sampler for currently selected instrument. Slots are " |
35 |
|
|
"executed consecutively from top down." |
36 |
|
|
)); |
37 |
|
|
m_generalInfoLabel.set_line_wrap(); |
38 |
|
|
m_vbox.pack_start(m_generalInfoLabel, Gtk::PACK_SHRINK); |
39 |
|
|
|
40 |
|
|
m_dragHintLabel.set_text(_( |
41 |
|
|
"Drag & drop a script from main window to this window to add a new " |
42 |
|
|
"script slot for this instrument." |
43 |
|
|
)); |
44 |
|
|
m_dragHintLabel.set_line_wrap(); |
45 |
|
|
m_scrolledWindow.add(m_vboxSlots); |
46 |
|
|
m_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); |
47 |
|
|
m_vbox.pack_start(m_scrolledWindow); |
48 |
|
|
|
49 |
|
|
m_vbox.pack_start(m_dragHintLabel, Gtk::PACK_SHRINK); |
50 |
|
|
|
51 |
|
|
m_buttonBox.set_layout(Gtk::BUTTONBOX_END); |
52 |
|
|
m_buttonBox.pack_start(m_closeButton); |
53 |
|
|
m_closeButton.set_can_default(); |
54 |
|
|
m_closeButton.grab_focus(); |
55 |
|
|
m_vbox.pack_start(m_buttonBox, Gtk::PACK_SHRINK); |
56 |
|
|
|
57 |
|
|
m_closeButton.signal_clicked().connect( |
58 |
|
|
sigc::mem_fun(*this, &ScriptSlots::onButtonClose) |
59 |
|
|
); |
60 |
|
|
|
61 |
|
|
signal_hide().connect( |
62 |
|
|
sigc::mem_fun(*this, &ScriptSlots::onWindowHide) |
63 |
|
|
); |
64 |
|
|
|
65 |
|
|
// establish drag&drop between scripts tree view on main diwno and this |
66 |
|
|
// ScriptSlots window |
67 |
|
|
std::vector<Gtk::TargetEntry> drag_target_gig_script; |
68 |
|
|
drag_target_gig_script.push_back(Gtk::TargetEntry("gig::Script")); |
69 |
|
|
drag_dest_set(drag_target_gig_script); |
70 |
|
|
signal_drag_data_received().connect( |
71 |
|
|
sigc::mem_fun(*this, &ScriptSlots::onScriptDragNDropDataReceived) |
72 |
|
|
); |
73 |
|
|
|
74 |
schoenebeck |
3364 |
#if HAS_GTKMM_SHOW_ALL_CHILDREN |
75 |
schoenebeck |
2610 |
show_all_children(); |
76 |
schoenebeck |
3364 |
#endif |
77 |
schoenebeck |
2610 |
} |
78 |
|
|
|
79 |
|
|
ScriptSlots::~ScriptSlots() { |
80 |
|
|
//printf("ScriptSlots destruct\n"); |
81 |
|
|
clearSlots(); |
82 |
|
|
} |
83 |
|
|
|
84 |
|
|
void ScriptSlots::clearSlots() { |
85 |
|
|
for (int i = 0; i < m_slots.size(); ++i) { |
86 |
|
|
delete m_slots[i].deleteButton; |
87 |
|
|
delete m_slots[i].downButton; |
88 |
|
|
delete m_slots[i].upButton; |
89 |
|
|
delete m_slots[i].label; |
90 |
|
|
delete m_slots[i].hbox; |
91 |
|
|
} |
92 |
|
|
m_slots.clear(); |
93 |
|
|
} |
94 |
|
|
|
95 |
|
|
void ScriptSlots::setInstrument(gig::Instrument* instrument) { |
96 |
|
|
m_instrument = instrument; |
97 |
|
|
if (!m_instrument) { |
98 |
|
|
set_title(_("No Instrument")); |
99 |
|
|
return; |
100 |
|
|
} |
101 |
|
|
|
102 |
|
|
set_title(std::string(_("Script Slots of Instrument")) + " - \"" + instrument->pInfo->Name + "\""); |
103 |
|
|
clearSlots(); |
104 |
|
|
for (int i = 0; i < instrument->ScriptSlotCount(); ++i) { |
105 |
|
|
gig::Script* script = instrument->GetScriptOfSlot(i); |
106 |
|
|
if (!script) continue; |
107 |
|
|
//printf("script '%s'\n", script->Name.c_str()); |
108 |
|
|
appendNewSlot(script); |
109 |
|
|
} |
110 |
|
|
} |
111 |
|
|
|
112 |
|
|
void ScriptSlots::refreshSlots() { |
113 |
|
|
clearSlots(); |
114 |
|
|
setInstrument(m_instrument); |
115 |
|
|
} |
116 |
|
|
|
117 |
|
|
void ScriptSlots::onScriptDragNDropDataReceived( |
118 |
|
|
const Glib::RefPtr<Gdk::DragContext>& context, int, int, |
119 |
|
|
const Gtk::SelectionData& selection_data, guint, guint time) |
120 |
|
|
{ |
121 |
|
|
gig::Script* script = *((gig::Script**) selection_data.get_data()); |
122 |
|
|
if (script && selection_data.get_length() == sizeof(gig::Script*)) { |
123 |
|
|
std::cout << "Drop received script \"" << script->Name << "\"" << std::endl; |
124 |
|
|
m_instrument->AddScriptSlot(script); |
125 |
|
|
appendNewSlot(script); |
126 |
|
|
// drop success |
127 |
|
|
context->drop_reply(true, time); |
128 |
schoenebeck |
3197 |
// inform i.e. main window |
129 |
|
|
script_slots_changed_signal.emit(m_instrument); |
130 |
schoenebeck |
2610 |
} else { |
131 |
|
|
// drop failed |
132 |
|
|
context->drop_reply(false, time); |
133 |
|
|
} |
134 |
|
|
} |
135 |
|
|
|
136 |
|
|
void ScriptSlots::appendNewSlot(gig::Script* script) { |
137 |
|
|
static int slotID = 0; |
138 |
|
|
|
139 |
|
|
Row row; |
140 |
|
|
row.id = slotID++; |
141 |
schoenebeck |
3364 |
row.hbox = new HBox; |
142 |
schoenebeck |
2610 |
row.label = new Gtk::Label; |
143 |
schoenebeck |
3364 |
#if HAS_GTKMM_STOCK |
144 |
schoenebeck |
3158 |
row.downButton = new Gtk::Button(Gtk::Stock::GO_DOWN); |
145 |
|
|
row.upButton = new Gtk::Button(Gtk::Stock::GO_UP); |
146 |
|
|
row.deleteButton = new Gtk::Button(Gtk::Stock::DELETE); |
147 |
schoenebeck |
3364 |
#else |
148 |
|
|
row.downButton = new Gtk::Button(_("_Down"), true); |
149 |
|
|
row.upButton = new Gtk::Button(_("_Up"), true); |
150 |
|
|
row.deleteButton = new Gtk::Button(_("_Delete"), true); |
151 |
|
|
|
152 |
|
|
row.downButton->set_icon_name("go-down"); |
153 |
|
|
row.upButton->set_icon_name("go-up"); |
154 |
|
|
row.deleteButton->set_icon_name("edit-delete"); |
155 |
|
|
#endif |
156 |
schoenebeck |
2610 |
row.script = script; |
157 |
|
|
|
158 |
|
|
row.hbox->pack_start(*row.label); |
159 |
|
|
row.hbox->pack_start(*row.downButton, Gtk::PACK_SHRINK); |
160 |
|
|
row.hbox->pack_start(*row.upButton, Gtk::PACK_SHRINK); |
161 |
|
|
row.hbox->pack_start(*row.deleteButton, Gtk::PACK_SHRINK); |
162 |
|
|
|
163 |
|
|
row.label->set_text(ToString(m_slots.size()+1) + ". \"" + script->Name + "\""); |
164 |
|
|
//row.label->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
165 |
|
|
|
166 |
|
|
row.upButton->signal_clicked().connect( |
167 |
|
|
sigc::bind( |
168 |
|
|
sigc::mem_fun(*this, &ScriptSlots::moveSlotUp), row.id |
169 |
|
|
) |
170 |
|
|
); |
171 |
|
|
row.downButton->signal_clicked().connect( |
172 |
|
|
sigc::bind( |
173 |
|
|
sigc::mem_fun(*this, &ScriptSlots::moveSlotDown), row.id |
174 |
|
|
) |
175 |
|
|
); |
176 |
|
|
row.deleteButton->signal_clicked().connect( |
177 |
|
|
sigc::bind( |
178 |
|
|
sigc::mem_fun(*this, &ScriptSlots::deleteSlot), row.id |
179 |
|
|
) |
180 |
|
|
); |
181 |
|
|
|
182 |
|
|
m_vboxSlots.add(*row.hbox); |
183 |
schoenebeck |
3364 |
#if HAS_GTKMM_SHOW_ALL_CHILDREN |
184 |
schoenebeck |
2610 |
m_scrolledWindow.show_all_children(); |
185 |
schoenebeck |
3364 |
#endif |
186 |
schoenebeck |
2610 |
|
187 |
|
|
m_slots.push_back(row); |
188 |
|
|
} |
189 |
|
|
|
190 |
|
|
void ScriptSlots::moveSlotUp(int slotID) { |
191 |
|
|
for (int i = 0; i < m_instrument->ScriptSlotCount(); ++i) { |
192 |
|
|
if (m_slots[i].id == slotID) { |
193 |
|
|
if (i != 0) { |
194 |
|
|
m_instrument->SwapScriptSlots(i, i-1); |
195 |
|
|
refreshSlots(); |
196 |
schoenebeck |
3197 |
script_slots_changed_signal.emit(m_instrument); |
197 |
schoenebeck |
2610 |
} |
198 |
|
|
break; |
199 |
|
|
} |
200 |
|
|
} |
201 |
|
|
} |
202 |
|
|
|
203 |
|
|
void ScriptSlots::moveSlotDown(int slotID) { |
204 |
|
|
for (int i = 0; i < m_instrument->ScriptSlotCount(); ++i) { |
205 |
|
|
if (m_slots[i].id == slotID) { |
206 |
|
|
if (i < m_instrument->ScriptSlotCount() - 1) { |
207 |
|
|
m_instrument->SwapScriptSlots(i, i+1); |
208 |
|
|
refreshSlots(); |
209 |
schoenebeck |
3197 |
script_slots_changed_signal.emit(m_instrument); |
210 |
schoenebeck |
2610 |
} |
211 |
|
|
break; |
212 |
|
|
} |
213 |
|
|
} |
214 |
|
|
} |
215 |
|
|
|
216 |
|
|
void ScriptSlots::deleteSlot(int slotID) { |
217 |
|
|
for (int i = 0; i < m_instrument->ScriptSlotCount(); ++i) { |
218 |
|
|
if (m_slots[i].id == slotID) { |
219 |
|
|
m_instrument->RemoveScriptSlot(i); |
220 |
|
|
refreshSlots(); |
221 |
schoenebeck |
3197 |
script_slots_changed_signal.emit(m_instrument); |
222 |
schoenebeck |
2610 |
break; |
223 |
|
|
} |
224 |
|
|
} |
225 |
|
|
} |
226 |
|
|
|
227 |
schoenebeck |
3197 |
sigc::signal<void, gig::Instrument*>& ScriptSlots::signal_script_slots_changed() { |
228 |
|
|
return script_slots_changed_signal; |
229 |
|
|
} |
230 |
|
|
|
231 |
schoenebeck |
2610 |
void ScriptSlots::onButtonClose() { |
232 |
|
|
hide(); |
233 |
|
|
} |
234 |
|
|
|
235 |
|
|
void ScriptSlots::onWindowHide() { |
236 |
|
|
delete this; // this is the end, my friend |
237 |
|
|
} |
238 |
|
|
|