From dde4ac438661765184581a6aeb2cd098d6b1a06f Mon Sep 17 00:00:00 2001 From: Philippe Saint-Pierre Date: Tue, 12 Oct 2010 23:50:09 +0000 Subject: [PATCH] DiskUsage enhancement (ticket #3520) * the volume are now displayed in tabs, mounting and unmounting volume adds and remove tabs accordingly * the infos (file size, etc..) are now displayed below the graph * node monitoring tells you when your current view is outdated. (the ticket suggested to adjust the view automatically, but I'll wait for comments on this first). * Drag&Dropping a file on the graph changes the tabview to the tab representing the volume owning that file. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38958 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/diskusage/App.cpp | 1 + src/apps/diskusage/Common.cpp | 2 + src/apps/diskusage/Common.h | 3 + src/apps/diskusage/ControlsView.cpp | 312 ++++++++++++++++------------ src/apps/diskusage/ControlsView.h | 21 +- src/apps/diskusage/DiskUsage.rdef | 3 +- src/apps/diskusage/Jamfile | 3 +- src/apps/diskusage/MainWindow.cpp | 70 ++----- src/apps/diskusage/MainWindow.h | 8 +- src/apps/diskusage/PieView.cpp | 209 ++++++++----------- src/apps/diskusage/PieView.h | 14 +- src/apps/diskusage/Scanner.cpp | 100 ++++++++- src/apps/diskusage/Scanner.h | 8 + src/apps/diskusage/StatusView.cpp | 110 +++++----- src/apps/diskusage/StatusView.h | 10 +- src/apps/diskusage/VolumeView.cpp | 85 ++++++++ src/apps/diskusage/VolumeView.h | 44 ++++ 17 files changed, 614 insertions(+), 389 deletions(-) create mode 100644 src/apps/diskusage/VolumeView.cpp create mode 100644 src/apps/diskusage/VolumeView.h diff --git a/src/apps/diskusage/App.cpp b/src/apps/diskusage/App.cpp index af405d09a5..9a165d3097 100644 --- a/src/apps/diskusage/App.cpp +++ b/src/apps/diskusage/App.cpp @@ -90,6 +90,7 @@ App::ReadyToRun() } fMainWindow = new MainWindow(frame); + fMainWindow->Show(); if (fSavedRefsReceived) { // RefsReceived() was called earlier than ReadyToRun() diff --git a/src/apps/diskusage/Common.cpp b/src/apps/diskusage/Common.cpp index ccdc14efbc..68b4f17d5a 100644 --- a/src/apps/diskusage/Common.cpp +++ b/src/apps/diskusage/Common.cpp @@ -78,6 +78,7 @@ read_resources(const char* appSignature) kVolMenuLabel = LoadString("STR_VM_LABEL"); kOneFile = LoadString("STR_1_FILE"); kManyFiles = LoadString("STR_N_FILES"); + kStrScan = LoadString("STR_SCAN"); kStrRescan = LoadString("STR_RESCAN"); kStrScanningX = LoadString("STR_SCN_X"); kStrUnavail = LoadString("STR_UNAVAIL"); @@ -94,6 +95,7 @@ read_resources(const char* appSignature) kInfoTimeFmt = LoadString("STR_TIMEFMT"); kInfoKind = LoadString("STR_KIND"); kInfoPath = LoadString("STR_PATH"); + kOutdatedStr = LoadString("STR_OUTDATED"); kWindowColor = ui_color(B_PANEL_BACKGROUND_COLOR); kOutlineColor = LoadColor("RGB_PIE_OL"); diff --git a/src/apps/diskusage/Common.h b/src/apps/diskusage/Common.h index b508c54234..1280419040 100644 --- a/src/apps/diskusage/Common.h +++ b/src/apps/diskusage/Common.h @@ -28,7 +28,9 @@ // Resources +EXTERN char* kStrScan; EXTERN char* kStrRescan; +EXTERN char* kOutdatedStr; EXTERN char* kStrScanningX; EXTERN char* kStrUnavail; EXTERN char* kVolMenuLabel; @@ -93,6 +95,7 @@ EXTERN bool kFoundHelpFile; #define kScanRefresh 'gSRF' #define kScanProgress 'gSPR' #define kScanDone 'gSDN' +#define kOutdatedMsg 'gOUT' #define deg2rad(x) (2.0 * M_PI * (x) / 360.0) #define rad2deg(x) (360.0 * (x) / (2.0 * M_PI)) diff --git a/src/apps/diskusage/ControlsView.cpp b/src/apps/diskusage/ControlsView.cpp index 870333ed20..8d1d31208b 100644 --- a/src/apps/diskusage/ControlsView.cpp +++ b/src/apps/diskusage/ControlsView.cpp @@ -12,47 +12,44 @@ #include #include -#include -#include +#include #include +#include #include #include #include #include #include +#include + #include "Common.h" +#include "VolumeView.h" -class VolumeMenuItem: public BMenuItem { +class VolumeTab: public BTab { public: - VolumeMenuItem(BVolume* volume, BMessage* message); - virtual ~VolumeMenuItem(); + VolumeTab(BVolume* volume); + virtual ~VolumeTab(); - virtual void GetContentSize(float* width, float* height); - virtual void DrawContent(); + BVolume* Volume() const + { return fVolume; } + float IconWidth() const; - BVolume* Volume() const - { return fVolume; } - status_t Invoke(BMessage* mesage = NULL) - { return BMenuItem::Invoke(); } + virtual void DrawLabel(BView* owner, BRect frame); private: - BBitmap* fIcon; - BVolume* fVolume; + BBitmap* fIcon; + BVolume* fVolume; }; -VolumeMenuItem::VolumeMenuItem(BVolume* volume, BMessage* message) +VolumeTab::VolumeTab(BVolume* volume) : - BMenuItem(kEmptyStr, message), + BTab(), fIcon(new BBitmap(BRect(0, 0, 15, 15), B_RGBA32)), fVolume(volume) { - char name[B_PATH_NAME_LENGTH]; - fVolume->GetName(name); - SetLabel(name); - if (fVolume->GetIcon(fIcon, B_MINI_ICON) < B_OK) { delete fIcon; fIcon = NULL; @@ -60,53 +57,56 @@ VolumeMenuItem::VolumeMenuItem(BVolume* volume, BMessage* message) } -VolumeMenuItem::~VolumeMenuItem() +float +VolumeTab::IconWidth() const +{ + if (fIcon != NULL) + // add a small margin + return fIcon->Bounds().Width() + kSmallHMargin; + else + return 0.0f; +} + + +void +VolumeTab::DrawLabel(BView* owner, BRect frame) +{ + owner->SetDrawingMode(B_OP_OVER); + if (fIcon != NULL) { + owner->MovePenTo(frame.left + kSmallHMargin, + (frame.top + frame.bottom - fIcon->Bounds().Height()) / 2.0); + owner->DrawBitmap(fIcon); + } + + font_height fh; + owner->GetFontHeight(&fh); + + owner->SetHighColor(ui_color(B_CONTROL_TEXT_COLOR)); + owner->DrawString(Label(), + BPoint(frame.left + IconWidth() + kSmallHMargin, + (frame.top + frame.bottom - fh.ascent - fh.descent) / 2.0 + + fh.ascent)); +} + + +VolumeTab::~VolumeTab() { delete fIcon; delete fVolume; } -void -VolumeMenuItem::GetContentSize(float* width, float* height) -{ - *width = be_plain_font->StringWidth(Label()); - - struct font_height fh; - be_plain_font->GetHeight(&fh); - float fontHeight = fh.ascent + fh.descent + fh.leading; - if (fIcon) { - *height = max_c(fontHeight, fIcon->Bounds().Height()); - *width += fIcon->Bounds().Width() + kSmallHMargin; - } else - *height = fontHeight; -} - - -void -VolumeMenuItem::DrawContent() -{ - if (fIcon) { - Menu()->SetDrawingMode(B_OP_OVER); - Menu()->MovePenBy(0.0, -1.0); - Menu()->DrawBitmap(fIcon); - Menu()->SetDrawingMode(B_OP_COPY); - Menu()->MovePenBy(fIcon->Bounds().Width() + kSmallHMargin, 0.0); - } - BMenuItem::DrawContent(); -} - - // #pragma mark - -class ControlsView::VolumePopup: public BMenuField { +class ControlsView::VolumeTabView: public BTabView { public: - VolumePopup(BRect r); - virtual ~VolumePopup(); + VolumeTabView(); + virtual ~VolumeTabView(); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* message); + virtual BRect TabFrame(int32 index) const; BVolume* FindDeviceFor(dev_t device, bool invoke = false); @@ -119,16 +119,40 @@ private: }; -ControlsView::VolumePopup::VolumePopup(BRect r) +ControlsView::VolumeTabView::VolumeTabView() : - BMenuField(r, NULL, kVolMenuLabel, new BPopUpMenu(kVolMenuDefault), false, - B_FOLLOW_LEFT) + BTabView("volume_tabs", B_WIDTH_FROM_LABEL) { - SetViewColor(kWindowColor); - SetLowColor(kWindowColor); +} - SetDivider(kSmallHMargin + StringWidth(kVolMenuLabel)); +ControlsView::VolumeTabView::~VolumeTabView() +{ + fVolumeRoster->StopWatching(); + delete fVolumeRoster; +} + + +BRect +ControlsView::VolumeTabView::TabFrame(int32 index) const +{ + float height = BTabView::TabFrame(index).Height(); + float x = 0.0f; + for (int32 i = 0; i < index; i++) { + x += StringWidth(TabAt(i)->Label()) + 3.0f * kSmallHMargin + + ((VolumeTab*)TabAt(i))->IconWidth(); + } + + return BRect(x, 0.0f, + x + StringWidth(TabAt(index)->Label()) + 3.0f * kSmallHMargin + + ((VolumeTab*)TabAt(index))->IconWidth(), + height); +} + + +void +ControlsView::VolumeTabView::AttachedToWindow() +{ // Populate the menu with the persistent volumes. fVolumeRoster = new BVolumeRoster(); @@ -136,32 +160,20 @@ ControlsView::VolumePopup::VolumePopup(BRect r) while (fVolumeRoster->GetNextVolume(&tempVolume) == B_OK) { if (tempVolume.IsPersistent()) { BVolume* volume = new BVolume(tempVolume); - BMessage* message = new BMessage(kMenuSelectVol); - message->AddPointer(kNameVolPtr, volume); - VolumeMenuItem *item = new VolumeMenuItem(volume, message); - Menu()->AddItem(item); + VolumeTab *item = new VolumeTab(volume); + char name[B_PATH_NAME_LENGTH]; + volume->GetName(name); + AddTab(new VolumeView(name, volume), item); } } -} - -ControlsView::VolumePopup::~VolumePopup() -{ - fVolumeRoster->StopWatching(); - delete fVolumeRoster; -} - - -void -ControlsView::VolumePopup::AttachedToWindow() -{ // Begin watching mount and unmount events. fVolumeRoster->StartWatching(BMessenger(this)); } void -ControlsView::VolumePopup::MessageReceived(BMessage* message) +ControlsView::VolumeTabView::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: @@ -176,24 +188,50 @@ ControlsView::VolumePopup::MessageReceived(BMessage* message) } break; + case kBtnRescan: + ViewForTab(Selection())->MessageReceived(message); + break; + + case B_SIMPLE_DATA: + case B_REFS_RECEIVED: + { + entry_ref ref; + + for (int i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { + BEntry entry(&ref, true); + BPath path; + entry.GetPath(&path); + dev_t device = dev_for_path(path.Path()); + + for (int j = 0; VolumeTab* item = (VolumeTab*)TabAt(j); j++) { + if (item->Volume()->Device() == device) { + Select(j); + ((VolumeView*)(item->View()))->SetPath(path); + break; + } + } + } + break; + } + default: - BMenuField::MessageReceived(message); + BTabView::MessageReceived(message); break; } } BVolume* -ControlsView::VolumePopup::FindDeviceFor(dev_t device, bool invoke) +ControlsView::VolumeTabView::FindDeviceFor(dev_t device, bool invoke) { BVolume* volume = NULL; // Iterate through items looking for a BVolume representing this device. - for (int i = 0; VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i); i++) { + for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) { if (item->Volume()->Device() == device) { volume = item->Volume(); if (invoke) - item->Invoke(); + Select(i); break; } } @@ -203,43 +241,36 @@ ControlsView::VolumePopup::FindDeviceFor(dev_t device, bool invoke) void -ControlsView::VolumePopup::_AddVolume(dev_t device) +ControlsView::VolumeTabView::_AddVolume(dev_t device) { // Make sure the volume is not already in the menu. - for (int i = 0; i < Menu()->CountItems(); i++) { - VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i); + for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) { if (item->Volume()->Device() == device) return; } - // Add the newly mounted volume to the menu. BVolume* volume = new BVolume(device); - BMessage* message = new BMessage(kMenuSelectVol); - message->AddPointer(kNameVolPtr, volume); - VolumeMenuItem* item = new VolumeMenuItem(volume, message); - Menu()->AddItem(item); + + VolumeTab* item = new VolumeTab(volume); + char name[B_PATH_NAME_LENGTH]; + volume->GetName(name); + + AddTab(new VolumeView(name, volume), item); + Invalidate(); } void -ControlsView::VolumePopup::_RemoveVolume(dev_t device) +ControlsView::VolumeTabView::_RemoveVolume(dev_t device) { - for (int i = 0; i < Menu()->CountItems(); i++) { - VolumeMenuItem* item = (VolumeMenuItem*)Menu()->ItemAt(i); + for (int i = 0; VolumeTab* item = (VolumeTab*)TabAt(i); i++) { if (item->Volume()->Device() == device) { - // If the volume being removed is currently selected, prompt for a - // different volume. - if (item->IsMarked()) { - // update the displayed volume label now that there is no marked - // item: - Menu()->Superitem()->SetLabel(kVolMenuDefault); - - BMessage messae(kMenuSelectVol); - messae.AddPointer(kNameVolPtr, NULL); - Window()->PostMessage(&messae); - } - - Menu()->RemoveItem(item); + if (i == 0) + Select(1); + else + Select(i - 1); + RemoveTab(i); + delete item; return; } } @@ -249,43 +280,34 @@ ControlsView::VolumePopup::_RemoveVolume(dev_t device) // #pragma mark - -ControlsView::ControlsView(BRect r) - : BView(r, NULL, B_FOLLOW_LEFT_RIGHT, 0) +ControlsView::ControlsView() + : + BView(NULL, B_WILL_DRAW) { - SetViewColor(kWindowColor); + SetLayout(new BGroupLayout(B_VERTICAL)); + fVolumeTabView = new VolumeTabView(); + AddChild(BLayoutBuilder::Group<>(B_VERTICAL) + .Add(fVolumeTabView) + ); +} - r.top += kSmallVMargin; - r.right -= kSmallHMargin; - float buttonWidth = kButtonMargin + StringWidth(kHelpBtnLabel); - r.left = r.right - buttonWidth; - BButton* helpButton = new BButton(r, NULL, kHelpBtnLabel, new BMessage(kBtnHelp), - B_FOLLOW_RIGHT); - if (!kFoundHelpFile) - helpButton->SetEnabled(false); - r.right = r.left - kSmallHMargin; - buttonWidth = kButtonMargin + StringWidth(kStrRescan); - r.left = r.right - max_c(kMinButtonWidth, buttonWidth); - fRescanButton = new BButton(r, NULL, kStrRescan, new BMessage(kBtnRescan), - B_FOLLOW_RIGHT); +void +ControlsView::MessageReceived(BMessage* msg) +{ + switch (msg->what) { + case B_SIMPLE_DATA: + case B_REFS_RECEIVED: + fVolumeTabView->MessageReceived(msg); + break; - fVolumePopup = new VolumePopup( - BRect(kSmallHMargin, kSmallVMargin, r.left - kSmallHMargin, kSmallVMargin)); + case kBtnRescan: + fVolumeTabView->MessageReceived(msg); + break; - float width, height; - fRescanButton->GetPreferredSize(&width, &height); - ResizeTo(Bounds().Width(), height + 6.0); - - // Horizontal divider - r = Bounds(); - r.top = r.bottom - 1.0; - r.left -= 5.0; r.right += 5.0; - BBox* divider = new BBox(r, NULL, B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW); - - AddChild(fVolumePopup); - AddChild(divider); - AddChild(fRescanButton); - AddChild(helpButton); + default: + BView::MessageReceived(msg); + } } @@ -294,8 +316,24 @@ ControlsView::~ControlsView() } +void +ControlsView::ShowInfo(const FileInfo* info) +{ + ((VolumeView*)fVolumeTabView->ViewForTab( + fVolumeTabView->Selection()))->ShowInfo(info); +} + + +void +ControlsView::SetRescanEnabled(bool enabled) +{ + ((VolumeView*)fVolumeTabView->ViewForTab( + fVolumeTabView->Selection()))->SetRescanEnabled(enabled); +} + + BVolume* ControlsView::FindDeviceFor(dev_t device, bool invoke) { - return fVolumePopup->FindDeviceFor(device, invoke); + return fVolumeTabView->FindDeviceFor(device, invoke); } diff --git a/src/apps/diskusage/ControlsView.h b/src/apps/diskusage/ControlsView.h index 155ae6e70d..1e13dcdfc3 100644 --- a/src/apps/diskusage/ControlsView.h +++ b/src/apps/diskusage/ControlsView.h @@ -9,29 +9,32 @@ #ifndef CONTROLS_VIEW_H #define CONTROLS_VIEW_H - #include #include +class BMessage; class BVolume; +struct FileInfo; + class ControlsView: public BView { public: - ControlsView(BRect r); + ControlsView(); virtual ~ControlsView(); - void SetRescanEnabled(bool enable) - { fRescanButton->SetEnabled(enable); } + virtual void MessageReceived(BMessage* msg); BVolume* FindDeviceFor(dev_t device, bool invoke = false); - -private: - class VolumePopup; - VolumePopup* fVolumePopup; - BButton* fRescanButton; + void SetRescanEnabled(bool enabled); + void ShowInfo(const FileInfo* info); + +private: + class VolumeTabView; + + VolumeTabView* fVolumeTabView; }; diff --git a/src/apps/diskusage/DiskUsage.rdef b/src/apps/diskusage/DiskUsage.rdef index e1ab2a7c04..2ee4c8c839 100644 --- a/src/apps/diskusage/DiskUsage.rdef +++ b/src/apps/diskusage/DiskUsage.rdef @@ -62,6 +62,7 @@ resource(101, "N_PIE_COLORS") (uint8)4; resource(103, "STR_N_FILES") "%d files"; resource(102, "STR_1_FILE") "%d file"; resource(101, "STR_VM_LABEL") "Volume:"; +resource(120, "STR_SCAN") "Scan"; resource(104, "STR_RESCAN") "Rescan"; resource(105, "STR_SCN_X") "Scanning "; resource(106, "STR_UNAVAIL") "file unavailable"; @@ -78,4 +79,4 @@ resource(116, "STR_MOD") "Modified"; resource(117, "STR_TIMEFMT") "%a, %d %b %Y, %r"; resource(118, "STR_KIND") "Kind"; resource(119, "STR_PATH") "Path"; - +resource(121, "STR_OUTDATED") "Outdated view"; diff --git a/src/apps/diskusage/Jamfile b/src/apps/diskusage/Jamfile index 27e509b754..edd802ac8d 100644 --- a/src/apps/diskusage/Jamfile +++ b/src/apps/diskusage/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src apps diskusage ; -UsePrivateHeaders mount shared tracker ; +UsePrivateHeaders mount shared tracker storage ; SubDirHdrs $(HAIKU_TOP) src kits tracker ; Application DiskUsage : @@ -14,6 +14,7 @@ Application DiskUsage : Scanner.cpp Snapshot.cpp StatusView.cpp + VolumeView.cpp : be $(TARGET_LIBSTDC++) : DiskUsage.rdef ; diff --git a/src/apps/diskusage/MainWindow.cpp b/src/apps/diskusage/MainWindow.cpp index 414a4196eb..fc439a5e69 100644 --- a/src/apps/diskusage/MainWindow.cpp +++ b/src/apps/diskusage/MainWindow.cpp @@ -7,8 +7,6 @@ * as long as it is accompanied by it's documentation and this copyright notice. * The software comes with no warranty, etc. */ - - #include "MainWindow.h" #include @@ -16,58 +14,28 @@ #include #include +#include + #include "Common.h" #include "ControlsView.h" -#include "PieView.h" -#include "StatusView.h" - - -const float kMinWinSize = 275.0; MainWindow::MainWindow(BRect pieRect) : BWindow(pieRect, "DiskUsage", B_TITLED_WINDOW, - B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE) + B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE + | B_AUTO_UPDATE_SIZE_LIMITS) { - BRect r = Bounds(); - r.bottom = r.top + 1.0; - fControlsView = new ControlsView(r); - float cvHeight = fControlsView->Bounds().Height(); - AddChild(fControlsView); + fControlsView = new ControlsView(); - r = Bounds(); - r.top = r.bottom - 1.0; - fStatusView = new StatusView(r); - float svHeight = fStatusView->Bounds().Height(); + SetLayout(new BGroupLayout(B_VERTICAL)); - float winHeight = pieRect.Height() + cvHeight + svHeight; - fStatusView->MoveTo(0.0, winHeight - svHeight); - ResizeTo(r.Width(), winHeight); - - AddChild(fStatusView); - - r = fControlsView->Frame(); - r.top = r.bottom + 1.0; - r.bottom = fStatusView->Frame().top - 1.0; - fPieView = new PieView(r, this); - AddChild(fPieView); - - Show(); - - // Note: The following code is semi-broken because BScreen::Frame() - // returns incorrect dimensions for the G200 in 1152x864 mode. I reported - // this bug, and Be said it's not a bug -- the Matrox driver actually uses - // a resolution of 1152x900 in that mode. Oh well. - Lock(); - float extraHeight = fControlsView->Bounds().Height() - + fStatusView->Bounds().Height(); - float minHeight = kMinWinSize + extraHeight; - float maxHeight = BScreen(this).Frame().Height(); - float maxWidth = maxHeight - extraHeight; - Unlock(); - - SetSizeLimits(kMinWinSize, maxWidth, minHeight, maxHeight); + AddChild(BLayoutBuilder::Group<>(B_VERTICAL) + .Add(fControlsView) + .SetInsets(5, 5, 5, 5) + ); + float maxHeight = BScreen(this).Frame().Height() - 12; + fControlsView->SetExplicitMaxSize(BSize(maxHeight, maxHeight)); } @@ -81,9 +49,11 @@ MainWindow::MessageReceived(BMessage* message) { switch (message->what) { case kBtnRescan: - case kMenuSelectVol: + fControlsView->MessageReceived(message); + break; + case B_SIMPLE_DATA: case B_REFS_RECEIVED: - fPieView->MessageReceived(message); + fControlsView->MessageReceived(message); break; case kBtnHelp: @@ -109,16 +79,16 @@ MainWindow::QuitRequested() void -MainWindow::ShowInfo(const FileInfo* info) +MainWindow::SetRescanEnabled(bool enabled) { - fStatusView->ShowInfo(info); + fControlsView->SetRescanEnabled(enabled); } void -MainWindow::SetRescanEnabled(bool enabled) +MainWindow::ShowInfo(const FileInfo* info) { - fControlsView->SetRescanEnabled(enabled); + fControlsView->ShowInfo(info); } diff --git a/src/apps/diskusage/MainWindow.h b/src/apps/diskusage/MainWindow.h index 2afcdb6bf5..638354d4e1 100644 --- a/src/apps/diskusage/MainWindow.h +++ b/src/apps/diskusage/MainWindow.h @@ -10,7 +10,6 @@ #ifndef MAIN_WINDOW_H #define MAIN_WINDOW_H - #include @@ -18,8 +17,6 @@ class BVolume; class ControlsView; struct FileInfo; class PieView; -class StatusView; - class MainWindow: public BWindow { public: @@ -29,15 +26,14 @@ public: virtual void MessageReceived(BMessage* message); virtual bool QuitRequested(); - void ShowInfo(const FileInfo* info); void SetRescanEnabled(bool enabled); BVolume* FindDeviceFor(dev_t device, bool invoke = false); + void ShowInfo(const FileInfo* info); + private: ControlsView* fControlsView; - PieView* fPieView; - StatusView* fStatusView; }; #endif // MAIN_WINDOW_H diff --git a/src/apps/diskusage/PieView.cpp b/src/apps/diskusage/PieView.cpp index 9e92c84664..a325ca65d0 100644 --- a/src/apps/diskusage/PieView.cpp +++ b/src/apps/diskusage/PieView.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -41,8 +40,6 @@ static const int32 kIdxOpen = 1; static const int32 kIdxOpenWith = 2; static const int32 kIdxRescan = 3; -// TODO: It would be nice to make a common base class for AppMenuItem and -// VolMenuItem (menu items that include an icon). class AppMenuItem : public BMenuItem { public: @@ -125,20 +122,17 @@ AppMenuItem::DrawContent() // #pragma mark - PieView -PieView::PieView(BRect frame, MainWindow* window) +PieView::PieView(BVolume* volume) : - BView(frame, NULL, B_FOLLOW_ALL, - B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE), - fWindow(window), - fScanners(), - fCurrentVolume(NULL), + BView(NULL, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_SUBPIXEL_PRECISE), + fWindow(NULL), + fScanner(NULL), + fVolume(volume), fMouseOverInfo(), fClicked(false), - fDragging(false) + fDragging(false), + fOutdated(false) { - SetViewColor(B_TRANSPARENT_COLOR); - SetLowColor(kWindowColor); - fMouseOverMenu = new BPopUpMenu(kEmptyStr, false, false); fMouseOverMenu->AddItem(new BMenuItem(kMenuGetInfo, NULL), kIdxGetInfo); fMouseOverMenu->AddItem(new BMenuItem(kMenuOpen, NULL), kIdxOpen); @@ -160,16 +154,19 @@ PieView::PieView(BRect frame, MainWindow* window) } +void +PieView::AttachedToWindow() +{ + fWindow = (MainWindow*)Window(); +} + + PieView::~PieView() { delete fMouseOverMenu; delete fFileUnavailableMenu; - - while (fScanners.size() != 0) { - ScannerMap::iterator i = fScanners.begin(); - (*i).second->RequestQuit(); - fScanners.erase(i); - } + if (fScanner != NULL) + fScanner->RequestQuit(); } @@ -177,41 +174,31 @@ void PieView::MessageReceived(BMessage* message) { switch (message->what) { - case B_SIMPLE_DATA: - case B_REFS_RECEIVED: - { - entry_ref ref; - for (int i = 0; message->FindRef("refs", i, &ref) == B_OK; i++) { - BEntry entry(&ref, true); - _HandleArg(&entry); - } - break; - } - case kBtnRescan: - if (fCurrentVolume != NULL) { - fScanners[fCurrentVolume]->Refresh(); + if (fVolume != NULL) { + if (fScanner != NULL) + fScanner->Refresh(); + else + _ShowVolume(fVolume); + + fOutdated = false; Invalidate(); } break; - case kMenuSelectVol: - { - BVolume* volume; - if (message->FindPointer(kNameVolPtr, (void**)&volume) == B_OK) - _ShowVolume(volume); - break; - } - case kScanProgress: case kScanDone: { - BVolume* volume; - if (message->FindPointer(kNameVolPtr, (void**)&volume) == B_OK - && volume == fCurrentVolume) { + Invalidate(); + break; + } + + case kOutdatedMsg: + { + if (!fScanner->IsBusy()) { + fOutdated = true; Invalidate(); } - break; } default: @@ -251,14 +238,15 @@ PieView::MouseUp(BPoint where) // If the primary button was released and there was no dragging happening, // just zoom in or out. if (fClicked && !fDragging) { - Scanner* scanner = fScanners[fCurrentVolume]; FileInfo* info = _FileAt(where); if (info != NULL) { - if (info == scanner->CurrentDir()) { - scanner->ChangeDir(info->parent); + if (info == fScanner->CurrentDir()) { + fScanner->ChangeDir(info->parent); + fOutdated = fScanner->IsOutdated(); Invalidate(); } else if (info->children.size() > 0) { - scanner->ChangeDir(info); + fScanner->ChangeDir(info); + fOutdated = fScanner->IsOutdated(); Invalidate(); } } @@ -307,27 +295,32 @@ PieView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) void PieView::Draw(BRect updateRect) { - if (fScanners.find(fCurrentVolume) != fScanners.end()) { + if (fScanner != NULL) { // There is a current volume. - Scanner* scanner = fScanners[fCurrentVolume]; - if (scanner->IsBusy()) { + if (fScanner->IsBusy()) { // Show progress of scanning. _DrawProgressBar(updateRect); - fWindow->SetRescanEnabled(false); + if (fWindow != NULL) + fWindow->SetRescanEnabled(false); } else { _DrawPieChart(updateRect); - fWindow->SetRescanEnabled(true); + if (fWindow != NULL) + fWindow->SetRescanEnabled(true); } - } else { - // No volume has been selected, so display a prompt for one. - FillRect(updateRect, B_SOLID_LOW); - BRect b = Bounds(); - float strWidth = StringWidth(kVolPrompt); - float bx = (b.left + b.Width() - strWidth) / 2.0; - float by = (b.top + b.Height()) / 2.0; - SetHighColor(0x00, 0x00, 0x00); - DrawString(kVolPrompt, BPoint(bx, by)); - fWindow->SetRescanEnabled(false); + } +} + + +void +PieView::SetPath(BPath path) +{ + if (fScanner == NULL) + _ShowVolume(fVolume); + + if (fScanner != NULL) { + string desiredPath(path.Path()); + fScanner->SetDesiredPath(desiredPath); + Invalidate(); } } @@ -335,57 +328,17 @@ PieView::Draw(BRect updateRect) // #pragma mark - private -void -PieView::_HandleArg(const BEntry* entry) -{ - // Going through these seemingly pointless gyrations (instead of getting - // the dev_t directly from the BEntry) allows us to process volumes - // properly. It looks like a dropped volume refers to dev_t 1 (why?), but - // getting the dev_t from the path allows us to get at the dev_t where the - // root directory actually lives. - BPath path; - entry->GetPath(&path); - dev_t device = dev_for_path(path.Path()); - - // Set the desired path in the scanner. - Scanner* scanner = NULL; - ScannerMap::iterator i = fScanners.begin(); - while (i != fScanners.end()) { - if ((*i).second->Device() == device) { - scanner = (*i).second; - break; - } - i++; - } - - if (scanner == NULL) { - BVolume* volume = fWindow->FindDeviceFor(device); - if (volume != NULL) - scanner = fScanners[volume] = new Scanner(volume, this); - } - if (scanner != NULL) { - string desiredPath(path.Path()); - scanner->SetDesiredPath(desiredPath); - - // Select the volume on the menu. - fWindow->FindDeviceFor(device, true); - } -} - - void PieView::_ShowVolume(BVolume* volume) { if (volume != NULL) { - if (fScanners.find(volume) == fScanners.end()) - fScanners[volume] = new Scanner(volume, this); - - Scanner* scanner = fScanners[volume]; - if (scanner->Snapshot() == NULL) - scanner->Refresh(); + if (fScanner == NULL) + fScanner = new Scanner(volume, this); + + if (fScanner->Snapshot() == NULL) + fScanner->Refresh(); } - fCurrentVolume = volume; Invalidate(); } @@ -416,7 +369,7 @@ PieView::_DrawProgressBar(BRect updateRect) bx += 1.0; by += 1.0; ex -= 1.0; ey -= 1.0; float mx = bx + floorf((kProgBarWidth - 2.0) - * fScanners[fCurrentVolume]->Progress() / 100.0 + 0.5); + * fScanner->Progress() / 100.0 + 0.5); SetHighColor(tint_color(kWindowColor, B_DARKEN_1_TINT)); FillRect(BRect(mx, by, ex, ey)); @@ -433,7 +386,7 @@ PieView::_DrawProgressBar(BRect updateRect) FillRect(BRect(bx, by, mx, ey)); // Tell what we are doing. - const char* task = fScanners[fCurrentVolume]->Task(); + const char* task = fScanner->Task(); float strWidth = StringWidth(task); bx = (b.left + b.Width() - strWidth) / 2.0; by -= fFontHeight + 2.0 * kSmallVMargin; @@ -465,7 +418,7 @@ PieView::_DrawPieChart(BRect updateRect) pieRect.bottom += moveBy; } int colorIdx = 0; - FileInfo* currentDir = fScanners[fCurrentVolume]->CurrentDir(); + FileInfo* currentDir = fScanner->CurrentDir(); FileInfo* parent = currentDir; while (parent != NULL) { parent = parent->parent; @@ -473,16 +426,21 @@ PieView::_DrawPieChart(BRect updateRect) } _DrawDirectory(pieRect, currentDir, 0.0, 0.0, colorIdx % kBasePieColorCount, 0); + + if (fOutdated) { + + BRect b = Bounds(); - // This is just for the case when the mouse hovers over the view - // while the scanning process is running and then does not move - // until after the results are shown. In that case the info will - // not automatically update. (TODO: fix this and put into MessageReceived() - // kScanDone - currently, fileAt() returns NULL (mouseoverinfo...)) - BPoint where; - uint32 ignore; - GetMouse(&where, &ignore, false); - fWindow->ShowInfo(_FileAt(where)); + float strWidth = StringWidth(kOutdatedStr); + float bx = (b.Width() - strWidth - kSmallHMargin); + + struct font_height fh; + be_plain_font->GetHeight(&fh); + + float by = (b.Height() - ceil(fh.descent) - kSmallVMargin); + SetHighColor(0x00, 0x00, 0x00); + DrawString(kOutdatedStr, BPoint(bx, by)); + } } @@ -500,7 +458,7 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan, else if (info != NULL) info->color = colorIdx; - VolumeSnapshot* snapshot = fScanners[fCurrentVolume]->Snapshot(); + VolumeSnapshot* snapshot = fScanner->Snapshot(); float cx = floorf(b.left + b.Width() / 2.0 + 0.5); float cy = floorf(b.top + b.Height() / 2.0 + 0.5); @@ -525,7 +483,8 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan, FillEllipse(BPoint(cx, cy), kPieCenterSize, kPieCenterSize); SetHighColor(kBasePieColor[0]); - FillArc(BPoint(cx, cy), kPieCenterSize, kPieCenterSize, 0.0, mySpan); + FillArc(BPoint(cx, cy), kPieCenterSize, kPieCenterSize, 0.0, + mySpan); // Show total volume capacity. char label[B_PATH_NAME_LENGTH]; @@ -560,7 +519,8 @@ PieView::_DrawDirectory(BRect b, FileInfo* info, float parentSpan, SetPenSize(1.0); SetHighColor(kOutlineColor); - StrokeEllipse(BPoint(cx, cy), kPieCenterSize + 0.5, kPieCenterSize + 0.5); + StrokeEllipse(BPoint(cx, cy), kPieCenterSize + 0.5, + kPieCenterSize + 0.5); // Show the name of the volume or directory. BString label(displayName); @@ -803,7 +763,7 @@ PieView::_ShowContextMenu(FileInfo* info, BPoint p) _Launch(info); break; case kIdxRescan: - fScanners[fCurrentVolume]->Refresh(info); + fScanner->Refresh(info); Invalidate(); break; default: // must be "Open With" submenu @@ -844,6 +804,7 @@ PieView::_Launch(FileInfo* info, const entry_ref* appRef) } } + void PieView::_OpenInfo(FileInfo* info, BPoint p) { diff --git a/src/apps/diskusage/PieView.h b/src/apps/diskusage/PieView.h index 1b8a9aa587..9e0d5e3bee 100644 --- a/src/apps/diskusage/PieView.h +++ b/src/apps/diskusage/PieView.h @@ -20,6 +20,7 @@ class AppMenuItem; class BEntry; class BMenu; +class BPath; class BPopUpMenu; class BVolume; struct entry_ref; @@ -33,18 +34,19 @@ using std::vector; class PieView: public BView { public: - PieView(BRect frame, MainWindow* window); + PieView(BVolume* volume); virtual ~PieView(); + virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* message); virtual void MouseDown(BPoint where); virtual void MouseUp(BPoint where); virtual void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage); virtual void Draw(BRect updateRect); + void SetPath(BPath path); private: - void _HandleArg(const BEntry* entry); void _ShowVolume(BVolume* volume); void _DrawProgressBar(BRect updateRect); void _DrawPieChart(BRect updateRect); @@ -59,6 +61,7 @@ private: void _Launch(FileInfo* info, const entry_ref* ref = NULL); void _OpenInfo(FileInfo* info, BPoint p); + private: struct Segment { Segment() @@ -76,12 +79,10 @@ private: typedef vector SegmentList; typedef map MouseOverInfo; - typedef map ScannerMap; - private: MainWindow* fWindow; - ScannerMap fScanners; - BVolume* fCurrentVolume; + Scanner* fScanner; + BVolume* fVolume; FileInfo* fCurrentDir; MouseOverInfo fMouseOverInfo; BPopUpMenu* fMouseOverMenu; @@ -91,6 +92,7 @@ private: bool fDragging; BPoint fDragStart; FileInfo* fClickedFile; + bool fOutdated; }; #endif // PIE_VIEW_H diff --git a/src/apps/diskusage/Scanner.cpp b/src/apps/diskusage/Scanner.cpp index 5ac246bc1c..8054a8f30a 100644 --- a/src/apps/diskusage/Scanner.cpp +++ b/src/apps/diskusage/Scanner.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "Common.h" @@ -31,18 +32,27 @@ Scanner::Scanner(BVolume *v, BHandler *handler) fDesiredPath(), fTask(), fBusy(false), - fQuitRequested(false) + fQuitRequested(false), + fIsWatching(false), + fModifiedEntries() { - fDoneMessage.AddPointer(kNameVolPtr, fVolume); - fProgressMessage.AddPointer(kNameVolPtr, fVolume); - Run(); } Scanner::~Scanner() { + if (fIsWatching) { + BPrivate::BPathMonitor::StopWatching(BMessenger(this, this)); + fIsWatching = false; + } delete fSnapshot; + + while (fModifiedEntries.size() != 0) { + entry_ref* entry = *fModifiedEntries.begin(); + delete entry; + fModifiedEntries.erase(fModifiedEntries.begin()); + } } @@ -58,6 +68,38 @@ Scanner::MessageReceived(BMessage* message) break; } + case B_PATH_MONITOR: + { + dev_t device; + ino_t directory; + const char* name = ""; + const char* path; + + if (((message->FindInt32("device", &device) != B_OK) + || (message->FindInt64("directory", &directory) != B_OK) + || (message->FindString("name", &name) != B_OK)) + && ((message->FindString("path", &path) != B_OK) + || (message->FindInt32("device", &device) != B_OK))) + return; + + entry_ref* reportedEntry; + if (strlen(name) > 0) + reportedEntry = new entry_ref(device, directory, name); + else { + BEntry entry(path); + reportedEntry = new entry_ref(); + entry.GetRef(reportedEntry); + } + + fModifiedEntries.push_back(reportedEntry); + + if (IsOutdated()) { + BMessage msg(kOutdatedMsg); + fListener.SendMessage(&msg); + } + + } + default: BLooper::MessageReceived(message); break; @@ -73,6 +115,12 @@ Scanner::Refresh(FileInfo* startInfo) fBusy = true; + while (fModifiedEntries.size() != 0) { + entry_ref* entry = *fModifiedEntries.begin(); + delete entry; + fModifiedEntries.erase(fModifiedEntries.begin()); + } + // Remember the current directory, if any, so we can return to it after // the scanning is done. if (fSnapshot != NULL && fSnapshot->currentDir != NULL) @@ -112,9 +160,43 @@ Scanner::RequestQuit() } +bool +Scanner::IsOutdated() +{ + FileInfo* currentDir = (fSnapshot->currentDir != NULL ? + fSnapshot->currentDir : fSnapshot->rootDir); + + BDirectory currentDirectory(&(currentDir->ref)); + + bool isOutdated = currentDirectory.InitCheck() != B_OK; + + vector::iterator i = fModifiedEntries.begin(); + while (!isOutdated && i != fModifiedEntries.end()) { + BEntry entry(*i); + isOutdated = _DirectoryContains(currentDir, *i) + || currentDirectory.Contains(&entry); + i++; + } + return isOutdated; +} + + // #pragma mark - private +bool +Scanner::_DirectoryContains(FileInfo* currentDir, entry_ref* ref) +{ + vector::iterator i = currentDir->children.begin(); + bool contains = currentDir->ref == *ref; + while (!contains && i != currentDir->children.end()) { + contains |= _DirectoryContains((*i), ref); + i++; + } + return contains; +} + + void Scanner::_RunScan(FileInfo* startInfo) { @@ -168,6 +250,16 @@ Scanner::_RunScan(FileInfo* startInfo) } } + if (!fIsWatching) { + string path; + fSnapshot->rootDir->GetPath(path); + + BPrivate::BPathMonitor::StartWatching(path.c_str(), + B_WATCH_ALL | B_WATCH_RECURSIVELY, BMessenger(this, this)); + + fIsWatching = true; + } + fBusy = false; _ChangeToDesired(); fListener.SendMessage(&fDoneMessage); diff --git a/src/apps/diskusage/Scanner.h b/src/apps/diskusage/Scanner.h index d4269aa3e0..bfc92221d1 100644 --- a/src/apps/diskusage/Scanner.h +++ b/src/apps/diskusage/Scanner.h @@ -11,6 +11,7 @@ #include +#include #include #include @@ -49,11 +50,14 @@ public: dev_t Device() const { return fVolume->Device(); } void RequestQuit(); + bool IsOutdated(); private: void _RunScan(FileInfo *startInfo); FileInfo* _GetFileInfo(BDirectory* dir, FileInfo* parent); void _ChangeToDesired(); + bool _DirectoryContains(FileInfo* currentDir, + entry_ref* ref); BMessenger fListener; BMessage fDoneMessage; @@ -69,6 +73,10 @@ private: string fTask; bool fBusy; bool fQuitRequested; + + bool fIsWatching; + + std::vector fModifiedEntries; }; #endif // SCANNER_H diff --git a/src/apps/diskusage/StatusView.cpp b/src/apps/diskusage/StatusView.cpp index e0bb00ae64..66669b330b 100644 --- a/src/apps/diskusage/StatusView.cpp +++ b/src/apps/diskusage/StatusView.cpp @@ -1,4 +1,5 @@ /* + * Copyright (c) 2010 Philippe St-Pierre . All rights reserved. * Copyright (c) 2008 Stephan Aßmus . All rights reserved. * Distributed under the terms of the MIT/X11 license. * @@ -14,73 +15,70 @@ #include #include +#include #include #include #include +#include + #include "Common.h" #include "Scanner.h" -StatusView::StatusView(BRect rect) +StatusView::StatusView() : - BView(rect, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW), + BView(NULL, B_WILL_DRAW), fCurrentFileInfo(NULL) { - SetViewColor(kWindowColor); + SetViewColor(kPieBGColor); + SetLowColor(kPieBGColor); - struct font_height fh; - be_plain_font->GetHeight(&fh); - float plainHeight = ceilf(fh.ascent) + ceilf(fh.descent) - + ceilf(fh.leading); - float fixedHeight = ceilf(fh.ascent) + ceilf(fh.descent) - + ceilf(fh.leading); - ResizeTo(Bounds().Width(), - 2.0 * kSmallVMargin + max_c(plainHeight, fixedHeight)); + fSizeView = new BStringView(NULL, kEmptyStr); + fSizeView->SetExplicitMinSize(BSize(StringWidth("9999.99 GB"), + B_SIZE_UNSET)); + fSizeView->SetExplicitMaxSize(BSize(StringWidth("9999.99 GB"), + B_SIZE_UNSET)); - BRect r = Bounds(); - r.top += kSmallVMargin; - - // Size display - r.right -= kSmallHMargin; - r.left = r.right - StringWidth("9999.99 GB"); - fSizeView = new BStringView(r, NULL, kEmptyStr, - B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM); - AddChild(fSizeView); - - // Vertical divider - r.right = r.left - kSmallHMargin; - r.left = r.right - 1.0; - AddChild(new BBox(r.InsetByCopy(0, -5), NULL, - B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM)); - - // Count display char testLabel[256]; sprintf(testLabel, kManyFiles, 999999); - r.right = r.left - kSmallHMargin; - r.left = r.right - (StringWidth(testLabel) + kSmallHMargin); - fCountView = new BStringView(r, NULL, kEmptyStr, - B_FOLLOW_RIGHT|B_FOLLOW_TOP_BOTTOM); - AddChild(fCountView); - // Vertical divider - r.right = r.left - kSmallHMargin; - r.left = r.right - 1.0; - AddChild(new BBox(r.InsetByCopy(0, -5), NULL, - B_FOLLOW_RIGHT | B_FOLLOW_TOP_BOTTOM)); + fCountView = new BStringView(NULL, kEmptyStr); + fCountView->SetExplicitMinSize(BSize(StringWidth(testLabel), B_SIZE_UNSET)); + fCountView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); - // Path display - r.right = r.left - kSmallHMargin; - r.left = kSmallHMargin; - fPathView = new BStringView(r, NULL, kEmptyStr, - B_FOLLOW_LEFT_RIGHT|B_FOLLOW_TOP_BOTTOM); - AddChild(fPathView); + fPathView = new BStringView(NULL, kEmptyStr); + fPathView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); - // Horizontal divider - r = Bounds(); - r.bottom = r.top + 1.0; - AddChild(new BBox(r.InsetByCopy(-5, 0), NULL, - B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM, B_WILL_DRAW)); + fRefreshBtn = new BButton(NULL, kStrScan, new BMessage(kBtnRescan)); + + fRefreshBtn->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNLIMITED)); + + BBox* divider1 = new BBox(BRect(), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, + B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER); + + BBox* divider2 = new BBox(BRect(), B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, + B_WILL_DRAW | B_FRAME_EVENTS, B_FANCY_BORDER); + + divider1->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 1)); + divider2->SetExplicitMaxSize(BSize(1, B_SIZE_UNLIMITED)); + + SetLayout(new BGroupLayout(B_VERTICAL)); + + AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL) + .AddGroup(B_VERTICAL) + .Add(fPathView) + .Add(divider1) + .AddGroup(B_HORIZONTAL) + .Add(fCountView) + .Add(divider2) + .Add(fSizeView) + .End() + .End() + .AddStrut(kSmallHMargin) + .Add(fRefreshBtn) + .SetInsets(kSmallHMargin, kSmallVMargin, kSmallVMargin, kSmallVMargin) + ); } @@ -89,6 +87,20 @@ StatusView::~StatusView() } +void +StatusView::SetRescanEnabled(bool enabled) +{ + fRefreshBtn->SetEnabled(enabled); +} + + +void +StatusView::SetBtnLabel(const char* label) +{ + fRefreshBtn->SetLabel(label); +} + + void StatusView::ShowInfo(const FileInfo* info) { diff --git a/src/apps/diskusage/StatusView.h b/src/apps/diskusage/StatusView.h index 9308c4653b..97051dac82 100644 --- a/src/apps/diskusage/StatusView.h +++ b/src/apps/diskusage/StatusView.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2010 Philippe St-Pierre . All rights reserved. * Copyright (c) 2008 Stephan Aßmus . All rights reserved. * Distributed under the terms of the MIT/X11 license. * @@ -9,7 +10,7 @@ #ifndef STATUS_VIEW_H #define STATUS_VIEW_H - +#include #include #include #include @@ -19,17 +20,22 @@ struct FileInfo; class StatusView: public BView { public: - StatusView(BRect frame); + StatusView(); virtual ~StatusView(); void ShowInfo(const FileInfo* info); + void SetBtnLabel(const char* label); + void SetRescanEnabled(bool enabled); private: BStringView* fPathView; BStringView* fSizeView; BStringView* fCountView; const FileInfo* fCurrentFileInfo; + + BButton* fRefreshBtn; }; #endif // STATUS_VIEW_H + diff --git a/src/apps/diskusage/VolumeView.cpp b/src/apps/diskusage/VolumeView.cpp new file mode 100644 index 0000000000..7b56282235 --- /dev/null +++ b/src/apps/diskusage/VolumeView.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010 Philippe Saint-Pierre, stpere@gmail.com + * All rights reserved. Distributed under the terms of the MIT license. + * + * Copyright (c) 1999 Mike Steed. You are free to use and distribute this software + * as long as it is accompanied by it's documentation and this copyright notice. + * The software comes with no warranty, etc. + */ + + +#include +#include +#include +#include +#include + +#include + +#include "Common.h" +#include "MainWindow.h" +#include "PieView.h" +#include "StatusView.h" + +#include "VolumeView.h" + +const float kMinWinSize = 275.0; + +VolumeView::VolumeView(const char* name, BVolume* volume) + : BView(name, B_WILL_DRAW) +{ + SetLayout(new BGroupLayout(B_HORIZONTAL)); + fPieView = new PieView(volume); + + fPieView->SetExplicitMinSize(BSize(kMinWinSize, kMinWinSize)); + + fStatusView = new StatusView(); + + AddChild(BLayoutBuilder::Group<>(B_VERTICAL) + .Add(fPieView) + .Add(fStatusView) + ); +} + + +VolumeView::~VolumeView() +{ +} + + +void +VolumeView::SetRescanEnabled(bool enabled) +{ + fStatusView->SetRescanEnabled(enabled); +} + + +void +VolumeView::SetPath(BPath path) +{ + fPieView->SetPath(path); + fStatusView->SetBtnLabel(kStrRescan); +} + + +void +VolumeView::MessageReceived(BMessage* msg) +{ + msg->PrintToStream(); + switch(msg->what) { + case kBtnRescan: + fPieView->MessageReceived(msg); + fStatusView->SetBtnLabel(kStrRescan); + break; + + default: + BView::MessageReceived(msg); + } +} + + +void +VolumeView::ShowInfo(const FileInfo* info) +{ + fStatusView->ShowInfo(info); +} diff --git a/src/apps/diskusage/VolumeView.h b/src/apps/diskusage/VolumeView.h new file mode 100644 index 0000000000..7dc4789b7a --- /dev/null +++ b/src/apps/diskusage/VolumeView.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010 Philippe Saint-Pierre, stpere@gmail.com + * All rights reserved. Distributed under the terms of the MIT license. + * + * Copyright (c) 1999 Mike Steed. You are free to use and distribute this software + * as long as it is accompanied by it's documentation and this copyright notice. + * The software comes with no warranty, etc. + */ + +#ifndef VOLUMETAB_VIEW_H +#define VOLUMETAB_VIEW_H + +#include + +class BButton; +class BPath; +class BStringView; +class BVolume; +class PieView; +class MainWindow; +class StatusView; + +struct FileInfo; + + +class VolumeView: public BView { + +public: + VolumeView(const char* name, BVolume* volume); + virtual ~VolumeView(); + + virtual void MessageReceived(BMessage* message); + void SetRescanEnabled(bool enabled); + void SetPath(BPath path); + void ShowInfo(const FileInfo* info); + +private: + PieView* fPieView; + StatusView* fStatusView; +}; + + + +#endif