/[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 1261 - (show annotations) (download)
Thu Jul 5 17:12:20 2007 UTC (16 years, 9 months ago) by persson
File size: 26801 byte(s)
* a changed file is now marked with an asterisk in the window title
* added close confirmation dialog, shown if file is changed
* "save" means "save as" for new files
* enabled acceleration keys
* add .gig to filename in "save as" if it's not already there
* filename character encodings other than utf-8 supported

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

  ViewVC Help
Powered by ViewVC