source: trunk/beos/TRTransfer.cpp @ 243

Last change on this file since 243 was 14, checked in by root, 16 years ago

Update 2005-12-13

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