/[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 1831 - (show annotations) (download)
Tue Feb 3 19:38:19 2009 UTC (15 years, 1 month ago) by persson
File size: 26695 byte(s)
* made all visible strings translatable

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

  ViewVC Help
Powered by ViewVC