Implemented display of current size/total size copied and current copy speed.
It will begin to play after a short time (10 seconds). Estimated finish time is still a TODO. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35129 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
406799c165
commit
4e1bbd4d0d
@ -55,7 +55,8 @@ All rights reserved.
|
||||
|
||||
|
||||
const float kDefaultStatusViewHeight = 50;
|
||||
const float kUpdateGrain = 100000;
|
||||
const bigtime_t kMaxUpdateInterval = 100000LL;
|
||||
const bigtime_t kSpeedReferenceInterval = 2000000LL;
|
||||
const BRect kStatusRect(200, 200, 550, 200);
|
||||
|
||||
|
||||
@ -500,7 +501,15 @@ BStatusView::Init()
|
||||
fWasCanceled = false;
|
||||
fIsPaused = false;
|
||||
fLastUpdateTime = 0;
|
||||
fBytesPerSecond = 0.0;
|
||||
for (size_t i = 0; i < kBytesPerSecondSlots; i++)
|
||||
fBytesPerSecondSlot[i] = 0.0;
|
||||
fCurrentBytesPerSecondSlot = 0;
|
||||
fItemSize = 0;
|
||||
fSizeProcessed = 0;
|
||||
|
||||
fProcessStartTime = fLastSpeedReferenceTime = system_time();
|
||||
fLastSpeedReferenceSize = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -559,6 +568,34 @@ BStatusView::InitStatus(int32 totalItems, off_t totalSize,
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
string_for_size(double size, char *string)
|
||||
{
|
||||
double kb = size / 1024.0;
|
||||
if (kb < 1.0) {
|
||||
sprintf(string, "%d B", (int)size);
|
||||
return string;
|
||||
}
|
||||
float mb = kb / 1024.0;
|
||||
if (mb < 1.0) {
|
||||
sprintf(string, "%3.1f KB", kb);
|
||||
return string;
|
||||
}
|
||||
float gb = mb / 1024.0;
|
||||
if (gb < 1.0) {
|
||||
sprintf(string, "%3.1f MB", mb);
|
||||
return string;
|
||||
}
|
||||
float tb = gb / 1024.0;
|
||||
if (tb < 1.0) {
|
||||
sprintf(string, "%3.1f GB", gb);
|
||||
return string;
|
||||
}
|
||||
sprintf(string, "%.1f TB", tb);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BStatusView::Draw(BRect updateRect)
|
||||
{
|
||||
@ -604,6 +641,42 @@ BStatusView::Draw(BRect updateRect)
|
||||
buffer << "To: " << fDestDir;
|
||||
SetHighColor(0, 0, 0);
|
||||
DrawString(buffer.String(), tp);
|
||||
|
||||
// Draw speed info
|
||||
float rightDivider = tp.x + StringWidth(buffer.String()) + 5.0f;
|
||||
if (fBytesPerSecond != 0.0) {
|
||||
SetHighColor(tint_color(LowColor(), B_DARKEN_4_TINT));
|
||||
|
||||
BFont font;
|
||||
GetFont(&font);
|
||||
float oldFontSize = font.Size();
|
||||
float fontSize = oldFontSize * 0.8f;
|
||||
font.SetSize(max_c(8.0f, fontSize));
|
||||
SetFont(&font, B_FONT_SIZE);
|
||||
|
||||
char sizeBuffer[128];
|
||||
buffer = "(";
|
||||
buffer << string_for_size((double)fSizeProcessed, sizeBuffer);
|
||||
buffer << " of ";
|
||||
buffer << string_for_size((double)fTotalSize, sizeBuffer);
|
||||
buffer << ", ";
|
||||
buffer << string_for_size(fBytesPerSecond, sizeBuffer);
|
||||
buffer << "/s)";
|
||||
tp.x = fStatusBar->Frame().right - StringWidth(buffer.String());
|
||||
if (tp.x > rightDivider)
|
||||
DrawString(buffer.String(), tp);
|
||||
else {
|
||||
// complete string too wide, try with shorter version
|
||||
buffer << string_for_size(fBytesPerSecond, sizeBuffer);
|
||||
buffer << "/s";
|
||||
tp.x = fStatusBar->Frame().right - StringWidth(buffer.String());
|
||||
if (tp.x > rightDivider)
|
||||
DrawString(buffer.String(), tp);
|
||||
}
|
||||
|
||||
font.SetSize(oldFontSize);
|
||||
SetFont(&font, B_FONT_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,6 +696,12 @@ BStatusView::MessageReceived(BMessage *message)
|
||||
case kPauseButton:
|
||||
fIsPaused = !fIsPaused;
|
||||
fPauseButton->SetValue(fIsPaused ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
if (fBytesPerSecond != 0.0) {
|
||||
fBytesPerSecond = 0.0;
|
||||
for (size_t i = 0; i < kBytesPerSecondSlots; i++)
|
||||
fBytesPerSecondSlot[i] = 0.0;
|
||||
Invalidate();
|
||||
}
|
||||
if (!fIsPaused) {
|
||||
|
||||
// force window update
|
||||
@ -657,48 +736,72 @@ BStatusView::MessageReceived(BMessage *message)
|
||||
void
|
||||
BStatusView::UpdateStatus(const char *curItem, off_t itemSize, bool optional)
|
||||
{
|
||||
float currentTime = system_time();
|
||||
|
||||
if (fShowCount) {
|
||||
|
||||
if (curItem)
|
||||
fCurItem++;
|
||||
|
||||
fItemSize += itemSize;
|
||||
|
||||
if (!optional || ((currentTime - fLastUpdateTime) > kUpdateGrain)) {
|
||||
if (curItem != NULL || fPendingStatusString[0]) {
|
||||
// forced update or past update time
|
||||
|
||||
BString buffer;
|
||||
buffer << fCurItem << " ";
|
||||
|
||||
// if we don't have curItem, take the one from the stash
|
||||
const char *statusItem = curItem != NULL
|
||||
? curItem : fPendingStatusString;
|
||||
|
||||
fStatusBar->Update((float)fItemSize / fTotalSize, statusItem,
|
||||
buffer.String());
|
||||
|
||||
// we already displayed this item, clear the stash
|
||||
fPendingStatusString[0] = '\0';
|
||||
|
||||
fLastUpdateTime = currentTime;
|
||||
}
|
||||
else
|
||||
// don't have a file to show, just update the bar
|
||||
fStatusBar->Update((float)fItemSize / fTotalSize);
|
||||
|
||||
fItemSize = 0;
|
||||
} else if (curItem != NULL) {
|
||||
// stash away the name of the item we are currently processing
|
||||
// so we can show it when the time comes
|
||||
strncpy(fPendingStatusString, curItem, 127);
|
||||
fPendingStatusString[127] = '0';
|
||||
}
|
||||
} else {
|
||||
if (!fShowCount) {
|
||||
fStatusBar->Update((float)fItemSize / fTotalSize);
|
||||
fItemSize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (curItem != NULL)
|
||||
fCurItem++;
|
||||
|
||||
fItemSize += itemSize;
|
||||
fSizeProcessed += itemSize;
|
||||
|
||||
bigtime_t currentTime = system_time();
|
||||
if (!optional || ((currentTime - fLastUpdateTime) > kMaxUpdateInterval)) {
|
||||
if (curItem != NULL || fPendingStatusString[0]) {
|
||||
// forced update or past update time
|
||||
|
||||
BString buffer;
|
||||
buffer << fCurItem << " ";
|
||||
|
||||
// if we don't have curItem, take the one from the stash
|
||||
const char *statusItem = curItem != NULL
|
||||
? curItem : fPendingStatusString;
|
||||
|
||||
fStatusBar->Update((float)fItemSize / fTotalSize, statusItem,
|
||||
buffer.String());
|
||||
|
||||
// we already displayed this item, clear the stash
|
||||
fPendingStatusString[0] = '\0';
|
||||
|
||||
fLastUpdateTime = currentTime;
|
||||
} else {
|
||||
// don't have a file to show, just update the bar
|
||||
fStatusBar->Update((float)fItemSize / fTotalSize);
|
||||
}
|
||||
|
||||
if (currentTime
|
||||
>= fLastSpeedReferenceTime + kSpeedReferenceInterval) {
|
||||
// update current speed every kSpeedReferenceInterval
|
||||
fCurrentBytesPerSecondSlot
|
||||
= (fCurrentBytesPerSecondSlot + 1) % kBytesPerSecondSlots;
|
||||
fBytesPerSecondSlot[fCurrentBytesPerSecondSlot]
|
||||
= (double)(fSizeProcessed - fLastSpeedReferenceSize)
|
||||
* 1000000LL / (currentTime - fLastSpeedReferenceTime);
|
||||
fLastSpeedReferenceSize = fSizeProcessed;
|
||||
fLastSpeedReferenceTime = currentTime;
|
||||
fBytesPerSecond = 0.0;
|
||||
for (size_t i = 0; i < kBytesPerSecondSlots; i++) {
|
||||
if (fBytesPerSecondSlot[i] != 0.0)
|
||||
fBytesPerSecond += fBytesPerSecondSlot[i];
|
||||
else {
|
||||
fBytesPerSecond = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fBytesPerSecond != 0.0)
|
||||
fBytesPerSecond /= kBytesPerSecondSlots;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
fItemSize = 0;
|
||||
} else if (curItem != NULL) {
|
||||
// stash away the name of the item we are currently processing
|
||||
// so we can show it when the time comes
|
||||
strncpy(fPendingStatusString, curItem, 127);
|
||||
fPendingStatusString[127] = '0';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,13 +132,22 @@ private:
|
||||
BStatusBar* fStatusBar;
|
||||
off_t fTotalSize;
|
||||
off_t fItemSize;
|
||||
off_t fSizeProcessed;
|
||||
off_t fLastSpeedReferenceSize;
|
||||
int32 fCurItem;
|
||||
int32 fType;
|
||||
BBitmap* fBitmap;
|
||||
BButton* fStopButton;
|
||||
BButton* fPauseButton;
|
||||
thread_id fThread;
|
||||
float fLastUpdateTime;
|
||||
bigtime_t fLastUpdateTime;
|
||||
bigtime_t fLastSpeedReferenceTime;
|
||||
bigtime_t fProcessStartTime;
|
||||
bigtime_t fLastSpeedUpdateTime;
|
||||
static const size_t kBytesPerSecondSlots = 5;
|
||||
size_t fCurrentBytesPerSecondSlot;
|
||||
double fBytesPerSecondSlot[kBytesPerSecondSlots];
|
||||
double fBytesPerSecond;
|
||||
bool fShowCount;
|
||||
bool fWasCanceled;
|
||||
bool fIsPaused;
|
||||
|
Loading…
Reference in New Issue
Block a user