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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1656 - (hide annotations) (download)
Sat Feb 2 08:18:19 2008 UTC (16 years, 1 month 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 schoenebeck 1225 /*
2 persson 1623 * Copyright (C) 2006-2008 Andreas Persson
3 schoenebeck 1225 *
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 persson 1303 for (int i = 0 ; i < 256 ; i++) dimvalue[i] = 0;
52 schoenebeck 1225 }
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 persson 1623 int w = get_width();
74 schoenebeck 1225 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 schoenebeck 1656 case gig::dimension_keyboard: dstr="keyswitching"; break;
97 schoenebeck 1225 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 persson 1303 int z = std::min(dimvalue[region->pDimensionDefinitions[dim].dimension],
250     region->pDimensionDefinitions[dim].zones - 1);
251 schoenebeck 1225 dimregno |= (z << bitcount);
252     bitcount += region->pDimensionDefinitions[dim].bits;
253     }
254     dimreg = region->pDimensionRegions[dimregno];
255     } else {
256     dimreg = 0;
257     }
258 persson 1261 dimregion_selected();
259 schoenebeck 1225 queue_resize();
260     }
261    
262 persson 1533
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 schoenebeck 1225 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 persson 1261 region_changed();
364 schoenebeck 1225
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 persson 1623 int w = get_width();
376 schoenebeck 1225 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 persson 1303 dimvalue[region->pDimensionDefinitions[dim].dimension] = z;
437 schoenebeck 1225
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 persson 1261 dimregion_selected();
445 schoenebeck 1225 }
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 persson 1623 int w = get_width();
459 schoenebeck 1225 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 persson 1623 int w = get_width();
522 schoenebeck 1225 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 schoenebeck 1339 sigc::signal<void>& DimRegionChooser::signal_dimregion_selected()
590 schoenebeck 1225 {
591 persson 1261 return dimregion_selected;
592 schoenebeck 1225 }
593    
594 schoenebeck 1339 sigc::signal<void>& DimRegionChooser::signal_region_changed()
595 persson 1261 {
596     return region_changed;
597     }
598    
599 schoenebeck 1225 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