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