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-2011 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();
    // This line adds extra padding to the the actual width -- JAS
    // return getBarPosition(n) + getBarWidth(n);

    // Return only the actual size instead.
    return getBarPosition(n);
}



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


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

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

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

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

timeT
00219 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
00232 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
//////////////////////////////////////////////////////////////////////

00247 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
00270 SegmentsRulerScale::segmentDeleted(const Segment *s)
{
    m_segments.erase((Segment *)s);
}

int
00276 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
00291 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
00306 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
//////////////////////////////////////////////////////////////////////

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

ZoomableRulerScale::~ZoomableRulerScale()
{
}

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

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

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

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

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

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

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

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

}

Generated by  Doxygen 1.6.0   Back to index