/[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 1623 - (show annotations) (download)
Fri Jan 4 19:42:45 2008 UTC (16 years, 3 months ago) by persson
File size: 26568 byte(s)
* gig files where regions are not internally ordered are now handled
* the resize mouse pointer is not shown anymore for regions that can't
  be resized
* the region and dimregion chooser widgets are now resizable
* bugfix: sometimes you could not delete more than one dimension
* filter headers are now also greyed out when the filter is inactive

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="keyboard"; 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