/[svn]/gigedit/trunk/src/dimregionchooser.cpp
ViewVC logotype

Contents of /gigedit/trunk/src/dimregionchooser.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1052 - (show annotations) (download)
Sat Mar 3 12:20:01 2007 UTC (13 years, 4 months ago) by persson
Original Path: gigedit/branches/linuxsampler_org/src/dimregionchooser.cpp
File size: 14398 byte(s)
Initial revision

1 /*
2 * Copyright (C) 2006, 2007 Andreas Persson
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with program; see the file COPYING. If not, write to the Free
16 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17 * 02110-1301 USA.
18 */
19
20 #include "dimregionchooser.h"
21
22 DimRegionChooser::DimRegionChooser()
23 {
24 // get_window() would return 0 because the Gdk::Window has not yet been realized
25 // So we can only allocate the colors here - the rest will happen in on_realize().
26 Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
27
28 black = Gdk::Color("black");
29 white = Gdk::Color("white");
30 red = Gdk::Color("#8070ff");
31 blue = Gdk::Color("blue");
32 green = Gdk::Color("green");
33
34 colormap->alloc_color(black);
35 colormap->alloc_color(white);
36 colormap->alloc_color(red);
37 colormap->alloc_color(blue);
38 colormap->alloc_color(green);
39 instrument = 0;
40 region = 0;
41 dimregno = -1;
42 focus_line = 0;
43 set_flags(Gtk::CAN_FOCUS);
44 add_events(Gdk::BUTTON_PRESS_MASK);
45
46 for (int i = 0 ; i < 256 ; i++) {
47 dimvalue_from[i] = 0;
48 dimvalue_to[i] = 1;
49 }
50 }
51
52 DimRegionChooser::~DimRegionChooser()
53 {
54 }
55
56 void DimRegionChooser::on_realize()
57 {
58 // We need to call the base on_realize()
59 Gtk::DrawingArea::on_realize();
60
61 // Now we can allocate any additional resources we need
62 Glib::RefPtr<Gdk::Window> window = get_window();
63 gc = Gdk::GC::create(window);
64 }
65
66 bool DimRegionChooser::on_expose_event(GdkEventExpose* event)
67 {
68 if (!region) return true;
69
70 int a = 1, b, c;
71 for (int i = 0 ; i < region->Dimensions ; i++) {
72 b = a * region->pDimensionDefinitions[i].zones;
73 if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
74 c = dimregno >= 0 ? (dimregno & ((a - 1) | ~(b - 1))) : 0;
75 break;
76 }
77 a = b;
78 }
79
80 // This is where we draw on the window
81 Glib::RefPtr<Gdk::Window> window = get_window();
82 Glib::RefPtr<Pango::Context> context = get_pango_context();
83
84 Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
85
86 window->clear();
87 const int h = 20;
88 const int w = 800;
89 const int w1 = 100;
90 int y = 0;
91 int bitcount = 0;
92 for (int i = 0 ; i < region->Dimensions ; i++) {
93 const int nb = region->pDimensionDefinitions[i].zones;
94 if (nb) {
95 char* dstr;
96 switch (region->pDimensionDefinitions[i].dimension) {
97 case gig::dimension_none: dstr="none"; break;
98 case gig::dimension_samplechannel: dstr="samplechannel"; break;
99 case gig::dimension_layer: dstr="layer"; break;
100 case gig::dimension_velocity: dstr="velocity"; break;
101 case gig::dimension_channelaftertouch: dstr="channelaftertouch"; break;
102 case gig::dimension_releasetrigger: dstr="releasetrigger"; break;
103 case gig::dimension_keyboard: dstr="keyboard"; break;
104 case gig::dimension_roundrobin: dstr="roundrobin"; break;
105 case gig::dimension_random: dstr="random"; break;
106 case gig::dimension_modwheel: dstr="modwheel"; break;
107 case gig::dimension_breath: dstr="breath"; break;
108 case gig::dimension_foot: dstr="foot"; break;
109 case gig::dimension_portamentotime: dstr="portamentotime"; break;
110 case gig::dimension_effect1: dstr="effect1"; break;
111 case gig::dimension_effect2: dstr="effect2"; break;
112 case gig::dimension_genpurpose1: dstr="genpurpose1"; break;
113 case gig::dimension_genpurpose2: dstr="genpurpose2"; break;
114 case gig::dimension_genpurpose3: dstr="genpurpose3"; break;
115 case gig::dimension_genpurpose4: dstr="genpurpose4"; break;
116 case gig::dimension_sustainpedal: dstr="sustainpedal"; break;
117 case gig::dimension_portamento: dstr="portamento"; break;
118 case gig::dimension_sostenutopedal: dstr="sostenutopedal"; break;
119 case gig::dimension_softpedal: dstr="softpedal"; break;
120 case gig::dimension_genpurpose5: dstr="genpurpose5"; break;
121 case gig::dimension_genpurpose6: dstr="genpurpose6"; break;
122 case gig::dimension_genpurpose7: dstr="genpurpose7"; break;
123 case gig::dimension_genpurpose8: dstr="genpurpose8"; break;
124 case gig::dimension_effect1depth: dstr="effect1depth"; break;
125 case gig::dimension_effect2depth: dstr="effect2depth"; break;
126 case gig::dimension_effect3depth: dstr="effect3depth"; break;
127 case gig::dimension_effect4depth: dstr="effect4depth"; break;
128 case gig::dimension_effect5depth: dstr="effect5depth"; break;
129 }
130 layout->set_text(dstr);
131
132 Pango::Rectangle rectangle = layout->get_logical_extents();
133 double text_h = double(rectangle.get_height()) / Pango::SCALE;
134 Glib::RefPtr<const Gdk::GC> fg = get_style()->get_fg_gc(get_state());
135 window->draw_layout(fg, 4, int(y + (h - text_h) / 2 + 0.5), layout);
136
137 if (has_focus() && focus_line == i) {
138 Gdk::Rectangle farea(0, y, 50, 20);
139 get_style()->paint_focus(window, get_state(), farea, *this, "hejsan", 0, y, 50, 20);
140 }
141
142 Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
143 window->draw_line(black, w1, y, w - 1, y);
144 window->draw_line(black, w - 1, y + h - 1, w1, y + h - 1);
145 window->draw_rectangle(get_style()->get_white_gc(), true, w1 + 1, y + 1, (w - w1 - 2), h - 2);
146
147 if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
148 region->pDimensionRegions[c]->VelocityUpperLimit) {
149 window->draw_line(black, w1, y + 1, w1, y + h - 2);
150 for (int k = c ; k < b ; k += a) {
151 gig::DimensionRegion *d = region->pDimensionRegions[k];
152 int v = d->VelocityUpperLimit + 1;
153 int x = int((w - w1 - 1) * v / 128.0 + 0.5);
154 window->draw_line(black, w1 + x, y + 1, w1 + x, y + h - 2);
155 }
156 } else {
157 for (int j = 0 ; j <= nb ; j++) {
158 int x = int((w - w1 - 1) * j / double(nb) + 0.5);
159 window->draw_line(black, w1 + x, y + 1, w1 + x, y + h - 2);
160 }
161 }
162
163 if (dimregno >= 0) {
164 gc->set_foreground(red);
165 int dr = (dimregno >> bitcount) & ((1 << region->pDimensionDefinitions[i].bits) - 1);
166 if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
167 region->pDimensionRegions[c]->VelocityUpperLimit) {
168 int x1 = 0, dr2 = 0;
169 for (int k = c ; k < b ; k += a) {
170 gig::DimensionRegion *d = region->pDimensionRegions[k];
171 int v = d->VelocityUpperLimit + 1;
172 int x2 = int((w - w1 - 1) * v / 128.0 + 0.5);
173 if (dr2 == dr) {
174 window->draw_rectangle(gc, true, w1 + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);
175 break;
176 }
177 dr2++;
178 x1 = x2;
179 }
180 } else {
181 if (dr < nb) {
182 int x1 = int((w - w1 - 1) * dr / double(nb) + 0.5);
183 int x2 = int((w - w1 - 1) * (dr + 1) / double(nb) + 0.5);
184 window->draw_rectangle(gc, true, w1 + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);
185 }
186 }
187 }
188
189 y += h;
190 }
191 bitcount += region->pDimensionDefinitions[i].bits;
192 }
193
194 return true;
195 }
196
197
198 void DimRegionChooser::on_size_request(GtkRequisition* requisition)
199 {
200 printf("DimRegionChooser::on_size_request\n");
201 *requisition = GtkRequisition();
202 requisition->height = region ? region->Dimensions * 20 : 0;
203 requisition->width = 800;
204 }
205
206 void DimRegionChooser::set_instrument(gig::Instrument* instrument)
207 {
208 this->instrument = instrument;
209 this->region = 0;
210 this->dimregno = -1;
211 queue_draw();
212 }
213
214 void DimRegionChooser::set_region(gig::Region* region)
215 {
216 this->region = region;
217 dimregno = 0;
218 int bitcount = 0;
219 for (int dim = 0 ; dim < region->Dimensions ; dim++) {
220 int from = dimvalue_from[region->pDimensionDefinitions[dim].dimension];
221 int to = dimvalue_to[region->pDimensionDefinitions[dim].dimension];
222 int z;
223 switch (region->pDimensionDefinitions[dim].split_type) {
224 case gig::split_type_normal:
225 z = int((to + from) / 2.0 / region->pDimensionDefinitions[dim].zone_size);
226 break;
227 case gig::split_type_bit:
228 z = std::min(from, region->pDimensionDefinitions[dim].zones - 1);
229 break;
230 }
231 int mask =
232 ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<
233 bitcount);
234 dimregno &= mask;
235 dimregno |= (z << bitcount);
236 bitcount += region->pDimensionDefinitions[dim].bits;
237 }
238 dimreg = region->pDimensionRegions[dimregno];
239 sel_changed_signal.emit();
240 queue_resize();
241 }
242
243 /*
244 void DimRegionChooser::set_dimregno(int x) {
245 this->dimregno = x;
246 queue_draw();
247 }
248 */
249
250 bool DimRegionChooser::on_button_press_event(GdkEventButton* event)
251 {
252 const int h = 20;
253 const int w = 800;
254 const int w1 = 100;
255
256 if (region) {
257 if (event->y < region->Dimensions * h &&
258 event->x >= w1 && event->x < w) {
259
260 int dim = int(event->y / h);
261 const int nb = region->pDimensionDefinitions[dim].zones;
262
263 int z = -1;
264 if (region->pDimensionDefinitions[dim].dimension == gig::dimension_velocity) {
265 int a = 1, b, c;
266 for (int i = 0 ; i < region->Dimensions ; i++) {
267 b = a * region->pDimensionDefinitions[i].zones;
268 if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
269 c = dimregno >= 0 ? (dimregno & ((a - 1) | ~(b - 1))) : 0;
270 break;
271 }
272 a = b;
273 }
274
275 if (region->pDimensionRegions[c]->VelocityUpperLimit) {
276 int vel = int((event->x - w1) * 128 / (w - w1 - 1));
277
278 z = 0;
279 for (int k = c ; k < b ; k += a) {
280 gig::DimensionRegion *d = region->pDimensionRegions[k];
281 if (vel <= d->VelocityUpperLimit) break;
282 z++;
283 }
284 }
285 }
286
287 if (z == -1) {
288 z = int((event->x - w1) * nb / (w - w1 - 1));
289 }
290
291 printf("dim=%d z=%d dimensionsource=%d split_type=%d zones=%d zone_size=%f\n", dim, z,
292 region->pDimensionDefinitions[dim].dimension,
293 region->pDimensionDefinitions[dim].split_type,
294 region->pDimensionDefinitions[dim].zones,
295 region->pDimensionDefinitions[dim].zone_size);
296 switch (region->pDimensionDefinitions[dim].split_type) {
297 case gig::split_type_normal:
298 dimvalue_from[region->pDimensionDefinitions[dim].dimension] =
299 int(z * region->pDimensionDefinitions[dim].zone_size);
300 dimvalue_to[region->pDimensionDefinitions[dim].dimension] =
301 int((z + 1) * region->pDimensionDefinitions[dim].zone_size) - 1;
302 break;
303 case gig::split_type_bit:
304 dimvalue_from[region->pDimensionDefinitions[dim].dimension] = z;
305 dimvalue_to[region->pDimensionDefinitions[dim].dimension] = z + 1;
306 break;
307 }
308 if (dimregno < 0) dimregno = 0;
309 int bitcount = 0;
310 for (int i = 0 ; i < dim ; i++) {
311 bitcount += region->pDimensionDefinitions[i].bits;
312 }
313
314 int mask =
315 ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<
316 bitcount);
317 dimregno &= mask;
318 dimregno |= (z << bitcount);
319
320 focus_line = dim;
321 if (has_focus()) queue_draw();
322 else grab_focus();
323 dimreg = region->pDimensionRegions[dimregno];
324 sel_changed_signal.emit();
325 }
326 }
327 return true;
328 }
329
330 sigc::signal<void> DimRegionChooser::signal_sel_changed()
331 {
332 return sel_changed_signal;
333 }
334
335 bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
336 {
337 // TODO: kolla att region finns osv, dvs att det g�r att s�tta
338 // fokus.
339 if (direction == Gtk::DIR_TAB_FORWARD ||
340 direction == Gtk::DIR_DOWN) {
341 if (!has_focus()) {
342 focus_line = 0;
343 grab_focus();
344 return true;
345 } else {
346 if (focus_line + 1 < region->Dimensions) {
347 focus_line++;
348 queue_draw();
349 return true;
350 } else {
351 return false;
352 }
353 }
354 } else if (direction == Gtk::DIR_TAB_BACKWARD ||
355 direction == Gtk::DIR_UP) {
356 if (!has_focus()) {
357 focus_line = region->Dimensions - 1;
358 grab_focus();
359 return true;
360 } else {
361 if (focus_line > 0) {
362 focus_line--;
363 queue_draw();
364 return true;
365 } else {
366 return false;
367 }
368 }
369 } else if (!has_focus()) {
370 // TODO: kolla att focus_line finns!
371 grab_focus();
372 return true;
373 } else {
374 // TODO: �ka eller minska v�rde!
375 }
376 }

  ViewVC Help
Powered by ViewVC