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 23static const uint32 kMsgShow = 'show'; 24 25 26ProgressWindow::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 65ProgressWindow::~ProgressWindow() 66{ 67 delete fRunner; 68} 69 70 71void 72ProgressWindow::_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 84void 85ProgressWindow::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 103void 104ProgressWindow::Stop() 105{ 106 BAutolock _(this); 107 108 delete fRunner; 109 fRunner = NULL; 110 111 if (!IsHidden()) 112 Hide(); 113} 114 115 116void 117ProgressWindow::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 break; 149 } 150} 151