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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1052 - (hide annotations) (download)
Sat Mar 3 12:20:01 2007 UTC (17 years ago) by persson
Original Path: gigedit/branches/linuxsampler_org/src/dimregionchooser.cpp
File size: 14398 byte(s)
Initial revision

1 persson 1052 /*
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    
22     DimRegionChooser::DimRegionChooser()
23     {
24     // get_window() would return 0 because the Gdk::Window has not yet been realized
25     // So we can only allocate the colors here - the rest will happen in on_realize().
26     Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
27    
28     black = Gdk::Color("black");
29     white = Gdk::Color("white");
30     red = Gdk::Color("#8070ff");
31     blue = Gdk::Color("blue");
32     green = Gdk::Color("green");
33    
34     colormap->alloc_color(black);
35     colormap->alloc_color(white);
36     colormap->alloc_color(red);
37     colormap->alloc_color(blue);
38     colormap->alloc_color(green);
39     instrument = 0;
40     region = 0;
41     dimregno = -1;
42     focus_line = 0;
43     set_flags(Gtk::CAN_FOCUS);
44     add_events(Gdk::BUTTON_PRESS_MASK);
45    
46     for (int i = 0 ; i < 256 ; i++) {
47     dimvalue_from[i] = 0;
48     dimvalue_to[i] = 1;
49     }
50     }
51    
52     DimRegionChooser::~DimRegionChooser()
53     {
54     }
55    
56     void DimRegionChooser::on_realize()
57     {
58     // We need to call the base on_realize()
59     Gtk::DrawingArea::on_realize();
60    
61     // Now we can allocate any additional resources we need
62     Glib::RefPtr<Gdk::Window> window = get_window();
63     gc = Gdk::GC::create(window);
64     }
65    
66     bool DimRegionChooser::on_expose_event(GdkEventExpose* event)
67     {
68     if (!region) return true;
69    
70     int a = 1, b, c;
71     for (int i = 0 ; i < region->Dimensions ; i++) {
72     b = a * region->pDimensionDefinitions[i].zones;
73     if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
74     c = dimregno >= 0 ? (dimregno & ((a - 1) | ~(b - 1))) : 0;
75     break;
76     }
77     a = b;
78     }
79    
80     // This is where we draw on the window
81     Glib::RefPtr<Gdk::Window> window = get_window();
82     Glib::RefPtr<Pango::Context> context = get_pango_context();
83    
84     Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
85    
86     window->clear();
87     const int h = 20;
88     const int w = 800;
89     const int w1 = 100;
90     int y = 0;
91     int bitcount = 0;
92     for (int i = 0 ; i < region->Dimensions ; i++) {
93     const int nb = region->pDimensionDefinitions[i].zones;
94     if (nb) {
95     char* dstr;
96     switch (region->pDimensionDefinitions[i].dimension) {
97     case gig::dimension_none: dstr="none"; break;
98     case gig::dimension_samplechannel: dstr="samplechannel"; break;
99     case gig::dimension_layer: dstr="layer"; break;
100     case gig::dimension_velocity: dstr="velocity"; break;
101     case gig::dimension_channelaftertouch: dstr="channelaftertouch"; break;
102     case gig::dimension_releasetrigger: dstr="releasetrigger"; break;
103     case gig::dimension_keyboard: dstr="keyboard"; break;
104     case gig::dimension_roundrobin: dstr="roundrobin"; break;
105     case gig::dimension_random: dstr="random"; break;
106     case gig::dimension_modwheel: dstr="modwheel"; break;
107     case gig::dimension_breath: dstr="breath"; break;
108     case gig::dimension_foot: dstr="foot"; break;
109     case gig::dimension_portamentotime: dstr="portamentotime"; break;
110     case gig::dimension_effect1: dstr="effect1"; break;
111     case gig::dimension_effect2: dstr="effect2"; break;
112     case gig::dimension_genpurpose1: dstr="genpurpose1"; break;
113     case gig::dimension_genpurpose2: dstr="genpurpose2"; break;
114     case gig::dimension_genpurpose3: dstr="genpurpose3"; break;
115     case gig::dimension_genpurpose4: dstr="genpurpose4"; break;
116     case gig::dimension_sustainpedal: dstr="sustainpedal"; break;
117     case gig::dimension_portamento: dstr="portamento"; break;
118     case gig::dimension_sostenutopedal: dstr="sostenutopedal"; break;
119     case gig::dimension_softpedal: dstr="softpedal"; break;
120     case gig::dimension_genpurpose5: dstr="genpurpose5"; break;
121     case gig::dimension_genpurpose6: dstr="genpurpose6"; break;
122     case gig::dimension_genpurpose7: dstr="genpurpose7"; break;
123     case gig::dimension_genpurpose8: dstr="genpurpose8"; break;
124     case gig::dimension_effect1depth: dstr="effect1depth"; break;
125     case gig::dimension_effect2depth: dstr="effect2depth"; break;
126     case gig::dimension_effect3depth: dstr="effect3depth"; break;
127     case gig::dimension_effect4depth: dstr="effect4depth"; break;
128     case gig::dimension_effect5depth: dstr="effect5depth"; break;
129     }
130     layout->set_text(dstr);
131    
132     Pango::Rectangle rectangle = layout->get_logical_extents();
133     double text_h = double(rectangle.get_height()) / Pango::SCALE;
134     Glib::RefPtr<const Gdk::GC> fg = get_style()->get_fg_gc(get_state());
135     window->draw_layout(fg, 4, int(y + (h - text_h) / 2 + 0.5), layout);
136    
137     if (has_focus() && focus_line == i) {
138     Gdk::Rectangle farea(0, y, 50, 20);
139     get_style()->paint_focus(window, get_state(), farea, *this, "hejsan", 0, y, 50, 20);
140     }
141    
142     Glib::RefPtr<const Gdk::GC> black = get_style()->get_black_gc();
143     window->draw_line(black, w1, y, w - 1, y);
144     window->draw_line(black, w - 1, y + h - 1, w1, y + h - 1);
145     window->draw_rectangle(get_style()->get_white_gc(), true, w1 + 1, y + 1, (w - w1 - 2), h - 2);
146    
147     if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
148     region->pDimensionRegions[c]->VelocityUpperLimit) {
149     window->draw_line(black, w1, y + 1, w1, y + h - 2);
150     for (int k = c ; k < b ; k += a) {
151     gig::DimensionRegion *d = region->pDimensionRegions[k];
152     int v = d->VelocityUpperLimit + 1;
153     int x = int((w - w1 - 1) * v / 128.0 + 0.5);
154     window->draw_line(black, w1 + x, y + 1, w1 + x, y + h - 2);
155     }
156     } else {
157     for (int j = 0 ; j <= nb ; j++) {
158     int x = int((w - w1 - 1) * j / double(nb) + 0.5);
159     window->draw_line(black, w1 + x, y + 1, w1 + x, y + h - 2);
160     }
161     }
162    
163     if (dimregno >= 0) {
164     gc->set_foreground(red);
165     int dr = (dimregno >> bitcount) & ((1 << region->pDimensionDefinitions[i].bits) - 1);
166     if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity &&
167     region->pDimensionRegions[c]->VelocityUpperLimit) {
168     int x1 = 0, dr2 = 0;
169     for (int k = c ; k < b ; k += a) {
170     gig::DimensionRegion *d = region->pDimensionRegions[k];
171     int v = d->VelocityUpperLimit + 1;
172     int x2 = int((w - w1 - 1) * v / 128.0 + 0.5);
173     if (dr2 == dr) {
174     window->draw_rectangle(gc, true, w1 + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);
175     break;
176     }
177     dr2++;
178     x1 = x2;
179     }
180     } else {
181     if (dr < nb) {
182     int x1 = int((w - w1 - 1) * dr / double(nb) + 0.5);
183     int x2 = int((w - w1 - 1) * (dr + 1) / double(nb) + 0.5);
184     window->draw_rectangle(gc, true, w1 + x1 + 1, y + 1, (x2 - x1) - 1, h - 2);
185     }
186     }
187     }
188    
189     y += h;
190     }
191     bitcount += region->pDimensionDefinitions[i].bits;
192     }
193    
194     return true;
195     }
196    
197    
198     void DimRegionChooser::on_size_request(GtkRequisition* requisition)
199     {
200     printf("DimRegionChooser::on_size_request\n");
201     *requisition = GtkRequisition();
202     requisition->height = region ? region->Dimensions * 20 : 0;
203     requisition->width = 800;
204     }
205    
206     void DimRegionChooser::set_instrument(gig::Instrument* instrument)
207     {
208     this->instrument = instrument;
209     this->region = 0;
210     this->dimregno = -1;
211     queue_draw();
212     }
213    
214     void DimRegionChooser::set_region(gig::Region* region)
215     {
216     this->region = region;
217     dimregno = 0;
218     int bitcount = 0;
219     for (int dim = 0 ; dim < region->Dimensions ; dim++) {
220     int from = dimvalue_from[region->pDimensionDefinitions[dim].dimension];
221     int to = dimvalue_to[region->pDimensionDefinitions[dim].dimension];
222     int z;
223     switch (region->pDimensionDefinitions[dim].split_type) {
224     case gig::split_type_normal:
225     z = int((to + from) / 2.0 / region->pDimensionDefinitions[dim].zone_size);
226     break;
227     case gig::split_type_bit:
228     z = std::min(from, region->pDimensionDefinitions[dim].zones - 1);
229     break;
230     }
231     int mask =
232     ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<
233     bitcount);
234     dimregno &= mask;
235     dimregno |= (z << bitcount);
236     bitcount += region->pDimensionDefinitions[dim].bits;
237     }
238     dimreg = region->pDimensionRegions[dimregno];
239     sel_changed_signal.emit();
240     queue_resize();
241     }
242    
243     /*
244     void DimRegionChooser::set_dimregno(int x) {
245     this->dimregno = x;
246     queue_draw();
247     }
248     */
249    
250     bool DimRegionChooser::on_button_press_event(GdkEventButton* event)
251     {
252     const int h = 20;
253     const int w = 800;
254     const int w1 = 100;
255    
256     if (region) {
257     if (event->y < region->Dimensions * h &&
258     event->x >= w1 && event->x < w) {
259    
260     int dim = int(event->y / h);
261     const int nb = region->pDimensionDefinitions[dim].zones;
262    
263     int z = -1;
264     if (region->pDimensionDefinitions[dim].dimension == gig::dimension_velocity) {
265     int a = 1, b, c;
266     for (int i = 0 ; i < region->Dimensions ; i++) {
267     b = a * region->pDimensionDefinitions[i].zones;
268     if (region->pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
269     c = dimregno >= 0 ? (dimregno & ((a - 1) | ~(b - 1))) : 0;
270     break;
271     }
272     a = b;
273     }
274    
275     if (region->pDimensionRegions[c]->VelocityUpperLimit) {
276     int vel = int((event->x - w1) * 128 / (w - w1 - 1));
277    
278     z = 0;
279     for (int k = c ; k < b ; k += a) {
280     gig::DimensionRegion *d = region->pDimensionRegions[k];
281     if (vel <= d->VelocityUpperLimit) break;
282     z++;
283     }
284     }
285     }
286    
287     if (z == -1) {
288     z = int((event->x - w1) * nb / (w - w1 - 1));
289     }
290    
291     printf("dim=%d z=%d dimensionsource=%d split_type=%d zones=%d zone_size=%f\n", dim, z,
292     region->pDimensionDefinitions[dim].dimension,
293     region->pDimensionDefinitions[dim].split_type,
294     region->pDimensionDefinitions[dim].zones,
295     region->pDimensionDefinitions[dim].zone_size);
296     switch (region->pDimensionDefinitions[dim].split_type) {
297     case gig::split_type_normal:
298     dimvalue_from[region->pDimensionDefinitions[dim].dimension] =
299     int(z * region->pDimensionDefinitions[dim].zone_size);
300     dimvalue_to[region->pDimensionDefinitions[dim].dimension] =
301     int((z + 1) * region->pDimensionDefinitions[dim].zone_size) - 1;
302     break;
303     case gig::split_type_bit:
304     dimvalue_from[region->pDimensionDefinitions[dim].dimension] = z;
305     dimvalue_to[region->pDimensionDefinitions[dim].dimension] = z + 1;
306     break;
307     }
308     if (dimregno < 0) dimregno = 0;
309     int bitcount = 0;
310     for (int i = 0 ; i < dim ; i++) {
311     bitcount += region->pDimensionDefinitions[i].bits;
312     }
313    
314     int mask =
315     ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) <<
316     bitcount);
317     dimregno &= mask;
318     dimregno |= (z << bitcount);
319    
320     focus_line = dim;
321     if (has_focus()) queue_draw();
322     else grab_focus();
323     dimreg = region->pDimensionRegions[dimregno];
324     sel_changed_signal.emit();
325     }
326     }
327     return true;
328     }
329    
330     sigc::signal<void> DimRegionChooser::signal_sel_changed()
331     {
332     return sel_changed_signal;
333     }
334    
335     bool DimRegionChooser::on_focus(Gtk::DirectionType direction)
336     {
337     // TODO: kolla att region finns osv, dvs att det g�r att s�tta
338     // fokus.
339     if (direction == Gtk::DIR_TAB_FORWARD ||
340     direction == Gtk::DIR_DOWN) {
341     if (!has_focus()) {
342     focus_line = 0;
343     grab_focus();
344     return true;
345     } else {
346     if (focus_line + 1 < region->Dimensions) {
347     focus_line++;
348     queue_draw();
349     return true;
350     } else {
351     return false;
352     }
353     }
354     } else if (direction == Gtk::DIR_TAB_BACKWARD ||
355     direction == Gtk::DIR_UP) {
356     if (!has_focus()) {
357     focus_line = region->Dimensions - 1;
358     grab_focus();
359     return true;
360     } else {
361     if (focus_line > 0) {
362     focus_line--;
363     queue_draw();
364     return true;
365     } else {
366     return false;
367     }
368     }
369     } else if (!has_focus()) {
370     // TODO: kolla att focus_line finns!
371     grab_focus();
372     return true;
373     } else {
374     // TODO: �ka eller minska v�rde!
375     }
376     }

  ViewVC Help
Powered by ViewVC