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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1656 - (show annotations) (download)
Sat Feb 2 08:18:19 2008 UTC (16 years, 2 months ago) by schoenebeck
File size: 26572 byte(s)
* bugfix: key highlighting of active keys on the virtual keyboard is now
  working on multiple invocations from the sampler as well
* renamed misleading names regarding the gig format's "keyswitching"
  feature (the dimension is now displayed as "keyswitching" instead of
  "keyboard" in the dimregchooser widget and the two parameters for
  defining the actual keyswitching area on the keyboard in the instruments
  properties dialog are now called "Keyswitching range low/high" instead of
  "Dimension key range low/high")

1 /*
2 * Copyright (C) 2006-2008 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 #include <gdkmm/cursor.h>
22
23 DimRegionChooser::DimRegionChooser()
24 {
25 // get_window() would return 0 because the Gdk::Window has not yet been realized
26 // So we can only allocate the colors here - the rest will happen in on_realize().
27 Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
28
29 black = Gdk::Color("black");
30 white = Gdk::Color("white");
31 red = Gdk::Color("#8070ff");
32 blue = Gdk::Color("blue");
33 green = Gdk::Color("green");
34
35 colormap->alloc_color(black);
36 colormap->alloc_color(white);
37 colormap->alloc_color(red);
38 colormap->alloc_color(blue);
39 colormap->alloc_color(green);
40 instrument = 0;
41 region = 0;
42 dimregno = -1;
43 focus_line = 0;
44 resize.active = false;
45 cursor_is_resize = false;
46 h = 20;
47 set_flags(Gtk::CAN_FOCUS);
48 add_events(Gdk::BUTTON_PRESS_MASK | Gdk::POINTER_MOTION_MASK |
49 Gdk::POINTER_MOTION_HINT_MASK);
50
51 for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;
52 }
53
54 DimRegionChooser::~DimRegionChooser()
55 {
56 }
57
58 void DimRegionChooser::on_realize()
59 {
60 // We need to call the base on_realize()
61 Gtk::DrawingArea::on_realize();
62
63 // Now we can allocate any additional resources we need
64 Glib::RefPtr<Gdk::Window> window = get_window();
65 gc = Gdk::GC::create(window);
66 }
67
68 bool DimRegionChooser::on_expose_event(GdkEventExpose* event)
69 {
70 if (!region) return true;
71
72 // This is where we draw on the window
73 int w = get_width();
74 Glib::RefPtr<Gdk::Window> window = get_window();
75 Glib::RefPtr<Pango::Context> context = get_pango_context();
76
77 Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
78
79 window->clear();
80
81 // draw labels on the left (reflecting the dimension type)
82 int y = 0;
83 double maxwidth = 0;
84 for (int i = 0 ; i < region->Dimensions ; i++) {
85 int nbZones = region->pDimensionDefinitions[i].zones;
86 if (nbZones) {
87 const char* dstr;
88 char dstrbuf[10];
89 switch (region->pDimensionDefinitions[i].dimension) {
90 case gig::dimension_none: dstr="none"; break;
91 case gig::dimension_samplechannel: dstr="samplechannel"; break;
92 case gig::dimension_layer: dstr="layer"; break;
93 case gig::dimension_velocity: dstr="velocity"; break;
94 case gig::dimension_channelaftertouch: dstr="channelaftertouch"; break;
95 case gig::dimension_releasetrigger: dstr="releasetrigger"; break;
96 case gig::dimension_keyboard: dstr="keyswitching"; break;
97 case gig::dimension_roundrobin: dstr="roundrobin"; break;
98 case gig::dimension_random: dstr="random"; break;
99 case gig::dimension_smartmidi: dstr="smartmidi"; break;
100 case gig::dimension_roundrobinkeyboard: dstr="roundrobinkeyboard"; break;
101 case gig::dimension_modwheel: dstr="modwheel"; break;
102 case gig::dimension_breath: dstr="breath"; break;
103 case gig::dimension_foot: dstr="foot"; break;
104 case gig::dimension_portamentotime: dstr="portamentotime"; break;
105 case gig::dimension_effect1: dstr="effect1"; break;
106 case gig::dimension_effect2: dstr="effect2"; break;
107 case gig::dimension_genpurpose1: dstr="genpurpose1"; break;
108 case gig::dimension_genpurpose2: dstr="genpurpose2"; break;
109 case gig::dimension_genpurpose3: dstr="genpurpose3"; break;
110 case gig::dimension_genpurpose4: dstr="genpurpose4"; break;
111 case gig::dimension_sustainpedal: dstr="sustainpedal"; break;
112 case gig::dimension_portamento: dstr="portamento"; break;
113 case gig::dimension_sostenutopedal: dstr="sostenutopedal"; break;
114 case gig::dimension_softpedal: dstr="softpedal"; break;
115 case gig::dimension_genpurpose5: dstr="genpurpose5"; break;
116 case gig::dimension_genpurpose6: dstr="genpurpose6"; break;
117 case gig::dimension_genpurpose7: dstr="genpurpose7"; break;
118 case gig::dimension_genpurpose8: dstr="genpurpose8"; break;
119 case gig::dimension_effect1depth: dstr="effect1depth"; break;
120 case gig::dimension_effect2depth: dstr="effect2depth"; break;
121 case gig::dimension_effect3depth: dstr="effect3depth"; break;
122 case gig::dimension_effect4depth: dstr="effect4depth"; break;
123 case gig::dimension_effect5depth: dstr="effect5depth"; break;
124 default:
125 sprintf(dstrbuf, "%d",
126 region->pDimensionDefinitions[i].dimension);
127 dstr = dstrbuf;
128 break;
129 }
130 layout->set_text(dstr);
131
132 Pango::Rectangle rectangle = layout->get_logical_extents();
133 double text_w = double(rectangle.get_width()) / Pango::SCALE;
134 if (text_w > maxwidth) maxwidth = text_w;
135 double text_h = double(rectangle.get_height()) / Pango::SCALE;
136 Glib::RefPtr<const Gdk::GC> fg = get_style()->get_fg_gc(get_state());
137 window->draw_layout(fg, 4, int(y + (h - text_h) / 2 + 0.5), layout);
138
139 }
140 y += h;
141 }
142
143 // draw dimensions' zones areas
144 y = 0;
145 int bitpos = 0;
146 label_width = int(maxwidth + 10);
147 for (int i = 0 ; i < region->Dimensions ; i++) {
148 int nbZones = region->pDimensionDefinitions[i].zones;
149 if (nbZones) {
150 // draw focus rectangle around dimension's label and zones
151 if (has_focus() && focus_line == i) {
152 Gdk::Rectangle farea(0, y, 150, 20);
153 get_style()->paint_focus(window, get_state(), farea, *this, "",
154 0, y, label_width, 20);
155 }
156
157 Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
158 // draw top and bottom lines of dimension's zones
159 window->draw_line(black, label_width, y, w - 1, y);
160 window->draw_line(black, w - 1, y + h - 1, label_width, y + h - 1);
161 // erase whole dimension's zones area
162 window->draw_rectangle(get_style()->get_white_gc(), true,
163 label_width + 1, y + 1, (w - label_width - 2), h - 2);
164
165 int c = 0;
166 if (dimregno >= 0) {
167 int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
168 c = dimregno & mask; // mask away this dimension
169 }
170 bool customsplits =
171 ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
172 region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
173 (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
174 region->pDimensionRegions[c]->VelocityUpperLimit));
175
176 // draw dimension's zone borders
177 if (customsplits) {
178 window->draw_line(black, label_width, y + 1, label_width, y + h - 2);
179 for (int j = 0 ; j < nbZones ; j++) {
180 gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
181 int upperLimit = d->DimensionUpperLimits[i];
182 if (!upperLimit) upperLimit = d->VelocityUpperLimit;
183 int v = upperLimit + 1;
184 int x = int((w - label_width - 1) * v / 128.0 + 0.5);
185 window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);
186 }
187 } else {
188 for (int j = 0 ; j <= nbZones ; j++) {
189 int x = int((w - label_width - 1) * j / double(nbZones) + 0.5);
190 window->draw_line(black, label_width + x, y + 1, label_width + x, y + h - 2);
191 }
192 }
193
194 // draw fill for currently selected zone
195 if (dimregno >= 0) {
196 gc->set_foreground(red);
197 int dr = (dimregno >> bitpos) & ((1 << region->pDimensionDefinitions[i].bits) - 1);
198 if (customsplits) {
199 int x1 = 0;
200 for (int j = 0 ; j < nbZones ; j++) {
201 gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
202 int upperLimit = d->DimensionUpperLimits[i];
203 if (!upperLimit) upperLimit = d->VelocityUpperLimit;
204 int v = upperLimit + 1;
205 int x2 = int((w - label_width - 1) * v / 128.0 + 0.5);
206 if (j == dr && x1 < x2) {
207 window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,
208 (x2 - x1) - 1, h - 2);
209 break;
210 }
211 x1 = x2;
212 }
213 } else {
214 if (dr < nbZones) {
215 int x1 = int((w - label_width - 1) * dr / double(nbZones) + 0.5);
216 int x2 = int((w - label_width - 1) * (dr + 1) / double(nbZones) + 0.5);
217 window->draw_rectangle(gc, true, label_width + x1 + 1, y + 1,
218 (x2 - x1) - 1, h - 2);
219 }
220 }
221 }
222
223 y += h;
224 }
225 bitpos += region->pDimensionDefinitions[i].bits;
226 }
227
228 return true;
229 }
230
231 void DimRegionChooser::on_size_request(GtkRequisition* requisition)
232 {
233 *requisition = GtkRequisition();
234 requisition->height = region ? nbDimensions * 20 : 0;
235 requisition->width = 800;
236 }
237
238 void DimRegionChooser::set_region(gig::Region* region)
239 {
240 this->region = region;
241 dimregno = 0;
242 nbDimensions = 0;
243 if (region) {
244 int bitcount = 0;
245 for (int dim = 0 ; dim < region->Dimensions ; dim++) {
246 if (region->pDimensionDefinitions[dim].bits == 0) continue;
247 nbDimensions++;
248
249 int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],
250 region->pDimensionDefinitions[dim].zones - 1);
251 dimregno |= (z << bitcount);
252 bitcount += region->pDimensionDefinitions[dim].bits;
253 }
254 dimreg = region->pDimensionRegions[dimregno];
255 } else {
256 dimreg = 0;
257 }
258 dimregion_selected();
259 queue_resize();
260 }
261
262
263 void DimRegionChooser::get_dimregions(const gig::Region* region, bool stereo,
264 std::set<gig::DimensionRegion*>& dimregs) const
265 {
266 int dimregno = 0;
267 int bitcount = 0;
268 int stereo_bit = 0;
269 for (int dim = 0 ; dim < region->Dimensions ; dim++) {
270 if (region->pDimensionDefinitions[dim].bits == 0) continue;
271 if (stereo &&
272 region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) {
273 stereo_bit = (1 << bitcount);
274 } else {
275 int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],
276 region->pDimensionDefinitions[dim].zones - 1);
277 dimregno |= (z << bitcount);
278 }
279 bitcount += region->pDimensionDefinitions[dim].bits;
280 }
281 dimregs.insert(region->pDimensionRegions[dimregno]);
282 if (stereo_bit) dimregs.insert(region->pDimensionRegions[dimregno | stereo_bit]);
283 }
284
285
286 bool DimRegionChooser::on_button_release_event(GdkEventButton* event)
287 {
288 if (resize.active) {
289 get_window()->pointer_ungrab(event->time);
290 resize.active = false;
291
292 if (region->pDimensionDefinitions[resize.dimension].dimension == gig::dimension_velocity) {
293
294 int bitpos = 0;
295 for (int j = 0 ; j < resize.dimension ; j++) {
296 bitpos += region->pDimensionDefinitions[j].bits;
297 }
298 int mask =
299 ~(((1 << region->pDimensionDefinitions[resize.dimension].bits) - 1) << bitpos);
300 int c = dimregno & mask; // mask away this dimension
301
302 if (region->pDimensionRegions[c]->DimensionUpperLimits[resize.dimension] == 0) {
303 // the velocity dimension didn't previously have
304 // custom v3 splits, so we initialize all splits with
305 // default values
306 int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
307 for (int j = 0 ; j < nbZones ; j++) {
308 gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
309 d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
310 }
311 }
312 if (region->pDimensionRegions[c]->VelocityUpperLimit == 0) {
313 // the velocity dimension didn't previously have
314 // custom v2 splits, so we initialize all splits with
315 // default values
316 int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
317 for (int j = 0 ; j < nbZones ; j++) {
318 gig::DimensionRegion *d = region->pDimensionRegions[c + (j << bitpos)];
319 d->VelocityUpperLimit = int(128.0 * (j + 1) / nbZones - 1);
320 }
321 }
322
323 gig::DimensionRegion *d = region->pDimensionRegions[c + resize.offset];
324 // update both v2 and v3 values
325 d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
326 d->VelocityUpperLimit = resize.pos - 1;
327
328 } else {
329 for (int i = 0 ; i < region->DimensionRegions ; ) {
330
331 if (region->pDimensionRegions[i]->DimensionUpperLimits[resize.dimension] == 0) {
332 // the dimension didn't previously have custom
333 // limits, so we have to set default limits for
334 // all the dimension regions
335 int bitpos = 0;
336 for (int j = 0 ; j < resize.dimension ; j++) {
337 bitpos += region->pDimensionDefinitions[j].bits;
338 }
339 int nbZones = region->pDimensionDefinitions[resize.dimension].zones;
340
341 for (int j = 0 ; j < nbZones ; j++) {
342 gig::DimensionRegion *d = region->pDimensionRegions[i + (j << bitpos)];
343 d->DimensionUpperLimits[resize.dimension] = int(128.0 * (j + 1) / nbZones - 1);
344 }
345 }
346 gig::DimensionRegion *d = region->pDimensionRegions[i + resize.offset];
347 d->DimensionUpperLimits[resize.dimension] = resize.pos - 1;
348
349 int bitpos = 0;
350 int j;
351 for (j = 0 ; j < region->Dimensions ; j++) {
352 if (j != resize.dimension) {
353 int maxzones = 1 << region->pDimensionDefinitions[j].bits;
354 int dimj = (i >> bitpos) & (maxzones - 1);
355 if (dimj + 1 < region->pDimensionDefinitions[j].zones) break;
356 }
357 bitpos += region->pDimensionDefinitions[j].bits;
358 }
359 if (j == region->Dimensions) break;
360 i = (i & ~((1 << bitpos) - 1)) + (1 << bitpos);
361 }
362 }
363 region_changed();
364
365 if (!is_in_resize_zone(event->x, event->y) && cursor_is_resize) {
366 get_window()->set_cursor();
367 cursor_is_resize = false;
368 }
369 }
370 return true;
371 }
372
373 bool DimRegionChooser::on_button_press_event(GdkEventButton* event)
374 {
375 int w = get_width();
376 if (region && event->y < nbDimensions * h &&
377 event->x >= label_width && event->x < w) {
378
379 if (is_in_resize_zone(event->x, event->y)) {
380 Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
381 get_window()->pointer_grab(false,
382 Gdk::BUTTON_RELEASE_MASK |
383 Gdk::POINTER_MOTION_MASK |
384 Gdk::POINTER_MOTION_HINT_MASK,
385 double_arrow, event->time);
386 resize.active = true;
387 } else {
388 int ydim = int(event->y / h);
389 int dim;
390 for (dim = 0 ; dim < region->Dimensions ; dim++) {
391 if (region->pDimensionDefinitions[dim].bits == 0) continue;
392 if (ydim == 0) break;
393 ydim--;
394 }
395 int nbZones = region->pDimensionDefinitions[dim].zones;
396
397 int z = -1;
398 int bitpos = 0;
399 for (int i = 0 ; i < dim ; i++) {
400 bitpos += region->pDimensionDefinitions[i].bits;
401 }
402
403 int i = dim;
404 if (dimregno < 0) dimregno = 0;
405 int mask = ~(((1 << region->pDimensionDefinitions[i].bits) - 1) << bitpos);
406 int c = dimregno & mask; // mask away this dimension
407
408 bool customsplits =
409 ((region->pDimensionDefinitions[i].split_type == gig::split_type_normal &&
410 region->pDimensionRegions[c]->DimensionUpperLimits[i]) ||
411 (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
412 region->pDimensionRegions[c]->VelocityUpperLimit));
413 if (customsplits) {
414 int val = int((event->x - label_width) * 128 / (w - label_width - 1));
415
416 if (region->pDimensionRegions[c]->DimensionUpperLimits[i]) {
417 for (z = 0 ; z < nbZones ; z++) {
418 gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];
419 if (val <= d->DimensionUpperLimits[i]) break;
420 }
421 } else {
422 for (z = 0 ; z < nbZones ; z++) {
423 gig::DimensionRegion *d = region->pDimensionRegions[c + (z << bitpos)];
424 if (val <= d->VelocityUpperLimit) break;
425 }
426 }
427 } else {
428 z = int((event->x - label_width) * nbZones / (w - label_width - 1));
429 }
430
431 printf("dim=%d z=%d dimensionsource=%d split_type=%d zones=%d zone_size=%f\n", dim, z,
432 region->pDimensionDefinitions[dim].dimension,
433 region->pDimensionDefinitions[dim].split_type,
434 region->pDimensionDefinitions[dim].zones,
435 region->pDimensionDefinitions[dim].zone_size);
436 dimvalue[region->pDimensionDefinitions[dim].dimension] = z;
437
438 dimregno = c | (z << bitpos);
439
440 focus_line = dim;
441 if (has_focus()) queue_draw();
442 else grab_focus();
443 dimreg = region->pDimensionRegions[dimregno];
444 dimregion_selected();
445 }
446 }
447 return true;
448 }
449
450 bool DimRegionChooser::on_motion_notify_event(GdkEventMotion* event)
451 {
452 Glib::RefPtr<Gdk::Window> window = get_window();
453 int x, y;
454 Gdk::ModifierType state = Gdk::ModifierType(0);
455 window->get_pointer(x, y, state);
456
457 if (resize.active) {
458 int w = get_width();
459 int k = int((x - label_width) * 128.0 / (w - label_width - 1) + 0.5);
460
461 if (k < resize.min) k = resize.min;
462 else if (k > resize.max) k = resize.max;
463
464 if (k < 2) k = 2; // k is upper limit + 1, upper limit 0 is forbidden
465
466 if (k != resize.pos) {
467 Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
468 Glib::RefPtr<const Gdk::GC> white = get_style()->get_white_gc();
469
470 int prevx = int((w - label_width - 1) * resize.pos / 128.0 + 0.5) + label_width;
471 int x = int((w - label_width - 1) * k / 128.0 + 0.5) + label_width;
472 int y = resize.dimension * h;
473
474 if (resize.selected == resize.none) {
475 if (resize.pos != resize.min && resize.pos != resize.max) {
476 window->draw_line(white, prevx, y + 1, prevx, y + h - 2);
477 }
478 } else {
479 gc->set_foreground(red);
480
481 Glib::RefPtr<const Gdk::GC> left;
482 Glib::RefPtr<const Gdk::GC> right;
483 if (resize.selected == resize.left) {
484 left = gc;
485 right = white;
486 } else {
487 left = white;
488 right = gc;
489 }
490
491 if (k > resize.pos) {
492 int xx = resize.pos == resize.min ? 1 : 0;
493 window->draw_rectangle(left, true,
494 prevx + xx, y + 1, x - prevx - xx, h - 2);
495 } else {
496 int xx = resize.pos == resize.max ? 0 : 1;
497 window->draw_rectangle(right, true,
498 x, y + 1, prevx - x + xx, h - 2);
499 }
500 }
501 window->draw_line(black, x, y + 1, x, y + h - 2);
502 resize.pos = k;
503 }
504 } else {
505 if (is_in_resize_zone(x, y)) {
506 if (!cursor_is_resize) {
507 Gdk::Cursor double_arrow(Gdk::SB_H_DOUBLE_ARROW);
508 window->set_cursor(double_arrow);
509 cursor_is_resize = true;
510 }
511 } else if (cursor_is_resize) {
512 window->set_cursor();
513 cursor_is_resize = false;
514 }
515 }
516 return true;
517 }
518
519 bool DimRegionChooser::is_in_resize_zone(double x, double y)
520 {
521 int w = get_width();
522 if (region && y < nbDimensions * h && x >= label_width && x < w) {
523 int ydim = int(y / h);
524 int dim;
525 int bitpos = 0;
526 for (dim = 0 ; dim < region->Dimensions ; dim++) {
527 if (region->pDimensionDefinitions[dim].bits == 0) continue;
528 if (ydim == 0) break;
529 ydim--;
530 bitpos += region->pDimensionDefinitions[dim].bits;
531 }
532 int nbZones = region->pDimensionDefinitions[dim].zones;
533
534 int c = 0;
535 if (dimregno >= 0) {
536 int mask = ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << bitpos);
537 c = dimregno & mask; // mask away this dimension
538 }
539 const bool customsplits =
540 ((region->pDimensionDefinitions[dim].split_type == gig::split_type_normal &&
541 region->pDimensionRegions[c]->DimensionUpperLimits[dim]) ||
542 (region->pDimensionDefinitions[dim].dimension == gig::dimension_velocity &&
543 region->pDimensionRegions[c]->VelocityUpperLimit));
544
545 // dimensions of split_type_bit cannot be resized
546 if (region->pDimensionDefinitions[dim].split_type != gig::split_type_bit) {
547 int prev_limit = 0;
548 for (int iZone = 0 ; iZone < nbZones - 1 ; iZone++) {
549 gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];
550 const int upperLimit =
551 (customsplits) ?
552 (d->DimensionUpperLimits[dim]) ?
553 d->DimensionUpperLimits[dim] : d->VelocityUpperLimit
554 : (iZone+1) * (int)region->pDimensionDefinitions[dim].zone_size - 1;
555 int limit = upperLimit + 1;
556 int limitx = int((w - label_width - 1) * limit / 128.0 + 0.5) + label_width;
557 if (x <= limitx - 2) break;
558 if (x <= limitx + 2) {
559 resize.dimension = dim;
560 resize.offset = iZone << bitpos;
561 resize.pos = limit;
562 resize.min = prev_limit;
563
564 int dr = (dimregno >> bitpos) &
565 ((1 << region->pDimensionDefinitions[dim].bits) - 1);
566 resize.selected = dr == iZone ? resize.left :
567 dr == iZone + 1 ? resize.right : resize.none;
568
569 iZone++;
570 gig::DimensionRegion *d = region->pDimensionRegions[c + (iZone << bitpos)];
571
572 const int upperLimit =
573 (customsplits) ?
574 (d->DimensionUpperLimits[dim]) ?
575 d->DimensionUpperLimits[dim] : d->VelocityUpperLimit
576 : (iZone+1) * (int)region->pDimensionDefinitions[dim].zone_size - 1;
577
578 int limit = upperLimit + 1;
579 resize.max = limit;
580 return true;
581 }
582 prev_limit = limit;
583 }
584 }
585 }
586 return false;
587 }
588
589 sigc::signal<void>& DimRegionChooser::signal_dimregion_selected()
590 {
591 return dimregion_selected;
592 }
593
594 sigc::signal<void>& DimRegionChooser::signal_region_changed()
595 {
596 return region_changed;
597 }
598
599 bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
600 {
601 // TODO: kolla att region finns osv, dvs att det g�r att s�tta
602 // fokus.
603 if (direction == Gtk::DIR_TAB_FORWARD ||
604 direction == Gtk::DIR_DOWN) {
605 if (!has_focus()) {
606 focus_line = 0;
607 grab_focus();
608 return true;
609 } else {
610 if (focus_line + 1 < region->Dimensions) {
611 focus_line++;
612 queue_draw();
613 return true;
614 } else {
615 return false;
616 }
617 }
618 } else if (direction == Gtk::DIR_TAB_BACKWARD ||
619 direction == Gtk::DIR_UP) {
620 if (!has_focus()) {
621 focus_line = region->Dimensions - 1;
622 grab_focus();
623 return true;
624 } else {
625 if (focus_line > 0) {
626 focus_line--;
627 queue_draw();
628 return true;
629 } else {
630 return false;
631 }
632 }
633 } else if (!has_focus()) {
634 // TODO: kolla att focus_line finns!
635 grab_focus();
636 return true;
637 } else {
638 // TODO: �ka eller minska v�rde!
639 }
640 }

  ViewVC Help
Powered by ViewVC