* Now use two views when starting (one memory, one CPU usage). The third view

that is added to the window is a networking monitor, all later views default
  to CPU usage again.
* DataSources can now share a single adaptive scale, so that they become
  comparable in a single view.
* The networking in/out sources are now using this feature.
* DataHistory::ValueAt() now uses binary search to find the right data_item;
  this also fixes bug #2140, and makes it possible to change the refresh rate
  (which is not yet implemented, though).
* Zooming the timeline now also works by clicking the first mouse button and
  dragging the mouse around (instead of only via the scroll wheel, in case you
  hadn't noticed yet :-)).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26409 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-07-14 17:29:02 +00:00
parent d4a18674e3
commit 51591198d6
6 changed files with 198 additions and 27 deletions
+136 -18
View File
@@ -11,7 +11,7 @@
#include <stdlib.h> #include <stdlib.h>
#ifdef __HAIKU__ #ifdef __HAIKU__
#include <AbstractLayoutItem.h> # include <AbstractLayoutItem.h>
#endif #endif
#include <Application.h> #include <Application.h>
#include <Bitmap.h> #include <Bitmap.h>
@@ -23,11 +23,26 @@
#include "ActivityMonitor.h" #include "ActivityMonitor.h"
#include "ActivityWindow.h" #include "ActivityWindow.h"
#include "DataSource.h"
#include "SystemInfo.h" #include "SystemInfo.h"
#include "SystemInfoHandler.h" #include "SystemInfoHandler.h"
class Scale {
public:
Scale(scale_type type);
int64 MinimumValue() const { return fMinimumValue; }
int64 MaximumValue() const { return fMaximumValue; }
void Update(int64 value);
private:
scale_type fType;
int64 fMinimumValue;
int64 fMaximumValue;
bool fInitialized;
};
struct data_item { struct data_item {
bigtime_t time; bigtime_t time;
int64 value; int64 value;
@@ -85,13 +100,39 @@ const uint32 kMsgToggleLegend = 'tglg';
extern const char* kSignature; extern const char* kSignature;
Scale::Scale(scale_type type)
:
fType(type),
fMinimumValue(0),
fMaximumValue(0),
fInitialized(false)
{
}
void
Scale::Update(int64 value)
{
if (!fInitialized || fMinimumValue > value)
fMinimumValue = value;
if (!fInitialized || fMaximumValue > value)
fMaximumValue = value;
fInitialized = true;
}
// #pragma mark -
DataHistory::DataHistory(bigtime_t memorize, bigtime_t interval) DataHistory::DataHistory(bigtime_t memorize, bigtime_t interval)
: :
fBuffer(10000), fBuffer(10000),
fMinimumValue(0), fMinimumValue(0),
fMaximumValue(0), fMaximumValue(0),
fRefreshInterval(interval), fRefreshInterval(interval),
fLastIndex(-1) fLastIndex(-1),
fScale(NULL)
{ {
} }
@@ -108,6 +149,8 @@ DataHistory::AddValue(bigtime_t time, int64 value)
fMaximumValue = value; fMaximumValue = value;
if (fBuffer.IsEmpty() || fMinimumValue > value) if (fBuffer.IsEmpty() || fMinimumValue > value)
fMinimumValue = value; fMinimumValue = value;
if (fScale != NULL)
fScale->Update(value);
data_item item = {time, value}; data_item item = {time, value};
fBuffer.AddItem(item); fBuffer.AddItem(item);
@@ -117,11 +160,28 @@ DataHistory::AddValue(bigtime_t time, int64 value)
int64 int64
DataHistory::ValueAt(bigtime_t time) DataHistory::ValueAt(bigtime_t time)
{ {
// TODO: if the refresh rate changes, this computation won't work anymore! int32 left = 0;
int32 index = (time - Start()) / fRefreshInterval; int32 right = fBuffer.CountItems() - 1;
data_item* item = fBuffer.ItemAt(index); data_item* item = NULL;
if (item != NULL)
return item->value; while (left <= right) {
int32 index = (left + right) / 2;
item = fBuffer.ItemAt(index);
if (item->time > time) {
// search in left part
right = index - 1;
} else {
if (index + 1 >= fBuffer.CountItems()
|| fBuffer.ItemAt(index + 1)->time > time) {
// found item
return item->value;
}
// search in right part
left = index + 1;
}
}
return 0; return 0;
} }
@@ -130,6 +190,9 @@ DataHistory::ValueAt(bigtime_t time)
int64 int64
DataHistory::MaximumValue() const DataHistory::MaximumValue() const
{ {
if (fScale != NULL)
return fScale->MaximumValue();
return fMaximumValue; return fMaximumValue;
} }
@@ -137,6 +200,9 @@ DataHistory::MaximumValue() const
int64 int64
DataHistory::MinimumValue() const DataHistory::MinimumValue() const
{ {
if (fScale != NULL)
return fScale->MinimumValue();
return fMinimumValue; return fMinimumValue;
} }
@@ -168,6 +234,13 @@ DataHistory::SetRefreshInterval(bigtime_t interval)
} }
void
DataHistory::SetScale(Scale* scale)
{
fScale = scale;
}
// #pragma mark - // #pragma mark -
@@ -378,6 +451,7 @@ ActivityView::_Init(const BMessage* settings)
fDrawInterval = kInitialRefreshInterval * 2; fDrawInterval = kInitialRefreshInterval * 2;
fLastRefresh = 0; fLastRefresh = 0;
fDrawResolution = 1; fDrawResolution = 1;
fZooming = false;
fSystemInfoHandler = new SystemInfoHandler; fSystemInfoHandler = new SystemInfoHandler;
@@ -385,11 +459,8 @@ ActivityView::_Init(const BMessage* settings)
|| settings->FindBool("show legend", &fShowLegend) != B_OK) || settings->FindBool("show legend", &fShowLegend) != B_OK)
fShowLegend = true; fShowLegend = true;
if (settings == NULL) { if (settings == NULL)
AddDataSource(new UsedMemoryDataSource());
AddDataSource(new CachedMemoryDataSource());
return; return;
}
ssize_t colorLength; ssize_t colorLength;
rgb_color *color; rgb_color *color;
@@ -466,6 +537,24 @@ ActivityView::SaveState(BMessage& state) const
} }
Scale*
ActivityView::_ScaleFor(scale_type type)
{
if (type == kNoScale)
return NULL;
std::map<scale_type, ::Scale*>::iterator iterator = fScales.find(type);
if (iterator != fScales.end())
return iterator->second;
// add new scale
::Scale* scale = new ::Scale(type);
fScales[type] = scale;
return scale;
}
#ifdef __HAIKU__ #ifdef __HAIKU__
BLayoutItem* BLayoutItem*
ActivityView::CreateHistoryLayoutItem() ActivityView::CreateHistoryLayoutItem()
@@ -535,6 +624,8 @@ ActivityView::AddDataSource(const DataSource* source, const BMessage* state)
return B_NO_MEMORY; return B_NO_MEMORY;
} }
values->SetScale(_ScaleFor(source->ScaleType()));
DataSource* copy; DataSource* copy;
if (source->PerCPU()) if (source->PerCPU())
copy = source->CopyForCPU(i); copy = source->CopyForCPU(i);
@@ -688,14 +779,16 @@ ActivityView::_OffscreenView()
void void
ActivityView::MouseDown(BPoint where) ActivityView::MouseDown(BPoint where)
{ {
#if 0 int32 buttons = B_SECONDARY_MOUSE_BUTTON;
int32 buttons = B_PRIMARY_MOUSE_BUTTON; if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
int32 clicks = 1;
if (Looper() != NULL && Looper()->CurrentMessage() != NULL) {
Looper()->CurrentMessage()->FindInt32("buttons", &buttons); Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
Looper()->CurrentMessage()->FindInt32("clicks", &clicks);
if (buttons == B_PRIMARY_MOUSE_BUTTON) {
fZoomPoint = where;
fOriginalResolution = fDrawResolution;
fZooming = true;
return;
} }
#endif
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false); BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
menu->SetFont(be_plain_font); menu->SetFont(be_plain_font);
@@ -748,10 +841,35 @@ ActivityView::MouseDown(BPoint where)
} }
void
ActivityView::MouseUp(BPoint where)
{
fZooming = false;
}
void void
ActivityView::MouseMoved(BPoint where, uint32 transit, ActivityView::MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage) const BMessage* dragMessage)
{ {
if (!fZooming)
return;
int32 previousResolution = fDrawResolution;
int32 shift = int32(where.x - fZoomPoint.x) / 25;
if (shift > 0)
fDrawResolution = fOriginalResolution << shift;
else
fDrawResolution = fOriginalResolution >> -shift;
if (fDrawResolution < 1)
fDrawResolution = 1;
if (fDrawResolution > 128)
fDrawResolution = 128;
if (previousResolution != fDrawResolution)
Invalidate();
} }
+13
View File
@@ -6,14 +6,18 @@
#define ACTIVITY_VIEW_H #define ACTIVITY_VIEW_H
#include <map>
#include <View.h> #include <View.h>
#include <ObjectList.h> #include <ObjectList.h>
#include "CircularBuffer.h" #include "CircularBuffer.h"
#include "DataSource.h"
class BBitmap; class BBitmap;
class BMessageRunner; class BMessageRunner;
class DataSource; class DataSource;
class Scale;
class SystemInfoHandler; class SystemInfoHandler;
struct data_item; struct data_item;
@@ -32,6 +36,7 @@ public:
bigtime_t End() const; bigtime_t End() const;
void SetRefreshInterval(bigtime_t interval); void SetRefreshInterval(bigtime_t interval);
void SetScale(Scale* scale);
private: private:
CircularBuffer<data_item> fBuffer; CircularBuffer<data_item> fBuffer;
@@ -39,6 +44,7 @@ private:
int64 fMaximumValue; int64 fMaximumValue;
bigtime_t fRefreshInterval; bigtime_t fRefreshInterval;
int32 fLastIndex; int32 fLastIndex;
Scale* fScale;
}; };
@@ -77,6 +83,7 @@ protected:
virtual void FrameResized(float width, float height); virtual void FrameResized(float width, float height);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit, virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage); const BMessage* dragMessage);
@@ -86,6 +93,7 @@ protected:
private: private:
void _Init(const BMessage* settings); void _Init(const BMessage* settings);
::Scale* _ScaleFor(scale_type type);
void _Refresh(); void _Refresh();
void _UpdateOffscreenBitmap(); void _UpdateOffscreenBitmap();
BView* _OffscreenView(); BView* _OffscreenView();
@@ -99,6 +107,7 @@ private:
DataHistory* values, int64 value); DataHistory* values, int64 value);
void _DrawHistory(); void _DrawHistory();
private:
class HistoryLayoutItem; class HistoryLayoutItem;
class LegendLayoutItem; class LegendLayoutItem;
@@ -120,7 +129,11 @@ private:
bigtime_t fDrawInterval; bigtime_t fDrawInterval;
int32 fDrawResolution; int32 fDrawResolution;
bool fShowLegend; bool fShowLegend;
bool fZooming;
BPoint fZoomPoint;
int32 fOriginalResolution;
SystemInfoHandler* fSystemInfoHandler; SystemInfoHandler* fSystemInfoHandler;
std::map<scale_type, ::Scale*> fScales;
}; };
#endif // ACTIVITY_VIEW_H #endif // ACTIVITY_VIEW_H
+35 -9
View File
@@ -22,13 +22,14 @@
#include "ActivityMonitor.h" #include "ActivityMonitor.h"
#include "ActivityView.h" #include "ActivityView.h"
#include "DataSource.h"
static const uint32 kMsgAddView = 'advw'; static const uint32 kMsgAddView = 'advw';
ActivityWindow::ActivityWindow() ActivityWindow::ActivityWindow()
: BWindow(BRect(100, 100, 500, 250), "ActivityMonitor", B_TITLED_WINDOW, : BWindow(BRect(100, 100, 500, 350), "ActivityMonitor", B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE) B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE)
{ {
BMessage settings; BMessage settings;
@@ -68,12 +69,11 @@ ActivityWindow::ActivityWindow()
count++; count++;
} }
if (count == 0) { if (count == 0) {
ActivityView* view = new ActivityView("ActivityMonitor", NULL); // Add default views (memory & CPU usage)
fLayout->AddItem(view->CreateHistoryLayoutItem()); _AddDefaultView();
fLayout->AddItem(view->CreateLegendLayoutItem()); _AddDefaultView();
} }
#else // !__HAIKU__
#else
BView *layout = new BView(Bounds(), "topmost", B_FOLLOW_NONE, 0); BView *layout = new BView(Bounds(), "topmost", B_FOLLOW_NONE, 0);
AddChild(layout); AddChild(layout);
@@ -221,6 +221,34 @@ ActivityWindow::_MessageDropped(BMessage* message)
} }
void
ActivityWindow::_AddDefaultView()
{
ActivityView* view = new ActivityView("ActivityMonitor", NULL);
switch (ActivityViewCount()) {
case 0:
// The first view defaults to memory usage
view->AddDataSource(new UsedMemoryDataSource());
view->AddDataSource(new CachedMemoryDataSource());
break;
case 2:
// The third view defaults to network in/out
view->AddDataSource(new NetworkUsageDataSource(true));
view->AddDataSource(new NetworkUsageDataSource(false));
break;
case 1:
default:
// Everything beyond that defaults to a CPU usage view
view->AddDataSource(new CPUUsageDataSource());
break;
}
fLayout->AddItem(view->CreateHistoryLayoutItem());
fLayout->AddItem(view->CreateLegendLayoutItem());
}
void void
ActivityWindow::MessageReceived(BMessage* message) ActivityWindow::MessageReceived(BMessage* message)
{ {
@@ -240,9 +268,7 @@ ActivityWindow::MessageReceived(BMessage* message)
#ifdef __HAIKU__ #ifdef __HAIKU__
BView* firstView = fLayout->View()->ChildAt(0); BView* firstView = fLayout->View()->ChildAt(0);
ActivityView* view = new ActivityView("ActivityMonitor", NULL); _AddDefaultView();
fLayout->AddItem(view->CreateHistoryLayoutItem());
fLayout->AddItem(view->CreateLegendLayoutItem());
if (firstView != NULL) if (firstView != NULL)
ResizeBy(0, firstView->Bounds().Height() + fLayout->Spacing()); ResizeBy(0, firstView->Bounds().Height() + fLayout->Spacing());
@@ -29,6 +29,7 @@ private:
status_t _LoadSettings(BMessage& settings); status_t _LoadSettings(BMessage& settings);
status_t _SaveSettings(); status_t _SaveSettings();
void _AddDefaultView();
void _UpdateRemoveItem(); void _UpdateRemoveItem();
void _MessageDropped(BMessage *message); void _MessageDropped(BMessage *message);
+7
View File
@@ -176,6 +176,13 @@ DataSource::AdaptiveScale() const
} }
scale_type
DataSource::ScaleType() const
{
return kNoScale;
}
int32 int32
DataSource::CPU() const DataSource::CPU() const
{ {
+6
View File
@@ -12,6 +12,11 @@
class SystemInfo; class SystemInfo;
enum scale_type {
kNoScale,
kBytePerSecondScale,
};
class DataSource { class DataSource {
public: public:
DataSource(int64 initialMin, int64 initialMax); DataSource(int64 initialMin, int64 initialMax);
@@ -38,6 +43,7 @@ public:
virtual const char* Unit() const; virtual const char* Unit() const;
virtual rgb_color Color() const; virtual rgb_color Color() const;
virtual bool AdaptiveScale() const; virtual bool AdaptiveScale() const;
virtual scale_type ScaleType() const;
virtual int32 CPU() const; virtual int32 CPU() const;
virtual bool PerCPU() const; virtual bool PerCPU() const;
virtual bool MultiCPUOnly() const; virtual bool MultiCPUOnly() const;