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