source: trunk/beos/TRTransfer.cpp @ 1125

Last change on this file since 1125 was 261, checked in by titer, 16 years ago

Updated svn:keywords

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