summaryrefslogtreecommitdiff
path: root/muse2/awl/posedit.cpp
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2010-11-28 21:14:50 +0000
committerTim E. Real <termtech@rogers.com>2010-11-28 21:14:50 +0000
commit8dc8689a009a3702bf4135e628f9d63df8b2ea36 (patch)
treefea6d4781b06fabfb24255751df95de750099830 /muse2/awl/posedit.cpp
parentb121a3b91f0e288934c4d78161ff1d20f96ff861 (diff)
Added AWL files
Diffstat (limited to 'muse2/awl/posedit.cpp')
-rw-r--r--muse2/awl/posedit.cpp441
1 files changed, 441 insertions, 0 deletions
diff --git a/muse2/awl/posedit.cpp b/muse2/awl/posedit.cpp
new file mode 100644
index 00000000..4f8b19b2
--- /dev/null
+++ b/muse2/awl/posedit.cpp
@@ -0,0 +1,441 @@
+//=============================================================================
+// Awl
+// Audio Widget Library
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al/al.h"
+#include "awl.h"
+#include "posedit.h"
+#include "al/sig.h"
+
+namespace Awl {
+
+ using AL::mtcType;
+ using AL::sigmap;
+
+//---------------------------------------------------------
+// PosEdit
+//---------------------------------------------------------
+
+PosEdit::PosEdit(QWidget* parent)
+ : QAbstractSpinBox(parent)
+ {
+ initialized = false;
+ setReadOnly(false);
+ setSmpte(false);
+ }
+
+void* PosEdit::operator new(size_t n)
+ {
+ void* p = new char[n];
+ memset(p, 0, n);
+ return p;
+ }
+
+PosEdit::~PosEdit()
+ {
+ }
+
+QSize PosEdit::sizeHint() const
+ {
+ QFontMetrics fm(font());
+ int fw = style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth);
+ int h = fm.height() + fw * 2;
+ int w = fw * 4 + 10; // HACK: 10 = spinbox up/down arrows
+ if (_smpte)
+ w += 2 + fm.width('9') * 9 + fm.width(':') * 3 + fw * 4;
+ else
+ w += 2 + fm.width('9') * 9 + fm.width('.') * 2 + fw * 4;
+ return QSize(w, h).expandedTo(QApplication::globalStrut());
+ }
+
+//---------------------------------------------------------
+// event
+// filter Tab and Backtab key events
+//---------------------------------------------------------
+
+bool PosEdit::event(QEvent* event)
+ {
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent* ke = static_cast<QKeyEvent*>(event);
+ int segment = curSegment();
+ if (ke->key() == Qt::Key_Backtab) {
+ if (_smpte) {
+ if (segment == 3) {
+ lineEdit()->setSelection(7, 2);
+ return true;
+ }
+ else if (segment == 2) {
+ lineEdit()->setSelection(4, 2);
+ return true;
+ }
+ else if (segment == 1) {
+ lineEdit()->setSelection(0, 3);
+ return true;
+ }
+ }
+ else {
+ if (segment == 2) {
+ lineEdit()->setSelection(5, 2);
+ return true;
+ }
+ if (segment == 1) {
+ lineEdit()->setSelection(0, 4);
+ return true;
+ }
+ }
+ }
+ if (ke->key() == Qt::Key_Tab) {
+ if (_smpte) {
+ if (segment == 0) {
+ lineEdit()->setSelection(4, 2);
+ return true;
+ }
+ else if (segment == 1) {
+ lineEdit()->setSelection(7, 2);
+ return true;
+ }
+ else if (segment == 2) {
+ lineEdit()->setSelection(10, 2);
+ return true;
+ }
+ }
+ else {
+ if (segment == 0) {
+ lineEdit()->setSelection(5, 2);
+ return true;
+ }
+ if (segment == 1) {
+ lineEdit()->setSelection(8, 3);
+ return true;
+ }
+ }
+ }
+ }
+ else if (event->type() == QEvent::FocusIn) {
+ QFocusEvent* fe = static_cast<QFocusEvent*>(event);
+ QAbstractSpinBox::focusInEvent(fe);
+ int segment = curSegment();
+ switch(segment) {
+ case 0: lineEdit()->setSelection(0,4); break;
+ case 1: lineEdit()->setSelection(5,2); break;
+ case 2: lineEdit()->setSelection(8,3); break;
+ }
+ return true;
+ }
+ return QAbstractSpinBox::event(event);
+ }
+
+//---------------------------------------------------------
+// setSmpte
+//---------------------------------------------------------
+
+void PosEdit::setSmpte(bool f)
+ {
+ _smpte = f;
+ if (_smpte)
+ lineEdit()->setInputMask("999:99:99:99");
+ else
+ lineEdit()->setInputMask("9999.99.999");
+ updateValue();
+ }
+
+//---------------------------------------------------------
+// setValue
+//---------------------------------------------------------
+
+void PosEdit::setValue(const Pos& time)
+ {
+ _pos = time;
+ updateValue();
+ }
+
+void PosEdit::setValue(const QString& s)
+ {
+ Pos time(s);
+ setValue(time);
+ }
+
+void PosEdit::setValue(int t)
+ {
+ Pos time(t);
+ setValue(time);
+ }
+
+//---------------------------------------------------------
+// updateValue
+//---------------------------------------------------------
+
+void PosEdit::updateValue()
+ {
+ char buffer[64];
+ if (_smpte) {
+ int minute, sec, frame, subframe;
+ _pos.msf(&minute, &sec, &frame, &subframe);
+ sprintf(buffer, "%03d:%02d:%02d:%02d", minute, sec, frame, subframe);
+ }
+ else {
+ int bar, beat;
+ int tick;
+ _pos.mbt(&bar, &beat, &tick);
+ sprintf(buffer, "%04d.%02d.%03d", bar+1, beat+1, tick);
+ }
+ lineEdit()->setText(buffer);
+ }
+
+//---------------------------------------------------------
+// stepEnables
+//---------------------------------------------------------
+
+QAbstractSpinBox::StepEnabled PosEdit::stepEnabled() const
+ {
+ int segment = curSegment();
+ QAbstractSpinBox::StepEnabled en = QAbstractSpinBox::StepUpEnabled | QAbstractSpinBox::StepDownEnabled;
+
+ if (_smpte) {
+ int minute, sec, frame, subframe;
+ _pos.msf(&minute, &sec, &frame, &subframe);
+ switch(segment) {
+ case 0:
+ if (minute == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ break;
+ case 1:
+ if (sec == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ else if (sec == 59)
+ en &= ~QAbstractSpinBox::StepUpEnabled;
+ break;
+ case 2:
+ if (frame == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ else if (frame == 23)
+ en &= ~QAbstractSpinBox::StepUpEnabled;
+ break;
+ case 3:
+ if (subframe == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ else if (subframe == 99)
+ en &= ~QAbstractSpinBox::StepUpEnabled;
+ break;
+ }
+ }
+ else {
+ int bar, beat;
+ unsigned tick;
+ AL::sigmap.tickValues(_pos.tick(), &bar, &beat, &tick);
+ unsigned tb = AL::sigmap.ticksBeat(_pos.tick());
+ unsigned tm = AL::sigmap.ticksMeasure(_pos.tick());
+ int bm = tm / tb;
+
+ switch (segment) {
+ case 0:
+ if (bar == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ break;
+ case 1:
+ if (beat == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ else {
+ if (beat >= (bm-1))
+ en &= ~QAbstractSpinBox::StepUpEnabled;
+ }
+ break;
+ case 2:
+ if (tick == 0)
+ en &= ~QAbstractSpinBox::StepDownEnabled;
+ else {
+ if (tick >= (tb-1))
+ en &= ~QAbstractSpinBox::StepUpEnabled;
+ }
+ break;
+ }
+ }
+ return en;
+ }
+
+//---------------------------------------------------------
+// fixup
+//---------------------------------------------------------
+
+void PosEdit::fixup(QString& input) const
+ {
+ printf("fixup <%s>\n", input.toLatin1().data());
+ }
+
+//---------------------------------------------------------
+// validate
+//---------------------------------------------------------
+
+QValidator::State PosEdit::validate(QString&,int&) const
+ {
+ // TODO
+// printf("validate\n");
+ return QValidator::Acceptable;
+ }
+
+//---------------------------------------------------------
+// curSegment
+//---------------------------------------------------------
+
+int PosEdit::curSegment() const
+ {
+ QLineEdit* le = lineEdit();
+ int pos = le->cursorPosition();
+ int segment = -1;
+
+ if (_smpte) {
+ if (pos >= 0 && pos <= 3)
+ segment = 0;
+ else if (pos >= 4 && pos <= 6)
+ segment = 1;
+ else if (pos >= 7 && pos <= 9)
+ segment = 2;
+ else if (pos >= 10)
+ segment = 3;
+ }
+ else {
+ if (pos >= 0 && pos <= 4)
+ segment = 0;
+ else if (pos >= 5 && pos <= 7)
+ segment = 1;
+ else if (pos >= 8)
+ segment = 2;
+ else
+ printf("curSegment = -1, pos %d\n", pos);
+ }
+ return segment;
+ }
+
+//---------------------------------------------------------
+// stepBy
+//---------------------------------------------------------
+
+void PosEdit::stepBy(int steps)
+ {
+ int segment = curSegment();
+ int selPos;
+ int selLen;
+
+ bool changed = false;
+
+ if (_smpte) {
+ int minute, sec, frame, subframe;
+ _pos.msf(&minute, &sec, &frame, &subframe);
+ switch(segment) {
+ case 0:
+ minute += steps;
+ if (minute < 0)
+ minute = 0;
+ selPos = 0;
+ selLen = 3;
+ break;
+ case 1:
+ sec += steps;
+ if (sec < 0)
+ sec = 0;
+ if (sec > 59)
+ sec = 59;
+ selPos = 4;
+ selLen = 2;
+ break;
+ case 2:
+ frame += steps;
+ if (frame < 0)
+ frame = 0;
+ if (frame > 24) //TD frame type?
+ frame = 24;
+ selPos = 7;
+ selLen = 2;
+ break;
+ case 3:
+ subframe += steps;
+ if (subframe < 0)
+ subframe = 0;
+ if (subframe > 99)
+ subframe = 99;
+ selPos = 10;
+ selLen = 2;
+ break;
+ default:
+ return;
+ }
+ Pos newPos(minute, sec, frame, subframe);
+ if (!(newPos == _pos)) {
+ changed = true;
+ _pos = newPos;
+ }
+ }
+ else {
+ int bar, beat, tick;
+ _pos.mbt(&bar, &beat, &tick);
+
+ int tb = AL::sigmap.ticksBeat(_pos.tick());
+ unsigned tm = AL::sigmap.ticksMeasure(_pos.tick());
+ int bm = tm / tb;
+
+ switch(segment) {
+ case 0:
+ bar += steps;
+ if (bar < 0)
+ bar = 0;
+ selPos = 0;
+ selLen = 4;
+ break;
+ case 1:
+ beat += steps;
+ if (beat < 0)
+ beat = 0;
+ else if (beat >= bm)
+ beat = bm - 1;
+ selPos = 5;
+ selLen = 2;
+ break;
+ case 2:
+ tick += steps;
+ if (tick < 0)
+ tick = 0;
+ else if (tick >= tb)
+ tick = tb -1;
+ selPos = 8;
+ selLen = 3;
+ break;
+ default:
+ return;
+ }
+ Pos newPos(bar, beat, tick);
+ if (!(newPos == _pos)) {
+ changed = true;
+ _pos = newPos;
+ }
+ }
+ if (changed) {
+ updateValue();
+ emit valueChanged(_pos);
+ }
+ lineEdit()->setSelection(selPos, selLen);
+ }
+
+ void PosEdit::paintEvent(QPaintEvent* event) {
+ if (!initialized)
+ updateValue();
+ initialized = true;
+ QAbstractSpinBox::paintEvent(event);
+ }
+}
+