From a5c1cac5a8c98c681891820bee73fbba208e05f1 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 6 May 2009 15:31:44 +0000 Subject: [PATCH] * Made the displayed domain and range settable. * Added support for scrolling. * Automatic white space cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30648 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/debuganalyzer/gui/chart/Chart.cpp | 179 ++++++++++++++++++--- src/apps/debuganalyzer/gui/chart/Chart.h | 54 +++++-- 2 files changed, 198 insertions(+), 35 deletions(-) diff --git a/src/apps/debuganalyzer/gui/chart/Chart.cpp b/src/apps/debuganalyzer/gui/chart/Chart.cpp index fc38150797..d799d94415 100644 --- a/src/apps/debuganalyzer/gui/chart/Chart.cpp +++ b/src/apps/debuganalyzer/gui/chart/Chart.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "chart/ChartAxis.h" #include "chart/ChartDataSource.h" @@ -58,7 +59,11 @@ Chart::AxisInfo::Render(BView* view, const BRect& updateRect) Chart::Chart(ChartRenderer* renderer, const char* name) : BView(name, B_FRAME_EVENTS | B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), - fRenderer(renderer) + fRenderer(renderer), + fHScrollSize(0), + fVScrollSize(0), + fHScrollValue(0), + fVScrollValue(0) { SetViewColor(B_TRANSPARENT_32_BIT); @@ -129,7 +134,7 @@ printf("Chart::RemoveDataSource(%ld)\n", index); fRenderer->RemoveDataSource(dataSource); _UpdateDomainAndRange(); - + return dataSource; } @@ -178,29 +183,80 @@ Chart::SetAxis(ChartAxisLocation location, ChartAxis* axis) } -#if 0 -ChartDataRange -Chart::Domain() const -{ - return fDataSource != NULL ? fDataSource->Domain() : ChartDataRange(); -} - - void -Chart::SetDisplayDomain(const ChartDataRange& domain) +Chart::SetDisplayDomain(ChartDataRange domain) { - fRenderer->SetDomain(domain); + // sanitize the supplied range + if (domain.IsValid() && domain.Size() < fDomain.Size()) { + if (domain.min < fDomain.min) + domain.OffsetBy(fDomain.min - domain.min); + else if (domain.max > fDomain.max) + domain.OffsetBy(fDomain.max - domain.max); + } else + domain = fDomain; + + if (domain == fDisplayDomain) + return; + + fDisplayDomain = domain; + + fRenderer->SetDomain(fDisplayDomain); + fTopAxis.SetRange(fDisplayDomain); + fBottomAxis.SetRange(fDisplayDomain); + + _UpdateScrollBar(true); + + InvalidateLayout(); Invalidate(); } void -Chart::SetDisplayDomain(const ChartDataRange& range) +Chart::SetDisplayRange(ChartDataRange range) { - fRenderer->SetRange(range); + // sanitize the supplied range + if (range.IsValid() && range.Size() < fRange.Size()) { + if (range.min < fRange.min) + range.OffsetBy(fRange.min - range.min); + else if (range.max > fRange.max) + range.OffsetBy(fRange.max - range.max); + } else + range = fRange; + + if (range == fDisplayRange) + return; + + fDisplayRange = range; + + fRenderer->SetRange(fDisplayRange); + fLeftAxis.SetRange(fDisplayRange); + fRightAxis.SetRange(fDisplayRange); + + _UpdateScrollBar(false); + + InvalidateLayout(); Invalidate(); } -#endif + + +void +Chart::DomainChanged() +{ + if (ScrollBar(B_HORIZONTAL) != NULL && fDisplayDomain.IsValid()) + SetDisplayDomain(fDisplayDomain); + else + SetDisplayDomain(fDomain); +} + + +void +Chart::RangeChanged() +{ + if (ScrollBar(B_VERTICAL) != NULL && fDisplayRange.IsValid()) + SetDisplayRange(fDisplayRange); + else + SetDisplayRange(fRange); +} void @@ -209,6 +265,9 @@ Chart::FrameResized(float newWidth, float newHeight) //printf("Chart::FrameResized(%f, %f)\n", newWidth, newHeight); // fRenderer->SetFrame(Bounds()); + _UpdateScrollBar(true); + _UpdateScrollBar(false); + Invalidate(); } @@ -252,24 +311,36 @@ printf("Chart::Draw((%f, %f) - (%f, %f))\n", updateRect.left, updateRect.top, up } -#if 0 +void +Chart::ScrollTo(BPoint where) +{ + _ScrollTo(where.x, true); + _ScrollTo(where.y, false); +} + + BSize Chart::MinSize() { + // TODO: Implement for real! + return BSize(100, 100); } BSize Chart::MaxSize() { + // TODO: Implement for real! + return BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED); } BSize Chart::PreferredSize() { + // TODO: Implement for real! + return MinSize(); } -#endif void @@ -316,15 +387,17 @@ printf(" fChartFrame: (%f, %f) - (%f, %f)\n", fChartFrame.left, fChartFrame.top void Chart::_UpdateDomainAndRange() { + ChartDataRange oldDomain = fDomain; + ChartDataRange oldRange = fRange; + if (fDataSources.IsEmpty()) { fDomain = ChartDataRange(); fRange = ChartDataRange(); - return; } else { ChartDataSource* firstSource = fDataSources.ItemAt(0); fDomain = firstSource->Domain(); fRange = firstSource->Range(); - + for (int32 i = 1; ChartDataSource* source = fDataSources.ItemAt(i); i++) { fDomain.Extend(source->Domain()); @@ -332,11 +405,65 @@ Chart::_UpdateDomainAndRange() } } - fRenderer->SetDomain(fDomain); - fRenderer->SetRange(fRange); - - fLeftAxis.SetRange(fRange); - fTopAxis.SetRange(fDomain); - fRightAxis.SetRange(fRange); - fBottomAxis.SetRange(fDomain); + if (fDomain != oldDomain) + DomainChanged(); + if (fRange != oldRange) + RangeChanged(); +} + + +void +Chart::_UpdateScrollBar(bool horizontal) +{ + const ChartDataRange& range = horizontal ? fDomain : fRange; + const ChartDataRange& displayRange = horizontal + ? fDisplayDomain : fDisplayRange; + float chartSize = horizontal ? fChartFrame.Width() : fChartFrame.Height(); + chartSize += 3; // +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); + + float proportion; + + if (range.IsValid() && displayRange.IsValid()) { + scrollSize = (range.Size() / displayRange.Size() - 1) * chartSize; + scrollValue = (displayRange.min - range.min) / displayRange.Size() + * chartSize; + proportion = displayRange.Size() / range.Size(); + } else { + scrollSize = 0; + scrollValue = 0; + proportion = 1; + } + + if (scrollBar != NULL) { + scrollBar->SetRange(0, scrollSize); +// TODO: If the scroll range changes, we might need to reset the scroll value. + scrollBar->SetValue(scrollValue); + scrollBar->SetProportion(proportion); + } +} + + +void +Chart::_ScrollTo(float value, bool horizontal) +{ + float& scrollValue = horizontal ? fHScrollValue : fVScrollValue; + if (value == scrollValue) + return; + + 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 + const float& scrollSize = horizontal ? fHScrollSize : fVScrollSize; + + scrollValue = value; + displayRange.OffsetTo(value / scrollSize + * (range.Size() - displayRange.Size())); + if (horizontal) + SetDisplayDomain(displayRange); + else + SetDisplayRange(displayRange); } diff --git a/src/apps/debuganalyzer/gui/chart/Chart.h b/src/apps/debuganalyzer/gui/chart/Chart.h index fcef82db26..ee8eb1c57d 100644 --- a/src/apps/debuganalyzer/gui/chart/Chart.h +++ b/src/apps/debuganalyzer/gui/chart/Chart.h @@ -40,21 +40,25 @@ public: void SetAxis(ChartAxisLocation location, ChartAxis* axis); -#if 0 - ChartDataRange Domain() const; + inline ChartDataRange Domain() const; + inline ChartDataRange Range() const; - void SetDisplayDomain(const ChartDataRange& domain); - void SetDisplayRange(const ChartDataRange& range); -#endif + inline ChartDataRange DisplayDomain() const; + inline ChartDataRange DisplayRange() const; + + void SetDisplayDomain(ChartDataRange domain); + void SetDisplayRange(ChartDataRange range); + + virtual void DomainChanged(); + virtual void RangeChanged(); virtual void FrameResized(float newWidth, float newHeight); virtual void Draw(BRect updateRect); + virtual void ScrollTo(BPoint where); -#if 0 virtual BSize MinSize(); virtual BSize MaxSize(); virtual BSize PreferredSize(); -#endif virtual void DoLayout(); @@ -74,6 +78,8 @@ private: private: void _UpdateDomainAndRange(); + void _UpdateScrollBar(bool horizontal); + void _ScrollTo(float value, bool horizontal); private: ChartRenderer* fRenderer; @@ -84,12 +90,42 @@ private: AxisInfo fBottomAxis; ChartDataRange fDomain; ChartDataRange fRange; -#if 0 ChartDataRange fDisplayDomain; ChartDataRange fDisplayRange; -#endif BRect fChartFrame; + float fHScrollSize; + float fVScrollSize; + float fHScrollValue; + float fVScrollValue; }; +ChartDataRange +Chart::Domain() const +{ + return fDomain; +} + + +ChartDataRange +Chart::Range() const +{ + return fRange; +} + + +ChartDataRange +Chart::DisplayDomain() const +{ + return fDisplayDomain; +} + + +ChartDataRange +Chart::DisplayRange() const +{ + return fDisplayRange; +} + + #endif // CHART_H