~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to midiedit/dlist.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2005-08-23 17:19:39 UTC
  • mto: (4.1.1 breezy) (1.1.9) (10.1.6 sid)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20050823171939-hd8fgzokb4dbj007
Tags: upstream-0.7.1+0.7.2pre2
ImportĀ upstreamĀ versionĀ 0.7.1+0.7.2pre2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//=========================================================
2
 
//  MusE
3
 
//  Linux Music Editor
4
 
//    $Id: dlist.cpp,v 1.4 2003/11/19 21:28:40 lunar_shuttle Exp $
5
 
//  (C) Copyright 1999 Werner Schweer (ws@seh.de)
6
 
//=========================================================
7
 
 
8
 
#include "icons.h"
9
 
#include "dlist.h"
10
 
#include <qpainter.h>
11
 
#include <stdio.h>
12
 
#include <qheader.h>
13
 
#include <qcursor.h>
14
 
#include "song.h"
15
 
#include "scrollscale.h"
16
 
#include <qpopupmenu.h>
17
 
#include <qlineedit.h>
18
 
 
19
 
#include "pitchedit.h"
20
 
#include "midiport.h"
21
 
#include "drummap.h"
22
 
 
23
 
enum DCols { COL_MUTE=0, COL_NAME, COL_QNT, COL_ENOTE, COL_LEN,
24
 
         COL_ANOTE, COL_CHANNEL, COL_PORT,
25
 
         COL_LV1, COL_LV2, COL_LV3, COL_LV4, COL_NONE=-1};
26
 
 
27
 
//---------------------------------------------------------
28
 
//   draw
29
 
//---------------------------------------------------------
30
 
 
31
 
void DList::draw(QPainter& p, const QRect& rect)
32
 
      {
33
 
      int x = rect.x();
34
 
      int y = rect.y();
35
 
      int w = rect.width();
36
 
      int h = rect.height();
37
 
 
38
 
      //---------------------------------------------------
39
 
      //    Tracks
40
 
      //---------------------------------------------------
41
 
 
42
 
      p.setPen(black);
43
 
 
44
 
 
45
 
      for (int i = 0; i < DRUM_MAPSIZE; ++i) {
46
 
            int yy = i * TH;
47
 
            if (yy+TH < y)
48
 
                  continue;
49
 
            if (yy > y + h)
50
 
                  break;
51
 
            DrumMap* dm = &drumMap[i];
52
 
            if (dm->selected)
53
 
                  p.fillRect(x, yy, w, TH, yellow);
54
 
            else
55
 
                  p.eraseRect(x, yy, w, TH);
56
 
            for (int k = 0; k < header->count(); ++k) {
57
 
                  int x   = header->sectionPos(k);
58
 
                  int w   = header->sectionSize(k);
59
 
                  QRect r = p.xForm(QRect(x+2, yy, w-4, TH));
60
 
                  QString s;
61
 
                  int align = AlignVCenter | AlignHCenter;
62
 
 
63
 
                  p.save();
64
 
                  p.setWorldXForm(false);
65
 
                  switch (k) {
66
 
                        case COL_QNT:
67
 
                              s.setNum(dm->quant);
68
 
                              break;
69
 
                        case COL_LEN:
70
 
                              s.setNum(dm->len);
71
 
                              break;
72
 
                        case COL_ANOTE:
73
 
                              s = pitch2string(dm->anote);
74
 
                              break;
75
 
                        case COL_ENOTE:
76
 
                              s = pitch2string(dm->enote);
77
 
                              break;
78
 
                        case COL_LV1:
79
 
                              s.setNum(dm->lv1);
80
 
                              break;
81
 
                        case COL_LV2:
82
 
                              s.setNum(dm->lv2);
83
 
                              break;
84
 
                        case COL_LV3:
85
 
                              s.setNum(dm->lv3);
86
 
                              break;
87
 
                        case COL_LV4:
88
 
                              s.setNum(dm->lv4);
89
 
                              break;
90
 
                        case COL_MUTE:
91
 
                              if (dm->mute) {
92
 
                                    p.setPen(red);
93
 
                                    const QPixmap& pm = *muteIcon;
94
 
                                    p.drawPixmap(
95
 
                                       r.x() + r.width()/2 - pm.width()/2,
96
 
                                       r.y() + r.height()/2 - pm.height()/2,
97
 
                                       pm);
98
 
                                    p.setPen(black);
99
 
                                    }
100
 
                              break;
101
 
                        case COL_NAME:
102
 
                              s = dm->name;
103
 
                              align = AlignVCenter | AlignLeft;
104
 
                              break;
105
 
                        case COL_CHANNEL:
106
 
                              s.setNum(dm->channel+1);
107
 
                              break;
108
 
                        case COL_PORT:
109
 
                              s = midiPorts[dm->port].portname();
110
 
                              align = AlignVCenter | AlignLeft;
111
 
                              break;
112
 
                        }
113
 
                  if (!s.isEmpty())
114
 
                        p.drawText(r, align, s);
115
 
                  p.restore();
116
 
                  }
117
 
            }
118
 
 
119
 
      //---------------------------------------------------
120
 
      //    horizontal lines
121
 
      //---------------------------------------------------
122
 
 
123
 
      p.setPen(gray);
124
 
      int yy  = (y / TH) * TH;
125
 
      for (; yy < y + h; yy += TH) {
126
 
            p.drawLine(x, yy, x + w, yy);
127
 
            }
128
 
 
129
 
      if (drag == DRAG) {
130
 
            int y  = (startY/TH) * TH;
131
 
            int dy = startY - y;
132
 
            int yy = curY - dy;
133
 
            p.setPen(green);
134
 
            p.drawLine(x, yy, x + w, yy);
135
 
            p.drawLine(x, yy+TH, x + w, yy+TH);
136
 
            p.setPen(gray);
137
 
            }
138
 
 
139
 
      //---------------------------------------------------
140
 
      //    vertical Lines
141
 
      //---------------------------------------------------
142
 
 
143
 
      p.setWorldXForm(false);
144
 
      int n = header->count();
145
 
      for (int i = 1; i < n; i++) {
146
 
            int x = header->sectionPos(i);
147
 
            p.drawLine(x, 0, x, height());
148
 
            }
149
 
      p.setWorldXForm(true);
150
 
      }
151
 
 
152
 
//---------------------------------------------------------
153
 
//   devicesPopupMenu
154
 
//---------------------------------------------------------
155
 
 
156
 
void DList::devicesPopupMenu(DrumMap* t, int x, int y, bool changeAll)
157
 
      {
158
 
      QPopupMenu* p = midiPortsPopup(this);
159
 
      int n = p->exec(mapToGlobal(QPoint(x, y)), 0);
160
 
      if (n != -1) {
161
 
            if (!changeAll)
162
 
                  t->port = n;
163
 
            else
164
 
            for (int i=0; i<DRUM_MAPSIZE; i++)
165
 
                  drumMap[i].port = n;
166
 
            }
167
 
      delete p;
168
 
      }
169
 
 
170
 
//---------------------------------------------------------
171
 
//   viewMousePressEvent
172
 
//---------------------------------------------------------
173
 
 
174
 
void DList::viewMousePressEvent(QMouseEvent* ev)
175
 
      {
176
 
      int x = ev->x();
177
 
      int y = ev->y();
178
 
      int instr = y/TH;
179
 
      int button = ev->button();
180
 
      bool shift = ev->state() & ShiftButton;
181
 
      unsigned pitch = y / TH;
182
 
      DrumMap* dm = &drumMap[pitch];
183
 
      if (currentlySelected != 0) {
184
 
            if (dm != currentlySelected) {
185
 
                  currentlySelected->selected = false;
186
 
                  dm->selected = true;
187
 
                  currentlySelected = dm;
188
 
                  emit selectionChanged(currentlySelected);
189
 
                  emit keyFilterChanged(instr);
190
 
                  song->update(SC_DRUMMAP);
191
 
                  repaint();
192
 
            }
193
 
      }
194
 
      else {
195
 
            currentlySelected = dm;
196
 
            dm->selected = true;
197
 
            emit selectionChanged(currentlySelected);
198
 
            emit keyFilterChanged(instr);
199
 
            song->update(SC_DRUMMAP);
200
 
            repaint();
201
 
      }
202
 
 
203
 
      startY = y;
204
 
      sPitch = pitch;
205
 
      drag   = START_DRAG;
206
 
 
207
 
      DCols col = DCols(x2col(x));
208
 
 
209
 
      int val;
210
 
      int incVal = 0;
211
 
      if (button == QMouseEvent::RightButton)
212
 
            incVal = 1;
213
 
      else if (button == QMouseEvent::MidButton)
214
 
            incVal = -1;
215
 
 
216
 
      // Check if we're already editing anything and have pressed the mouse elsewhere
217
 
      // In that case, treat it as if a return was pressed
218
 
      if (button == QMouseEvent::LeftButton) {
219
 
                  if ((editEntry && editEntry != dm  || col != selectedColumn) && editEntry != 0) {
220
 
                        returnPressed();
221
 
                        }
222
 
                  }
223
 
 
224
 
      switch (col) {
225
 
            case COL_NONE:
226
 
                  break;
227
 
            case COL_MUTE:
228
 
                  if (button == QMouseEvent::LeftButton)
229
 
                        dm->mute = !dm->mute;
230
 
                  break;
231
 
            case COL_PORT:
232
 
                  if (button == QMouseEvent::RightButton) {
233
 
                        bool changeAll = ev->state() & ControlButton;
234
 
                        devicesPopupMenu(dm, mapx(x), mapy(pitch * TH), changeAll);
235
 
                        }
236
 
                  break;
237
 
            case COL_QNT:
238
 
                  dm->quant += incVal;
239
 
                  // ?? range
240
 
                  break;
241
 
            case COL_ENOTE:
242
 
                  val = dm->enote + incVal;
243
 
                  if (val < 0)
244
 
                        val = 0;
245
 
                  else if (val > 127)
246
 
                        val = 127;
247
 
                  // Check if there is any other drumMap with the same inmap value
248
 
                  // If so, switch the inmap between the instruments
249
 
                  for (int i=0; i<DRUM_MAPSIZE; i++) {
250
 
                        if (drumMap[i].enote == val && &drumMap[i] != dm) {
251
 
                              drumInmap[dm->enote] = i;
252
 
                              drumMap[i].enote = dm->enote;
253
 
                              break;
254
 
                        }
255
 
                  }
256
 
                  dm->enote = val;
257
 
                  drumInmap[val] = pitch; // The inmap for the particular note now points to the instrument we're currently at
258
 
                  break;
259
 
            case COL_LEN:
260
 
                  val = dm->len + incVal;
261
 
                  if (val < 0)
262
 
                        val = 0;
263
 
                  dm->len = val;
264
 
                  break;
265
 
            case COL_ANOTE:
266
 
                  val = dm->anote + incVal;
267
 
                  if (val < 0)
268
 
                        val = 0;
269
 
                  else if (val > 127)
270
 
                        val = 127;
271
 
                  dm->anote = val;
272
 
                  emit keyPressed(dm->enote, shift); //Send input-key
273
 
                  break;
274
 
            case COL_CHANNEL:
275
 
                  val = dm->channel + incVal;
276
 
                  if (val < 0)
277
 
                        val = 0;
278
 
                  else if (val > 127)
279
 
                        val = 127;
280
 
                  if (ev->state() & ControlButton) {
281
 
                        for (int i=0; i<DRUM_MAPSIZE; i++)
282
 
                              drumMap[i].channel = val;
283
 
                  }
284
 
                  else
285
 
                        dm->channel = val;
286
 
                  break;
287
 
            case COL_LV1:
288
 
                  val = dm->lv1 + incVal;
289
 
                  if (val < 0)
290
 
                        val = 0;
291
 
                  else if (val > 127)
292
 
                        val = 127;
293
 
                  dm->lv1 = val;
294
 
                  break;
295
 
            case COL_LV2:
296
 
                  val = dm->lv2 + incVal;
297
 
                  if (val < 0)
298
 
                        val = 0;
299
 
                  else if (val > 127)
300
 
                        val = 127;
301
 
                  dm->lv2 = val;
302
 
                  break;
303
 
            case COL_LV3:
304
 
                  val = dm->lv3 + incVal;
305
 
                  if (val < 0)
306
 
                        val = 0;
307
 
                  else if (val > 127)
308
 
                        val = 127;
309
 
                  dm->lv3 = val;
310
 
                  break;
311
 
            case COL_LV4:
312
 
                  val = dm->lv4 + incVal;
313
 
                  if (val < 0)
314
 
                        val = 0;
315
 
                  else if (val > 127)
316
 
                        val = 127;
317
 
                  dm->lv4 = val;
318
 
                  break;
319
 
            case COL_NAME:
320
 
                  emit keyPressed(dm->enote, shift); //Send input key
321
 
                  break;
322
 
#if 0
323
 
            case COL_CHANNEL:
324
 
                  {
325
 
                  int channel = t->channel();
326
 
                  if (button == QMouseEvent::RightButton) {
327
 
                        if (channel < 15)
328
 
                              ++channel;
329
 
                        }
330
 
                  else if (button == QMouseEvent::MidButton) {
331
 
                        if (channel > 0)
332
 
                              --channel;
333
 
                        }
334
 
                  if (channel != t->channel()) {
335
 
                        t->setChannel(channel);
336
 
                        emit channelChanged();
337
 
                        }
338
 
                  }
339
 
#endif
340
 
            default:
341
 
                  break;
342
 
            }
343
 
      redraw();
344
 
      }
345
 
 
346
 
//---------------------------------------------------------
347
 
//   viewMouseDoubleClickEvent
348
 
//---------------------------------------------------------
349
 
 
350
 
void DList::viewMouseDoubleClickEvent(QMouseEvent* ev)
351
 
      {
352
 
      int x = ev->x();
353
 
      int y = ev->y();
354
 
      unsigned pitch = y / TH;
355
 
      DrumMap* dm = &drumMap[pitch];
356
 
 
357
 
      int section = header->sectionAt(x);
358
 
 
359
 
      if (section == COL_NAME || section == COL_LEN || section == COL_LV1 ||
360
 
            section == COL_LV2 || section == COL_LV3 || section == COL_LV4) {
361
 
            editEntry = dm;
362
 
            if (editor == 0) {
363
 
                  editor = new QLineEdit(this);
364
 
                  connect(editor, SIGNAL(returnPressed()),
365
 
                     SLOT(returnPressed()));
366
 
                  editor->setFrame(true);
367
 
                  }
368
 
            int colx = mapx(header->sectionPos(section));
369
 
            int colw = rmapx(header->sectionSize(section));
370
 
            int coly = mapy(pitch * TH);
371
 
            int colh = rmapy(TH);
372
 
            selectedColumn = section; //Store selected column to have an idea of which one was selected when return is pressed
373
 
            switch (section) {
374
 
                  case COL_NAME:
375
 
                  editor->setText(dm->name);
376
 
                  break;
377
 
 
378
 
                  case COL_LEN: {
379
 
                  editor->setText(QString::number(dm->len));
380
 
                  break;
381
 
                  }
382
 
 
383
 
                  case COL_LV1:
384
 
                  editor->setText(QString::number(dm->lv1));
385
 
                  break;
386
 
 
387
 
                  case COL_LV2:
388
 
                  editor->setText(QString::number(dm->lv2));
389
 
                  break;
390
 
 
391
 
                  case COL_LV3:
392
 
                  editor->setText(QString::number(dm->lv3));
393
 
                  break;
394
 
 
395
 
                  case COL_LV4:
396
 
                  editor->setText(QString::number(dm->lv4));
397
 
                  break;
398
 
            }
399
 
 
400
 
            editor->end(false);
401
 
            editor->setGeometry(colx, coly, colw, colh);
402
 
            //In all cases but the column name, select all text:
403
 
            if (section != COL_NAME)
404
 
                  editor->selectAll();
405
 
            editor->show();
406
 
            }
407
 
      else
408
 
            viewMousePressEvent(ev);
409
 
      }
410
 
 
411
 
//---------------------------------------------------------
412
 
//   x2col
413
 
//---------------------------------------------------------
414
 
 
415
 
int DList::x2col(int x) const
416
 
      {
417
 
      int col = 0;
418
 
      int w = 0;
419
 
      for (; col < header->count(); col++) {
420
 
            w += header->cellSize(col);
421
 
            if (x < w)
422
 
                  break;
423
 
            }
424
 
      if (col == header->count())
425
 
            return -1;
426
 
      return header->mapToLogical(col);
427
 
      }
428
 
 
429
 
//---------------------------------------------------------
430
 
//   moveSelection
431
 
//---------------------------------------------------------
432
 
 
433
 
void DList::moveSelection(int)
434
 
      {
435
 
      }
436
 
 
437
 
//---------------------------------------------------------
438
 
//   sizeChange
439
 
//---------------------------------------------------------
440
 
 
441
 
void DList::sizeChange(int, int, int)
442
 
      {
443
 
      redraw();
444
 
      }
445
 
 
446
 
//---------------------------------------------------------
447
 
//   returnPressed
448
 
//---------------------------------------------------------
449
 
 
450
 
void DList::returnPressed()
451
 
      {
452
 
      int val = -1;
453
 
      if (selectedColumn != COL_NAME) {
454
 
            val = atoi(editor->text().ascii());
455
 
            if (selectedColumn != COL_LEN) {
456
 
                  if (val > 127) //Check bounds for lv1-lv4 values
457
 
                  val = 127;
458
 
                  if (val < 0)
459
 
                  val = 0;
460
 
                  }
461
 
            }
462
 
 
463
 
      switch(selectedColumn) {
464
 
            case COL_NAME:
465
 
                  editEntry->name = editor->text();
466
 
                  break;
467
 
 
468
 
            case COL_LEN:
469
 
                  editEntry->len = atoi(editor->text().ascii());
470
 
                  break;
471
 
 
472
 
            case COL_LV1:
473
 
                  editEntry->lv1 = val;
474
 
                  break;
475
 
 
476
 
            case COL_LV2:
477
 
                  editEntry->lv2 = val;
478
 
                  break;
479
 
 
480
 
            case COL_LV3:
481
 
                  editEntry->lv3 = val;
482
 
                  break;
483
 
 
484
 
            case COL_LV4:
485
 
                  editEntry->lv4 = val;
486
 
                  break;
487
 
 
488
 
            default:
489
 
                  printf("Return pressed in unknown column\n");
490
 
                  break;
491
 
            }
492
 
      selectedColumn = -1;
493
 
      editor->hide();
494
 
      editEntry = 0;
495
 
      setFocus();
496
 
      redraw();
497
 
      }
498
 
 
499
 
//---------------------------------------------------------
500
 
//   moved
501
 
//---------------------------------------------------------
502
 
 
503
 
void DList::moved(int, int)
504
 
      {
505
 
      redraw();
506
 
      }
507
 
 
508
 
//---------------------------------------------------------
509
 
//   tracklistChanged
510
 
//---------------------------------------------------------
511
 
 
512
 
void DList::tracklistChanged()
513
 
      {
514
 
      }
515
 
 
516
 
//---------------------------------------------------------
517
 
//   songChanged
518
 
//---------------------------------------------------------
519
 
 
520
 
void DList::songChanged(int flags)
521
 
      {
522
 
      if (flags & SC_DRUMMAP)
523
 
            redraw();
524
 
      }
525
 
 
526
 
 
527
 
//---------------------------------------------------------
528
 
//   DList
529
 
//---------------------------------------------------------
530
 
 
531
 
DList::DList(QHeader* h, QWidget* parent, int ymag)
532
 
   : View(parent, 1, ymag)
533
 
      {
534
 
      setBg(white);
535
 
      header = h;
536
 
      scroll = 0;
537
 
      header->setTracking(true);
538
 
      connect(header, SIGNAL(sizeChange(int,int,int)),
539
 
         SLOT(sizeChange(int,int,int)));
540
 
      connect(header, SIGNAL(moved(int,int)), SLOT(moved(int,int)));
541
 
      setFocusPolicy(QWidget::StrongFocus);
542
 
      drag = NORMAL;
543
 
      editor = 0;
544
 
      editEntry = 0;
545
 
      currentlySelected = 0;
546
 
      selectedColumn = -1;
547
 
      }
548
 
//---------------------------------------------------------
549
 
//   ~DList
550
 
//---------------------------------------------------------
551
 
DList::~DList()
552
 
{
553
 
      if (currentlySelected != 0)
554
 
            currentlySelected->selected = false; //Reset the global
555
 
}
556
 
 
557
 
//---------------------------------------------------------
558
 
//   viewMouseMoveEvent
559
 
//---------------------------------------------------------
560
 
 
561
 
void DList::viewMouseMoveEvent(QMouseEvent* ev)
562
 
      {
563
 
      curY = ev->y();
564
 
      int delta = curY - startY;
565
 
      switch (drag) {
566
 
            case START_DRAG:
567
 
                  if (delta < 0)
568
 
                        delta = -delta;
569
 
                  if (delta <= 2)
570
 
                        return;
571
 
                  drag = DRAG;
572
 
                  setCursor(QCursor(sizeVerCursor));
573
 
                  redraw();
574
 
                  break;
575
 
            case NORMAL:
576
 
                  break;
577
 
            case DRAG:
578
 
                  redraw();
579
 
                  break;
580
 
            }
581
 
      }
582
 
 
583
 
//---------------------------------------------------------
584
 
//   viewMouseReleaseEvent
585
 
//---------------------------------------------------------
586
 
 
587
 
void DList::viewMouseReleaseEvent(QMouseEvent* ev)
588
 
      {
589
 
      if (drag == DRAG) {
590
 
            int y = ev->y();
591
 
            unsigned dPitch = y / TH;
592
 
            DrumMap dm = drumMap[sPitch];
593
 
            drumMap[sPitch] = drumMap[dPitch];
594
 
            drumMap[dPitch] = dm;
595
 
            setCursor(QCursor(arrowCursor));
596
 
 
597
 
            drumInmap[drumMap[sPitch].enote]  = sPitch;
598
 
            drumOutmap[drumMap[sPitch].anote] = sPitch;
599
 
            drumInmap[drumMap[dPitch].enote]  = dPitch;
600
 
            drumOutmap[drumMap[dPitch].anote] = dPitch;
601
 
            currentlySelected = &drumMap[dPitch];
602
 
            emit mapChanged(sPitch, dPitch); //Pitch change throughout the whole track done in canvas
603
 
            }
604
 
      drag = NORMAL;
605
 
      redraw();
606
 
      if (editEntry)
607
 
            editor->setFocus();
608
 
      int x = ev->x();
609
 
      int y = ev->y();
610
 
      bool shift = ev->state() & ShiftButton;
611
 
      unsigned pitch = y / TH;
612
 
      DrumMap* dm = &drumMap[pitch];
613
 
 
614
 
      DCols col = DCols(x2col(x));
615
 
 
616
 
      switch (col) {
617
 
            case COL_NAME:
618
 
                  emit keyReleased(dm->enote, shift);
619
 
                  break;
620
 
            case COL_ANOTE:
621
 
                  emit keyReleased(dm->enote, shift);
622
 
                  break;
623
 
            default:
624
 
                  break;
625
 
            }
626
 
      }
627
 
 
628
 
int DList::getSelectedInstrument()
629
 
      {
630
 
            if (currentlySelected == 0)
631
 
                  return -1;
632
 
 
633
 
            return drumInmap[currentlySelected->enote];
634
 
      }