* Implemented zooming the domain of the chart (via Shift + Wheel).
* The scrolling related computations used a slightly off chart width/height. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30658 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9057fee626
commit
6619cc4d56
@ -63,7 +63,9 @@ Chart::Chart(ChartRenderer* renderer, const char* name)
|
|||||||
fHScrollSize(0),
|
fHScrollSize(0),
|
||||||
fVScrollSize(0),
|
fVScrollSize(0),
|
||||||
fHScrollValue(0),
|
fHScrollValue(0),
|
||||||
fVScrollValue(0)
|
fVScrollValue(0),
|
||||||
|
fDomainZoomLimit(0),
|
||||||
|
fLastMousePos(-1, -1)
|
||||||
{
|
{
|
||||||
SetViewColor(B_TRANSPARENT_32_BIT);
|
SetViewColor(B_TRANSPARENT_32_BIT);
|
||||||
|
|
||||||
@ -239,6 +241,20 @@ Chart::SetDisplayRange(ChartDataRange range)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double
|
||||||
|
Chart::DomainZoomLimit() const
|
||||||
|
{
|
||||||
|
return fDomainZoomLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Chart::SetDomainZoomLimit(double limit)
|
||||||
|
{
|
||||||
|
fDomainZoomLimit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Chart::DomainChanged()
|
Chart::DomainChanged()
|
||||||
{
|
{
|
||||||
@ -259,6 +275,31 @@ Chart::RangeChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Chart::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case B_MOUSE_WHEEL_CHANGED:
|
||||||
|
{
|
||||||
|
// We're only interested in Shift + vertical wheel, if the mouse
|
||||||
|
// is in the chart frame.
|
||||||
|
float deltaY;
|
||||||
|
if ((modifiers() & B_SHIFT_KEY) == 0
|
||||||
|
|| message->FindFloat("be:wheel_delta_y", &deltaY) != B_OK
|
||||||
|
|| !fChartFrame.InsetByCopy(1, 1).Contains(fLastMousePos)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Zoom(fLastMousePos.x, deltaY);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Chart::FrameResized(float newWidth, float newHeight)
|
Chart::FrameResized(float newWidth, float newHeight)
|
||||||
{
|
{
|
||||||
@ -272,6 +313,13 @@ Chart::FrameResized(float newWidth, float newHeight)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Chart::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
|
||||||
|
{
|
||||||
|
fLastMousePos = where;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Chart::Draw(BRect updateRect)
|
Chart::Draw(BRect updateRect)
|
||||||
{
|
{
|
||||||
@ -419,7 +467,7 @@ Chart::_UpdateScrollBar(bool horizontal)
|
|||||||
const ChartDataRange& displayRange = horizontal
|
const ChartDataRange& displayRange = horizontal
|
||||||
? fDisplayDomain : fDisplayRange;
|
? fDisplayDomain : fDisplayRange;
|
||||||
float chartSize = horizontal ? fChartFrame.Width() : fChartFrame.Height();
|
float chartSize = horizontal ? fChartFrame.Width() : fChartFrame.Height();
|
||||||
chartSize += 3; // +1 for pixel size, +2 for border
|
chartSize--; // +1 for pixel size, -2 for border
|
||||||
float& scrollSize = horizontal ? fHScrollSize : fVScrollSize;
|
float& scrollSize = horizontal ? fHScrollSize : fVScrollSize;
|
||||||
float& scrollValue = horizontal ? fHScrollValue : fVScrollValue;
|
float& scrollValue = horizontal ? fHScrollValue : fVScrollValue;
|
||||||
BScrollBar* scrollBar = ScrollBar(horizontal ? B_HORIZONTAL : B_VERTICAL);
|
BScrollBar* scrollBar = ScrollBar(horizontal ? B_HORIZONTAL : B_VERTICAL);
|
||||||
@ -456,7 +504,7 @@ Chart::_ScrollTo(float value, bool horizontal)
|
|||||||
const ChartDataRange& range = horizontal ? fDomain : fRange;
|
const ChartDataRange& range = horizontal ? fDomain : fRange;
|
||||||
ChartDataRange displayRange = horizontal ? fDisplayDomain : fDisplayRange;
|
ChartDataRange displayRange = horizontal ? fDisplayDomain : fDisplayRange;
|
||||||
float chartSize = horizontal ? fChartFrame.Width() : fChartFrame.Height();
|
float chartSize = horizontal ? fChartFrame.Width() : fChartFrame.Height();
|
||||||
chartSize += 3; // +1 for pixel size, +2 for border
|
chartSize--; // +1 for pixel size, -2 for border
|
||||||
const float& scrollSize = horizontal ? fHScrollSize : fVScrollSize;
|
const float& scrollSize = horizontal ? fHScrollSize : fVScrollSize;
|
||||||
|
|
||||||
scrollValue = value;
|
scrollValue = value;
|
||||||
@ -467,3 +515,46 @@ Chart::_ScrollTo(float value, bool horizontal)
|
|||||||
else
|
else
|
||||||
SetDisplayRange(displayRange);
|
SetDisplayRange(displayRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Chart::_Zoom(float x, float steps)
|
||||||
|
{
|
||||||
|
double displayDomainSize = fDisplayDomain.Size();
|
||||||
|
if (fDomainZoomLimit <= 0 || !fDomain.IsValid() || !fDisplayDomain.IsValid()
|
||||||
|
|| steps == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the domain point where to zoom in
|
||||||
|
float chartSize = fChartFrame.Width() - 1;
|
||||||
|
x -= fChartFrame.left + 1;
|
||||||
|
double domainPos = (fHScrollValue + x) / (fHScrollSize + chartSize)
|
||||||
|
* fDomain.Size();
|
||||||
|
|
||||||
|
double factor = 2;
|
||||||
|
if (steps < 0) {
|
||||||
|
steps = -steps;
|
||||||
|
factor = 1.0 / factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; steps > 0; steps--)
|
||||||
|
displayDomainSize *= factor;
|
||||||
|
|
||||||
|
if (displayDomainSize < fDomainZoomLimit)
|
||||||
|
displayDomainSize = fDomainZoomLimit;
|
||||||
|
if (displayDomainSize > fDomain.Size())
|
||||||
|
displayDomainSize = fDomain.Size();
|
||||||
|
|
||||||
|
if (displayDomainSize == fDisplayDomain.Size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
domainPos -= displayDomainSize * x / chartSize;
|
||||||
|
ChartDataRange displayDomain(domainPos, domainPos + displayDomainSize);
|
||||||
|
if (displayDomain.min < fDomain.min)
|
||||||
|
displayDomain.OffsetTo(fDomain.min);
|
||||||
|
if (displayDomain.max > fDomain.max)
|
||||||
|
displayDomain.OffsetTo(fDomain.max - displayDomainSize);
|
||||||
|
|
||||||
|
SetDisplayDomain(displayDomain);
|
||||||
|
}
|
||||||
|
@ -49,9 +49,16 @@ public:
|
|||||||
void SetDisplayDomain(ChartDataRange domain);
|
void SetDisplayDomain(ChartDataRange domain);
|
||||||
void SetDisplayRange(ChartDataRange range);
|
void SetDisplayRange(ChartDataRange range);
|
||||||
|
|
||||||
|
double DomainZoomLimit() const;
|
||||||
|
void SetDomainZoomLimit(double limit);
|
||||||
|
|
||||||
virtual void DomainChanged();
|
virtual void DomainChanged();
|
||||||
virtual void RangeChanged();
|
virtual void RangeChanged();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
virtual void MouseMoved(BPoint where, uint32 code,
|
||||||
|
const BMessage* dragMessage);
|
||||||
virtual void FrameResized(float newWidth, float newHeight);
|
virtual void FrameResized(float newWidth, float newHeight);
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
virtual void ScrollTo(BPoint where);
|
virtual void ScrollTo(BPoint where);
|
||||||
@ -80,6 +87,7 @@ private:
|
|||||||
void _UpdateDomainAndRange();
|
void _UpdateDomainAndRange();
|
||||||
void _UpdateScrollBar(bool horizontal);
|
void _UpdateScrollBar(bool horizontal);
|
||||||
void _ScrollTo(float value, bool horizontal);
|
void _ScrollTo(float value, bool horizontal);
|
||||||
|
void _Zoom(float x, float steps);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChartRenderer* fRenderer;
|
ChartRenderer* fRenderer;
|
||||||
@ -97,6 +105,8 @@ private:
|
|||||||
float fVScrollSize;
|
float fVScrollSize;
|
||||||
float fHScrollValue;
|
float fHScrollValue;
|
||||||
float fVScrollValue;
|
float fVScrollValue;
|
||||||
|
double fDomainZoomLimit;
|
||||||
|
BPoint fLastMousePos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user