source: trunk/beos/TRTransfer.cpp @ 2631

Last change on this file since 2631 was 2631, checked in by joshe, 15 years ago

Count "stopping" state as running, not paused.
Display "stopping" state correctly in main window.

  • Property svn:keywords set to Date Rev Author Id
File size: 8.0 KB
Line 
1// $Id: TRTransfer.cpp 2631 2007-08-05 03:31:15Z joshe $
2
3#include "TRTransfer.h"
4
5#include <Font.h>
6
7#include <malloc.h>
8#include <stdio.h>
9
10/**
11 * BListItem that renders Transfer status.
12 */
13TRTransfer::TRTransfer(const char *fullpath, node_ref node, tr_torrent_t *torrentRef) : BListItem(0, false), cachedNodeRef(node) {
14        fBaselineOffset = 0.0f;
15        fLineSpacing = 0.0f;
16        torrent = torrentRef;
17       
18        cachedPath = new BString(fullpath);
19        fStatusLock = new BLocker("Status Locker", true);
20       
21        fStatus = (tr_stat_t*)calloc(1, sizeof(tr_stat_t));
22        const tr_info_t *info = tr_torrentInfo(torrent);
23        fName = new BString("<unknown name>");
24        fName->SetTo(info->name);
25       
26        fBarColor.red = 50;
27        fBarColor.green = 150;
28        fBarColor.blue = 255;
29        fBarColor.alpha = 255;
30       
31        fTimeStr = (char*)calloc(78, sizeof(char));
32        fTransStr = (char*)calloc(78, sizeof(char));
33}
34
35
36TRTransfer::~TRTransfer() {
37        if (fStatusLock->Lock()) {
38                free(fStatus);
39                fStatusLock->Unlock();
40                delete fStatusLock;
41        }
42        delete cachedPath;
43        delete fName;
44}
45
46
47void TRTransfer::Update(BView *owner, const BFont *font) {
48        BListItem::Update(owner, font);
49        SetHeight(BListItem::Height() * 4);
50       
51        font_height height;
52        font->GetHeight(&height);
53       
54        fBaselineOffset = height.leading + height.ascent;
55        fLineSpacing = height.descent;
56}
57
58
59/**
60 * Sets the transfer information to render.
61 * Returns a bool signaling the view is dirty after the update.
62 *
63 * The view is determined to be dirty if the transfer
64 * status, percentDone, eta or the "shade" (even or odd)
65 * position in the list changes from the previous state.
66 * If the tr_stat_t is in fact different then the new, full
67 * status is memcpy'd overtop the existing code.
68 *
69 * This is a thread-safe function, as all writing to the
70 * local fStatus requires a successful Lock on fStatusLock.
71 */
72bool TRTransfer::UpdateStatus(const tr_stat_t *stat, bool shade) {
73        bool dirty = false;
74        if (fStatusLock->Lock()) {
75                if (fStatus->status != stat->status ||
76                    fStatus->percentDone != stat->percentDone ||
77                    fStatus->eta != stat->eta ||
78                    fShade != shade)
79                {
80                        memcpy(fStatus, stat, sizeof(tr_stat_t));
81                        dirty = true;
82                }
83                fStatusLock->Unlock();
84                fShade = shade;
85        }
86        return dirty;
87}
88
89bool TRTransfer::IsRunning() {
90        return (fStatus != NULL && 
91                        (fStatus->status & (TR_STATUS_CHECK_WAIT | TR_STATUS_CHECK |
92                                            TR_STATUS_DOWNLOAD | TR_STATUS_SEED | TR_STATUS_STOPPING)));
93}
94
95
96/**
97 * Renders (Draws) the current status into the BListView.
98 */
99void TRTransfer::DrawItem(BView *owner, BRect frame, bool) {
100        rgb_color col;
101        col.red = 255;
102        col.green = 255;
103        col.blue = 255;
104       
105        owner->PushState();
106       
107        // Draw the background...
108        if (IsSelected()) {
109                owner->SetLowColor(tint_color(col, B_DARKEN_2_TINT));
110        } else if (fShade) {
111                owner->SetLowColor(tint_color(tint_color(col, B_DARKEN_1_TINT), B_LIGHTEN_2_TINT));
112        } else {
113                owner->SetLowColor(col);
114        }
115        owner->FillRect(frame, B_SOLID_LOW);
116       
117        // Draw the informational text...
118        owner->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
119        BPoint textLoc = frame.LeftTop();
120        textLoc.y += (fBaselineOffset / 2);
121        textLoc += BPoint(2, fBaselineOffset);
122       
123        if (fStatus != NULL && fStatusLock->Lock()) {
124                owner->DrawString(fName->String(), textLoc);
125               
126                if (fStatus->status & TR_STATUS_STOPPED ) {
127                        sprintf(fTimeStr, "Paused (%.2f %%)", 100 * fStatus->percentDone);
128                } else if (fStatus->status & TR_STATUS_CHECK_WAIT ) {
129                        sprintf(fTimeStr, "Waiting To Check Existing Files (%.2f %%)",
130                                100 * fStatus->percentDone);
131                } else if (fStatus->status & TR_STATUS_CHECK ) {
132                        sprintf(fTimeStr, "Checking Existing Files (%.2f %%)",
133                                100 * fStatus->percentDone);
134                } else if (fStatus->status & TR_STATUS_DONE ) {
135                        sprintf(fTimeStr, "Done...");
136                } else if (fStatus->status & TR_STATUS_DOWNLOAD) {
137                        if (fStatus->eta < 0 ) {
138                                sprintf(fTimeStr, "--:--:-- Remaining (%.2f %%Complete)",
139                                        100 * fStatus->percentDone);
140                        } else {
141                                sprintf(fTimeStr, "%02d:%02d:%02d Remaining (%.2f %%Complete)",
142                                        fStatus->eta / 3600, (fStatus->eta / 60) % 60,
143                                        fStatus->eta % 60, 100 * fStatus->percentDone);
144                        }
145                } else if (fStatus->status & TR_STATUS_SEED) {
146                        sprintf(fTimeStr, "Seeding");
147                } else if (fStatus->status & TR_STATUS_STOPPING) {
148                        sprintf(fTimeStr, "Stopping...");
149                } else {
150                        fTimeStr[0] = '\0';
151                }
152               
153                textLoc.x = frame.Width() - owner->StringWidth(fTimeStr) - 2;
154                owner->DrawString(fTimeStr, textLoc);
155               
156                if (fStatus->status & (TR_STATUS_DOWNLOAD | TR_STATUS_SEED | TR_STATUS_CHECK | TR_STATUS_CHECK_WAIT )) {
157                        // Move to the left of the bottom line.
158                        textLoc.Set(frame.left + 2, 
159                                    frame.top + fBaselineOffset * 3 + (2 * fLineSpacing) + (fBaselineOffset / 2));
160                        sprintf(fTransStr, "DL: %.2f KB/s (from %i of %i peer%s)",
161                                fStatus->rateDownload, fStatus->peersSendingToUs, fStatus->peersTotal,
162                                (fStatus->peersTotal == 1) ? "" : "s");
163                        owner->DrawString(fTransStr, textLoc);
164                       
165                        sprintf(fTransStr, "UL: %.2f KB/s", fStatus->rateUpload);
166                        textLoc.x = frame.Width() - owner->StringWidth(fTransStr) - 2;
167                        owner->DrawString(fTransStr, textLoc);
168                }
169               
170                /*
171                 * Progress Bar - Mercilessly ripped from the Haiku source code, and
172                 * modified to handle selection tinting, and list item position shading.
173                 */
174                // Custom setup (Transmission Added)
175                BRect rect(frame.left + 2, frame.top + fBaselineOffset + fLineSpacing + (fBaselineOffset / 2),
176                           frame.Width() - 2, frame.top + fBaselineOffset * 2 + fLineSpacing + (fBaselineOffset / 2));
177               
178                // First bevel
179                owner->SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT));
180                if (IsSelected()) {
181                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
182                }
183                owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
184                owner->StrokeLine(BPoint(rect.right, rect.top));
185       
186                owner->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_2_TINT));
187                if (IsSelected()) {
188                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
189                }
190                owner->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom));
191                owner->StrokeLine(BPoint(rect.right, rect.top + 1.0f));
192       
193                rect.InsetBy(1.0f, 1.0f);
194               
195                // Second bevel
196                owner->SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_4_TINT));
197                if (IsSelected()) {
198                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
199                }
200                owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
201                owner->StrokeLine(BPoint(rect.right, rect.top));
202       
203                owner->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
204                if (IsSelected()) {
205                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
206                }
207                owner->StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), BPoint(rect.right, rect.bottom));
208                owner->StrokeLine(BPoint(rect.right, rect.top + 1.0f));
209       
210                rect.InsetBy(1.0f, 1.0f);
211       
212                // Filling
213                owner->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT));
214                if (IsSelected()) {
215                        owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
216                }
217                owner->FillRect(rect);
218       
219                if (fStatus->percentDone != 0.0f) {
220                        rect.right = rect.left + (float)ceil(fStatus->percentDone * (rect.Width() - 4)),
221       
222                        // Bevel
223                        owner->SetHighColor(tint_color(fBarColor, B_LIGHTEN_2_TINT));
224                        if (IsSelected()) {
225                                owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
226                        }
227                        owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top));
228                        owner->StrokeLine(BPoint(rect.right, rect.top));
229       
230                        owner->SetHighColor(tint_color(fBarColor, B_DARKEN_2_TINT));
231                        if (IsSelected()) {
232                                owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
233                        }
234                        owner->StrokeLine(BPoint(rect.left, rect.bottom), BPoint(rect.right, rect.bottom));
235                        owner->StrokeLine(BPoint(rect.right, rect.top));
236       
237                        rect.InsetBy(1.0f, 1.0f);
238       
239                        // Filling
240                        owner->SetHighColor(fBarColor);
241                        if (IsSelected()) {
242                                owner->SetHighColor(tint_color(owner->HighColor(), B_DARKEN_1_TINT));
243                        }
244                        owner->FillRect(rect);
245                }
246               
247                fStatusLock->Unlock();
248        } else {
249                owner->DrawString("loading...", textLoc);
250        }
251       
252        owner->PopState();
253}
Note: See TracBrowser for help on using the repository browser.