//========================================================= // MusE // Linux Music Editor // $Id: mtscale_flo.cpp,v 1.8.2.7 2011/05/19 04:14:01 flo Exp $ // (C) Copyright 1999 Werner Schweer (ws@seh.de) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; version 2 of // the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //========================================================= #include #include #include #include "mtscale_flo.h" #include "song.h" #include "app.h" #include "icons.h" #include "gconfig.h" #include "scoreedit.h" namespace MusEGui { //--------------------------------------------------------- // MTScale // Midi Time Scale //--------------------------------------------------------- MTScaleFlo::MTScaleFlo(ScoreCanvas* parent_editor, QWidget* parent_widget) : View(parent_widget, 1, 1) { setToolTip(tr("bar scale")); pos[0] = MusEGlobal::song->cpos(); pos[1] = MusEGlobal::song->lpos(); pos[2] = MusEGlobal::song->rpos(); xpos=0; xoffset=0; button = Qt::NoButton; setMouseTracking(true); connect(MusEGlobal::song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(setPos(int, unsigned, bool))); connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), SLOT(songChanged(MusECore::SongChangedFlags_t))); connect(MusEGlobal::song, SIGNAL(markerChanged(int)), SLOT(redraw())); connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged())); parent=parent_editor; setFixedHeight(28); setBg(MusEGlobal::config.rulerBg); } void MTScaleFlo::configChanged() { setBg(MusEGlobal::config.rulerBg); } //--------------------------------------------------------- // songChanged //--------------------------------------------------------- void MTScaleFlo::songChanged(MusECore::SongChangedFlags_t type) { if (type & (SC_SIG|SC_TEMPO)) redraw(); } //--------------------------------------------------------- // setPos //--------------------------------------------------------- void MTScaleFlo::setPos(int idx, unsigned val, bool) { if ((val == INT_MAX) || (val == pos[idx])) return; int opos = parent->tick_to_x(pos[idx] == INT_MAX ? val : pos[idx]) + xoffset - xpos; pos[idx] = val; // if (isVisible()) // redraw(); if (isVisible()) { int tval = parent->tick_to_x(val) + xoffset - xpos; int x = -9; int w = 18; if (tval < 0) { // tval<0 occurs whenever the window is scrolled left, so I switched to signed int (ml) redraw(); } else if (opos > tval) { w += opos - tval; x += tval; } else { w += tval - opos; x += opos; } redraw(QRect(x, 0, w, height())); } } //--------------------------------------------------------- // mousePressEvent //--------------------------------------------------------- void MTScaleFlo::mousePressEvent(QMouseEvent* event) { button = event->button(); mouseMoveEvent(event); } //--------------------------------------------------------- // mouseReleaseEvent //--------------------------------------------------------- void MTScaleFlo::mouseReleaseEvent(QMouseEvent*) { button = Qt::NoButton; } //--------------------------------------------------------- // mouseMoveEvent //--------------------------------------------------------- void MTScaleFlo::mouseMoveEvent(QMouseEvent* event) { if (event->modifiers() & Qt::ShiftModifier ) setCursor(QCursor(Qt::PointingHandCursor)); else setCursor(QCursor(Qt::ArrowCursor)); int tick = AL::sigmap.raster(parent->x_to_tick(event->x()-xoffset+xpos), parent->quant_ticks()); if (tick<0) tick=0; int i; switch (button) { case Qt::LeftButton: i = 0; break; case Qt::MidButton: i = 1; break; case Qt::RightButton: if ((MusEGlobal::config.rangeMarkerWithoutMMB) && (event->modifiers() & Qt::ControlModifier)) i = 1; else i = 2; break; default: return; // if no button is pressed the function returns here } MusECore::Pos p(tick, true); if(i== 0 && (event->modifiers() & Qt::ShiftModifier )) { // If shift +LMB we add a marker MusECore::Marker *alreadyExists = MusEGlobal::song->getMarkerAt(tick); if (!alreadyExists) MusEGlobal::song->addMarker(QString(""), tick, false); } else if (i== 2 && (event->modifiers() & Qt::ShiftModifier )) { // If shift +RMB we remove a marker MusECore::Marker *toRemove = MusEGlobal::song->getMarkerAt(tick); if (toRemove) MusEGlobal::song->removeMarker(toRemove); else printf("No marker to remove\n"); } else MusEGlobal::song->setPos(i, p); // all other cases: relocating one of the locators } //--------------------------------------------------------- // draw //--------------------------------------------------------- void MTScaleFlo::draw(QPainter& p, const QRect& r) { int x = r.x(); int w = r.width(); x -= 20; w += 40; // wg. Text //--------------------------------------------------- // draw Marker //--------------------------------------------------- int y = 12; p.setPen(MusEGlobal::config.rulerFg); p.setFont(MusEGlobal::config.fonts[5]); p.drawLine(r.x(), y+1, r.x() + r.width(), y+1); QRect tr(r); tr.setHeight(12); MusECore::MarkerList* marker = MusEGlobal::song->marker(); for (MusECore::iMarker m = marker->begin(); m != marker->end(); ++m) { int xp = parent->tick_to_x(m->second.tick()) + xoffset - xpos; if (xp > x+w) break; int xe = r.x() + r.width(); MusECore::iMarker mm = m; ++mm; if (mm != marker->end()) xe = parent->tick_to_x(mm->first) + xoffset - xpos; QRect tr(xp, 0, xe-xp, 13); QRect wr = r.intersect(tr); if(!wr.isEmpty()) { if (m->second.current()) p.fillRect(wr, MusEGlobal::config.rulerCurrent); int x2; if (mm != marker->end()) x2 = parent->tick_to_x(mm->first) + xoffset - xpos; else x2 = xp+200; if(xp >= -32) p.drawPixmap(xp, 0, *flagIconS); if(xp >= -1023) { QRect r = QRect(xp+10, 0, x2-xp, 12); p.setPen(MusEGlobal::config.rulerFg); p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter, m->second.name()); } if(xp >= 0) { p.setPen(Qt::green); p.drawLine(xp, y, xp, height()); } } } //--------------------------------------------------- // draw location marker //--------------------------------------------------- int h = height()-12; for (int i = 0; i < 3; ++i) { int xp = parent->tick_to_x(pos[i]) + xoffset - xpos; if (xp >= x && xp < x+w) { QPixmap* pm = markIcon[i]; p.drawPixmap(xp - pm->width()/2, y-1, *pm); } } //--------------------------------------------------- // draw beats //--------------------------------------------------- p.setPen(MusEGlobal::config.rulerFg); unsigned ctick; int bar1, bar2, beat; unsigned tick; ctick = parent->x_to_tick(x - xoffset + xpos); AL::sigmap.tickValues(ctick, &bar1, &beat, &tick); AL::sigmap.tickValues(parent->x_to_tick(x+w - xoffset + xpos), &bar2, &beat, &tick); int stick = AL::sigmap.bar2tick(bar1, 0, 0); int ntick; for (int bar = bar1; bar <= bar2; bar++, stick = ntick) { ntick = AL::sigmap.bar2tick(bar+1, 0, 0); int tpix = parent->delta_tick_to_delta_x(ntick - stick); if (tpix < 64) { // don�t show beats if measure is this small int n = 1; if (tpix < 32) n = 2; if (tpix <= 16) n = 4; if (tpix < 8) n = 8; if (tpix <= 4) n = 16; if (tpix <= 2) n = 32; if (bar % n) continue; p.setFont(MusEGlobal::config.fonts[3]); int x = parent->tick_to_x(stick) + xoffset - xpos; QString s; s.setNum(bar + 1); p.drawLine(x, y+1, x, y+1+h); // QRect r = QRect(x+2, y, 0, h); QRect r = QRect(x+2, y, 1000, h); p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip, s); } else { int z, n; AL::sigmap.timesig(stick, z, n); for (int beat = 0; beat < z; beat++) { int xp = parent->tick_to_x(AL::sigmap.bar2tick(bar, beat, 0)) + xoffset - xpos; QString s; QRect r(xp+2, y, 1000, h); int y1; int num; if (beat == 0) { num = bar + 1; y1 = y + 1; p.setFont(MusEGlobal::config.fonts[3]); } else { num = beat + 1; y1 = y + 7; p.setFont(MusEGlobal::config.fonts[4]); r.setY(y+3); } s.setNum(num); p.drawLine(xp, y1, xp, y+1+h); p.drawText(r, Qt::AlignLeft|Qt::AlignVCenter|Qt::TextDontClip, s); } } } } void MTScaleFlo::set_xpos(int pos) { xpos=pos; redraw(); } void MTScaleFlo::set_xoffset(int o) { xoffset=o; redraw(); } void MTScaleFlo::pos_add_changed() { redraw(); } } // namespace MusEGui