Logo Search packages:      
Sourcecode: rosegarden version File versions  Download package

RulerScale.cpp

/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */

/*
    Rosegarden
    A MIDI and audio sequencer and musical notation editor.
    Copyright 2000-2010 the Rosegarden development team.

    Other copyrights also apply to some parts of this work.  Please
    see the AUTHORS file and individual file headers for details.

    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; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#include <cmath>
#include "RulerScale.h"
#include "Composition.h"

namespace Rosegarden {


//////////////////////////////////////////////////////////////////////
//                 RulerScale
//////////////////////////////////////////////////////////////////////

RulerScale::RulerScale(Composition *c) :
    m_composition(c)
{ 
    // nothing
}

RulerScale::~RulerScale()
{
    // nothing
}

int
00041 RulerScale::getFirstVisibleBar() const
{
    return m_composition->getBarNumber(m_composition->getStartMarker());
}

int
00047 RulerScale::getLastVisibleBar() const
{
    return m_composition->getBarNumber(m_composition->getEndMarker());
}

double
00053 RulerScale::getBarWidth(int n) const
{
    return getBarPosition(n + 1) - getBarPosition(n);
}

double
00059 RulerScale::getBeatWidth(int n) const
{
    std::pair<timeT, timeT> barRange = m_composition->getBarRange(n);
    timeT barDuration = barRange.second - barRange.first;
    if (barDuration == 0) return 0;

    bool isNew;
    TimeSignature timeSig = m_composition->getTimeSignatureInBar(n, isNew);

    // cope with partial bars
    double theoreticalWidth =
      (getBarWidth(n) * timeSig.getBarDuration()) / barDuration;

    return theoreticalWidth / timeSig.getBeatsPerBar();
}

int
00076 RulerScale::getBarForX(double x) const
{
    // binary search

    int minBar = getFirstVisibleBar(),
      maxBar = getLastVisibleBar();
    
    while (maxBar > minBar) {
      int middle = minBar + (maxBar - minBar) / 2;
      if (x > getBarPosition(middle)) minBar = middle + 1;
      else maxBar = middle;
    }

    // we've just done equivalent of lower_bound -- we're one bar too
    // far into the list

    if (minBar > getFirstVisibleBar()) return minBar - 1;
    else return minBar;
}

timeT
00097 RulerScale::getTimeForX(double x) const
{
    int n = getBarForX(x);

    double barWidth = getBarWidth(n);
    std::pair<timeT, timeT> barRange = m_composition->getBarRange(n);

    if (barWidth < 1.0) {

      return barRange.first;

    } else {

      timeT barDuration = barRange.second - barRange.first;
      x -= getBarPosition(n);

      return barRange.first + (timeT)nearbyint(((double)(x * barDuration) / barWidth));
    }
}

double
00118 RulerScale::getXForTime(timeT time) const
{
    int n = m_composition->getBarNumber(time);

    double barWidth = getBarWidth(n);
    std::pair<timeT, timeT> barRange = m_composition->getBarRange(n);
    timeT barDuration = barRange.second - barRange.first;

    if (barDuration == 0) {

      return getBarPosition(n);

    } else {

      time -= barRange.first;
      return getBarPosition(n) + (double)(time * barWidth) / barDuration;
    }
}

timeT
00138 RulerScale::getDurationForWidth(double x, double width) const
{
    return getTimeForX(x + width) - getTimeForX(x);
}

double
00144 RulerScale::getWidthForDuration(timeT startTime, timeT duration) const
{
    return getXForTime(startTime + duration) - getXForTime(startTime);
}

double
00150 RulerScale::getTotalWidth() const
{
    int n = getLastVisibleBar();
    return getBarPosition(n) + getBarWidth(n);
}



//////////////////////////////////////////////////////////////////////
//                 SimpleRulerScale
//////////////////////////////////////////////////////////////////////


00163 SimpleRulerScale::SimpleRulerScale(Composition *composition,
                           double origin, double ratio) :
    RulerScale(composition),
    m_origin(origin),
    m_ratio(ratio)
{
    // nothing
}

SimpleRulerScale::SimpleRulerScale(const SimpleRulerScale &ruler):
    RulerScale(ruler.getComposition()),
    m_origin(ruler.getOrigin()),
    m_ratio(ruler.getUnitsPerPixel())
{
    // nothing
}


SimpleRulerScale::~SimpleRulerScale()
{
    // nothing
}

double
00187 SimpleRulerScale::getBarPosition(int n) const
{
    timeT barStart = m_composition->getBarRange(n).first;
    return getXForTime(barStart);
}

double
00194 SimpleRulerScale::getBarWidth(int n) const
{
    std::pair<timeT, timeT> range = m_composition->getBarRange(n);
    return (double)(range.second - range.first) / m_ratio;
}

double
00201 SimpleRulerScale::getBeatWidth(int n) const
{
    bool isNew;
    TimeSignature timeSig(m_composition->getTimeSignatureInBar(n, isNew));
    return (double)(timeSig.getBeatDuration()) / m_ratio;
}

int
00209 SimpleRulerScale::getBarForX(double x) const
{
    return m_composition->getBarNumber(getTimeForX(x));
}

timeT
00215 SimpleRulerScale::getTimeForX(double x) const
{
    timeT t = (timeT)(nearbyint((double)(x - m_origin) * m_ratio));

    int firstBar = getFirstVisibleBar();
    if (firstBar != 0) {
      t += m_composition->getBarRange(firstBar).first;
    }

    return t;
}

double
00228 SimpleRulerScale::getXForTime(timeT time) const
{
    int firstBar = getFirstVisibleBar();
    if (firstBar != 0) {
      time -= m_composition->getBarRange(firstBar).first;
    }

    return m_origin + (double)time / m_ratio;
}


//////////////////////////////////////////////////////////////////////
//                 SegmentsRulerScale
//////////////////////////////////////////////////////////////////////

00243 SegmentsRulerScale::SegmentsRulerScale(Composition *composition,
                                       SegmentSelection segments,
                                       double origin, double ratio) :
    RulerScale(composition),
    m_origin(origin),
    m_ratio(ratio),
    m_segments(segments)
{
    for (SegmentSelection::iterator i = m_segments.begin();
         i != m_segments.end(); ++i) {
        (*i)->addObserver(this);
    }
}

SegmentsRulerScale::~SegmentsRulerScale()
{
    for (SegmentSelection::iterator i = m_segments.begin();
         i != m_segments.end(); ++i) {
        (*i)->removeObserver(this);
    }
}

void
00266 SegmentsRulerScale::segmentDeleted(const Segment *s)
{
    m_segments.erase((Segment *)s);
}

int
00272 SegmentsRulerScale::getFirstVisibleBar() const
{
    timeT earliest = 0;
    bool have = false;
    for (SegmentSelection::iterator i = m_segments.begin();
         i != m_segments.end(); ++i) {
        if (!have || (*i)->getStartTime() < earliest) {
            earliest = (*i)->getStartTime();
            have = true;
        }
    }
    return m_composition->getBarNumber(earliest);
}

int
00287 SegmentsRulerScale::getLastVisibleBar() const
{
    timeT latest = 0;
    bool have = false;
    for (SegmentSelection::iterator i = m_segments.begin();
         i != m_segments.end(); ++i) {
        if (!have || (*i)->getEndMarkerTime() > latest) {
            latest = (*i)->getEndMarkerTime();
            have = true;
        }
    }
    return m_composition->getBarNumber(latest - 1) + 1;
}

double
00302 SegmentsRulerScale::getBarPosition(int n) const
{
    timeT t = m_composition->getBarRange(n).first;

    int firstBar = getFirstVisibleBar();
    if (firstBar != 0) {
      t -= m_composition->getBarRange(firstBar).first;
    }

    return m_origin + (double)t / m_ratio;
}


//////////////////////////////////////////////////////////////////////
//                 ZoomableRulerScale
//////////////////////////////////////////////////////////////////////

00319 ZoomableRulerScale::ZoomableRulerScale(const RulerScale *reference) :
    RulerScale(reference->getComposition()),
    m_reference(reference),
    m_xfactor(1),
    m_yfactor(1)
{
}

ZoomableRulerScale::~ZoomableRulerScale()
{
}

double
00332 ZoomableRulerScale::getBarPosition(int n) const
{
    return m_reference->getBarPosition(n) * m_xfactor;
}

double
00338 ZoomableRulerScale::getBarWidth(int n) const
{
    return m_reference->getBarWidth(n) * m_xfactor;
}

double
00344 ZoomableRulerScale::getBeatWidth(int n) const
{
    return m_reference->getBeatWidth(n) * m_xfactor;
}

int
00350 ZoomableRulerScale::getBarForX(double x) const
{
    return m_reference->getBarForX(x / m_xfactor);
}

timeT
00356 ZoomableRulerScale::getTimeForX(double x) const
{
    return m_reference->getTimeForX(x / m_xfactor);
}

double
00362 ZoomableRulerScale::getXForTime(timeT time) const
{
    return m_reference->getXForTime(time) * m_xfactor;
}

int
00368 ZoomableRulerScale::getFirstVisibleBar() const
{
    return m_reference->getFirstVisibleBar();
}

int
00374 ZoomableRulerScale::getLastVisibleBar() const
{
    return m_reference->getLastVisibleBar();
}

}

Generated by  Doxygen 1.6.0   Back to index