diff --git a/src/apps/activitymonitor/ActivityView.cpp b/src/apps/activitymonitor/ActivityView.cpp index 4f3a21ebf1..b28d1c30ed 100644 --- a/src/apps/activitymonitor/ActivityView.cpp +++ b/src/apps/activitymonitor/ActivityView.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,47 @@ struct data_item { int64 value; }; +class ActivityView::HistoryLayoutItem : public BAbstractLayoutItem { +public: + HistoryLayoutItem(ActivityView* parent); + + virtual bool IsVisible(); + virtual void SetVisible(bool visible); + + virtual BRect Frame(); + virtual void SetFrame(BRect frame); + + virtual BView* View(); + + virtual BSize BasePreferredSize(); + +private: + ActivityView* fParent; + BRect fFrame; +}; + +class ActivityView::LegendLayoutItem : public BAbstractLayoutItem { +public: + LegendLayoutItem(ActivityView* parent); + + virtual bool IsVisible(); + virtual void SetVisible(bool visible); + + virtual BRect Frame(); + virtual void SetFrame(BRect frame); + + virtual BView* View(); + + virtual BSize BaseMinSize(); + virtual BSize BaseMaxSize(); + virtual BSize BasePreferredSize(); + virtual BAlignment BaseAlignment(); + +private: + ActivityView* fParent; + BRect fFrame; +}; + const bigtime_t kInitialRefreshInterval = 500000LL; const uint32 kMsgRefresh = 'refr'; @@ -124,6 +166,144 @@ DataHistory::SetRefreshInterval(bigtime_t interval) // #pragma mark - +ActivityView::HistoryLayoutItem::HistoryLayoutItem(ActivityView* parent) + : + fParent(parent), + fFrame() +{ +} + + +bool +ActivityView::HistoryLayoutItem::IsVisible() +{ + return !fParent->IsHidden(fParent); +} + + +void +ActivityView::HistoryLayoutItem::SetVisible(bool visible) +{ + // not allowed +} + + +BRect +ActivityView::HistoryLayoutItem::Frame() +{ + return fFrame; +} + + +void +ActivityView::HistoryLayoutItem::SetFrame(BRect frame) +{ + fFrame = frame; + fParent->_UpdateFrame(); +} + + +BView* +ActivityView::HistoryLayoutItem::View() +{ + return fParent; +} + + +BSize +ActivityView::HistoryLayoutItem::BasePreferredSize() +{ + BSize size(BaseMaxSize()); + return size; +} + + +// #pragma mark - + + +ActivityView::LegendLayoutItem::LegendLayoutItem(ActivityView* parent) + : + fParent(parent), + fFrame() +{ +} + + +bool +ActivityView::LegendLayoutItem::IsVisible() +{ + return !fParent->IsHidden(fParent); +} + + +void +ActivityView::LegendLayoutItem::SetVisible(bool visible) +{ + // not allowed +} + + +BRect +ActivityView::LegendLayoutItem::Frame() +{ + return fFrame; +} + + +void +ActivityView::LegendLayoutItem::SetFrame(BRect frame) +{ + fFrame = frame; + fParent->_UpdateFrame(); +} + + +BView* +ActivityView::LegendLayoutItem::View() +{ + return fParent; +} + + +BSize +ActivityView::LegendLayoutItem::BaseMinSize() +{ + // TODO: Cache the info. Might be too expensive for this call. + BSize size; + size.width = 80; + size.height = fParent->_LegendHeight(); + + return size; +} + + +BSize +ActivityView::LegendLayoutItem::BaseMaxSize() +{ + BSize size(BaseMinSize()); + size.width = B_SIZE_UNLIMITED; + return size; +} + + +BSize +ActivityView::LegendLayoutItem::BasePreferredSize() +{ + BSize size(BaseMinSize()); + return size; +} + + +BAlignment +ActivityView::LegendLayoutItem::BaseAlignment() +{ + return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); +} + + +// #pragma mark - + + ActivityView::ActivityView(BRect frame, const char* name, const BMessage* settings, uint32 resizingMode) : BView(frame, name, resizingMode, @@ -177,6 +357,8 @@ ActivityView::_Init(const BMessage* settings) { fBackgroundColor = (rgb_color){255, 255, 240}; fOffscreen = NULL; + fHistoryLayoutItem = NULL; + fLegendLayoutItem = NULL; SetViewColor(B_TRANSPARENT_COLOR); SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -256,6 +438,26 @@ ActivityView::SaveState(BMessage& state) const } +BLayoutItem* +ActivityView::CreateHistoryLayoutItem() +{ + if (fHistoryLayoutItem == NULL) + fHistoryLayoutItem = new HistoryLayoutItem(this); + + return fHistoryLayoutItem; +} + + +BLayoutItem* +ActivityView::CreateLegendLayoutItem() +{ + if (fLegendLayoutItem == NULL) + fLegendLayoutItem = new LegendLayoutItem(this); + + return fLegendLayoutItem; +} + + DataSource* ActivityView::FindDataSource(const DataSource* search) { @@ -316,6 +518,7 @@ ActivityView::AddDataSource(const DataSource* source) } } + InvalidateLayout(); return B_OK; } @@ -323,10 +526,15 @@ ActivityView::AddDataSource(const DataSource* source) status_t ActivityView::RemoveDataSource(const DataSource* remove) { + bool removed = false; + while (true) { DataSource* source = FindDataSource(remove); - if (source == NULL) - return B_OK; + if (source == NULL) { + if (removed) + break; + return B_ENTRY_NOT_FOUND; + } int32 index = fSources.IndexOf(source); if (index < 0) @@ -336,8 +544,10 @@ ActivityView::RemoveDataSource(const DataSource* remove) delete source; DataHistory* values = fValues.RemoveItemAt(index); delete values; + removed = true; } + InvalidateLayout(); return B_OK; } @@ -537,6 +747,20 @@ ActivityView::MessageReceived(BMessage* message) } +void +ActivityView::_UpdateFrame() +{ + if (fLegendLayoutItem == NULL || fHistoryLayoutItem == NULL) + return; + + BRect historyFrame = fHistoryLayoutItem->Frame(); + BRect legendFrame = fLegendLayoutItem->Frame(); + MoveTo(historyFrame.left, historyFrame.top); + ResizeTo(legendFrame.left + legendFrame.Width() - historyFrame.left, + legendFrame.top + legendFrame.Height() - historyFrame.top); +} + + BRect ActivityView::_HistoryFrame() const { @@ -552,16 +776,29 @@ ActivityView::_HistoryFrame() const } -BRect -ActivityView::_LegendFrame() const +float +ActivityView::_LegendHeight() const { - BRect frame = Bounds(); font_height fontHeight; GetFontHeight(&fontHeight); int32 rows = (fSources.CountItems() + 1) / 2; - frame.top = frame.bottom - rows * (4 + ceilf(fontHeight.ascent) + return rows * (4 + ceilf(fontHeight.ascent) + ceilf(fontHeight.descent) + ceilf(fontHeight.leading)); +} + + +BRect +ActivityView::_LegendFrame() const +{ + float height; + if (fLegendLayoutItem != NULL) + height = fLegendLayoutItem->Frame().Height(); + else + height = _LegendHeight(); + + BRect frame = Bounds(); + frame.top = frame.bottom - height; return frame; } diff --git a/src/apps/activitymonitor/ActivityView.h b/src/apps/activitymonitor/ActivityView.h index 5ee2aa76cb..7f5b060199 100644 --- a/src/apps/activitymonitor/ActivityView.h +++ b/src/apps/activitymonitor/ActivityView.h @@ -56,6 +56,9 @@ public: status_t SaveState(BMessage& state) const; + BLayoutItem* CreateHistoryLayoutItem(); + BLayoutItem* CreateLegendLayoutItem(); + DataSource* FindDataSource(const DataSource* source); status_t AddDataSource(const DataSource* source); status_t RemoveDataSource(const DataSource* source); @@ -82,15 +85,25 @@ private: void _Init(const BMessage* settings); void _Refresh(); void _UpdateOffscreenBitmap(); + void _UpdateFrame(); BRect _HistoryFrame() const; + float _LegendHeight() const; BRect _LegendFrame() const; BRect _LegendFrameAt(BRect frame, int32 index) const; float _PositionForValue(DataSource* source, DataHistory* values, int64 value); void _DrawHistory(); + class HistoryLayoutItem; + class LegendLayoutItem; + + friend class HistoryLayoutItem; + friend class LegendLayoutItem; + rgb_color fBackgroundColor; BBitmap* fOffscreen; + BLayoutItem* fHistoryLayoutItem; + BLayoutItem* fLegendLayoutItem; BObjectList fSources; BObjectList fValues; BMessageRunner* fRunner; diff --git a/src/apps/activitymonitor/ActivityWindow.cpp b/src/apps/activitymonitor/ActivityWindow.cpp index 792833863e..5d03388233 100644 --- a/src/apps/activitymonitor/ActivityWindow.cpp +++ b/src/apps/activitymonitor/ActivityWindow.cpp @@ -63,11 +63,16 @@ ActivityWindow::ActivityWindow() int32 count = 0; for (int32 i = 0; settings.FindMessage("activity view", i, &viewState) == B_OK; i++) { - fLayout->AddView(new ActivityView("ActivityMonitor", &viewState)); + ActivityView* view = new ActivityView("ActivityMonitor", &viewState); + fLayout->AddItem(view->CreateHistoryLayoutItem()); + fLayout->AddItem(view->CreateLegendLayoutItem()); count++; } - if (count == 0) - fLayout->AddView(new ActivityView("ActivityMonitor", NULL)); + if (count == 0) { + ActivityView* view = new ActivityView("ActivityMonitor", NULL); + fLayout->AddItem(view->CreateHistoryLayoutItem()); + fLayout->AddItem(view->CreateLegendLayoutItem()); + } #else BView *layout = new BView(Bounds(), "topmost", B_FOLLOW_NONE, 0); @@ -239,10 +244,14 @@ ActivityWindow::MessageReceived(BMessage* message) case kMsgAddView: { #ifdef __HAIKU__ - BView* view = fLayout->View()->ChildAt(0); - fLayout->AddView(new ActivityView("ActivityMonitor", NULL)); - if (view != NULL) - ResizeBy(0, view->Bounds().Height() + fLayout->Spacing()); + BView* firstView = fLayout->View()->ChildAt(0); + + ActivityView* view = new ActivityView("ActivityMonitor", NULL); + fLayout->AddItem(view->CreateHistoryLayoutItem()); + fLayout->AddItem(view->CreateLegendLayoutItem()); + + if (firstView != NULL) + ResizeBy(0, firstView->Bounds().Height() + fLayout->Spacing()); #endif _UpdateRemoveItem(); break;