Logo Search packages:      
Sourcecode: rosegarden version File versions

RulerScale.cpp

/*
    Rosegarden
    A sequencer and musical notation editor.
    Copyright 2000-2008 the Rosegarden development team.
    See the AUTHORS file for more 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
00038 RulerScale::getFirstVisibleBar() const
{
    return m_composition->getBarNumber(m_composition->getStartMarker());
}

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

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

double
00056 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
00073 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
00094 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
00115 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
00135 RulerScale::getDurationForWidth(double x, double width) const
{
    return getTimeForX(x + width) - getTimeForX(x);
}

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

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




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


00161 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
00185 SimpleRulerScale::getBarPosition(int n) const
{
    timeT barStart = m_composition->getBarRange(n).first;
    return getXForTime(barStart);
}

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

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

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

timeT
00213 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
00226 SimpleRulerScale::getXForTime(timeT time) const
{
    int firstBar = getFirstVisibleBar();
    if (firstBar != 0) {
      time -= m_composition->getBarRange(firstBar).first;
    }

    return m_origin + (double)time / m_ratio;
}


}

Generated by  Doxygen 1.6.0   Back to index