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 _Center(referenceWindow); 83 84 fRetrievedUpdate = false; 85 fRetrievedShow = false; 86 delete fRunner; 87 88 BMessage show(kMsgShow); 89 fRunner = new BMessageRunner(this, &show, 1000000, 1); 90 } 91 92 93 void 94 ProgressWindow::Stop() 95 { 96 BAutolock _(this); 97 98 delete fRunner; 99 fRunner = NULL; 100 101 if (!IsHidden()) 102 Hide(); 103 } 104 105 106 void 107 ProgressWindow::MessageReceived(BMessage *message) 108 { 109 switch (message->what) { 110 case kMsgShow: 111 if (fRetrievedUpdate && IsHidden()) { 112 Show(); 113 Minimize(false); 114 } 115 116 fRetrievedShow = true; 117 break; 118 119 case kMsgProgressStatusUpdate: 120 float percent; 121 if (message->FindFloat("percent", &percent) == B_OK) 122 fStatusBar->Update(percent - fStatusBar->CurrentValue()); 123 124 const char *text; 125 if (message->FindString("message", &text) == B_OK) 126 fStatusBar->SetText(text); 127 128 fRetrievedUpdate = true; 129 130 if (fRetrievedShow && IsHidden()) { 131 Show(); 132 Minimize(false); 133 } 134 break; 135 136 default: 137 BWindow::MessageReceived(message); 138 } 139 } 140 141