* 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),
|
||||
fVScrollSize(0),
|
||||
fHScrollValue(0),
|
||||
fVScrollValue(0)
|
||||
fVScrollValue(0),
|
||||
fDomainZoomLimit(0),
|
||||
fLastMousePos(-1, -1)
|
||||
{
|
||||
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
|
||||
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
|
||||
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
|
||||
Chart::Draw(BRect updateRect)
|
||||
{
|
||||
@ -419,7 +467,7 @@ Chart::_UpdateScrollBar(bool horizontal)
|
||||
const ChartDataRange& displayRange = horizontal
|
||||
? fDisplayDomain : fDisplayRange;
|
||||
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& scrollValue = horizontal ? fHScrollValue : fVScrollValue;
|
||||
BScrollBar* scrollBar = ScrollBar(horizontal ? B_HORIZONTAL : B_VERTICAL);
|
||||
@ -456,7 +504,7 @@ Chart::_ScrollTo(float value, bool horizontal)
|
||||
const ChartDataRange& range = horizontal ? fDomain : fRange;
|
||||
ChartDataRange displayRange = horizontal ? fDisplayDomain : fDisplayRange;
|
||||
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;
|
||||
|
||||
scrollValue = value;
|
||||
@ -467,3 +515,46 @@ Chart::_ScrollTo(float value, bool horizontal)
|
||||
else
|
||||
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 SetDisplayRange(ChartDataRange range);
|
||||
|
||||
double DomainZoomLimit() const;
|
||||
void SetDomainZoomLimit(double limit);
|
||||
|
||||
virtual void DomainChanged();
|
||||
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 Draw(BRect updateRect);
|
||||
virtual void ScrollTo(BPoint where);
|
||||
@ -80,6 +87,7 @@ private:
|
||||
void _UpdateDomainAndRange();
|
||||
void _UpdateScrollBar(bool horizontal);
|
||||
void _ScrollTo(float value, bool horizontal);
|
||||
void _Zoom(float x, float steps);
|
||||
|
||||
private:
|
||||
ChartRenderer* fRenderer;
|
||||
@ -97,6 +105,8 @@ private:
|
||||
float fVScrollSize;
|
||||
float fHScrollValue;
|
||||
float fVScrollValue;
|
||||
double fDomainZoomLimit;
|
||||
BPoint fLastMousePos;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user