1 /* 2 * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "ProgressWindow.h" 8 9 #include <Autolock.h> 10 #include <Button.h> 11 #include <MessageRunner.h> 12 #include <Screen.h> 13 #include <StatusBar.h> 14 15 #include <stdio.h> 16 17 18 static const uint32 kMsgShow = 'show'; 19 20 21 ProgressWindow::ProgressWindow(BWindow* referenceWindow, 22 BMessage* abortMessage) 23 : BWindow(BRect(0, 0, 250, 100), "Progress Monitor", 24 B_MODAL_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL, 25 B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS), 26 fRunner(NULL) 27 { 28 BRect rect = Bounds(); 29 30 BView *view = new BView(rect, NULL, B_FOLLOW_ALL, B_WILL_DRAW); 31 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 32 AddChild(view); 33 34 rect = view->Bounds().InsetByCopy(8, 8); 35 fStatusBar = new BStatusBar(rect, "status", NULL, NULL); 36 float width, height; 37 fStatusBar->GetPreferredSize(&width, &height); 38 fStatusBar->ResizeTo(rect.Width(), height); 39 fStatusBar->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT); 40 view->AddChild(fStatusBar); 41 42 if (abortMessage != NULL && referenceWindow) { 43 rect.top += height + 8; 44 BButton* button = new BButton(rect, "abort", "Abort", 45 abortMessage); 46 button->ResizeToPreferred(); 47 button->MoveBy((rect.Width() - button->Bounds().Width()) / 2, 0); 48 view->AddChild(button); 49 button->SetTarget(referenceWindow); 50 height = button->Frame().bottom; 51 } 52 53 ResizeTo(Bounds().Width(), height + 8); 54 _Center(referenceWindow); 55 Run(); 56 } 57 58 59 ProgressWindow::~ProgressWindow() 60 { 61 delete fRunner; 62 } 63 64 65 void 66 ProgressWindow::_Center(BWindow* referenceWindow) 67 { 68 BRect frame; 69 if (referenceWindow != NULL) 70 frame = referenceWindow->Frame(); 71 else 72 frame = BScreen().Frame(); 73 74 MoveTo(frame.left + (frame.Width() - Bounds().Width()) / 2, 75 frame.top + (frame.Height() - Bounds().Height()) / 2); 76 } 77 78 void 79 ProgressWindow::Start(BWindow* referenceWindow) 80 { 81 BAutolock _(this); 82 83 _Center(referenceWindow); 84 85 if (referenceWindow != NULL) 86 SetWorkspaces(referenceWindow->Workspaces()); 87 88 fRetrievedUpdate = false; 89 fRetrievedShow = false; 90 delete fRunner; 91 92 BMessage show(kMsgShow); 93 fRunner = new BMessageRunner(this, &show, 1000000, 1); 94 } 95 96 97 void 98 ProgressWindow::Stop() 99 { 100 BAutolock _(this); 101 102 delete fRunner; 103 fRunner = NULL; 104 105 if (!IsHidden()) 106 Hide(); 107 } 108 109 110 void 111 ProgressWindow::MessageReceived(BMessage *message) 112 { 113 switch (message->what) { 114 case kMsgShow: 115 if (fRetrievedUpdate && IsHidden()) { 116 Show(); 117 Minimize(false); 118 } 119 120 fRetrievedShow = true; 121 break; 122 123 case kMsgProgressStatusUpdate: 124 float percent; 125 if (message->FindFloat("percent", &percent) == B_OK) 126 fStatusBar->Update(percent - fStatusBar->CurrentValue()); 127 128 const char *text; 129 if (message->FindString("message", &text) == B_OK) 130 fStatusBar->SetText(text); 131 132 fRetrievedUpdate = true; 133 134 if (fRetrievedShow && IsHidden()) { 135 Show(); 136 Minimize(false); 137 } 138 break; 139 140 default: 141 BWindow::MessageReceived(message); 142 } 143 } 144 145