Opened 16 years ago
Last modified 7 years ago
#378 assigned feature-request
Advanced (pieces) progress bar
Reported by: | andar | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 2.x |
Component: | Web UI | Version: | |
Keywords: | Cc: | ufs@ufsoft.org, kernja@earlham.edu |
Description
Attachments (15)
Change History (57)
comment:1 by , 16 years ago
Milestone: | 1.1.0 → 1.2.0 |
---|
comment:2 by , 15 years ago
comment:3 by , 15 years ago
Cc: | added |
---|
comment:4 by , 15 years ago
Milestone: | 1.2.0 → Future |
---|---|
Version: | 1.1.0_dev |
comment:5 by , 15 years ago
Cc: | added |
---|
To get a feel for the code base, I've swapped out the progress bar in the status tab with a bar that shows you the status of each piece in the torrent. Not sure on how to go about getting this merged back in though.
by , 15 years ago
Attachment: | pieces_bar.patch added |
---|
patch for adding pieces bar to status tab, against 1.2.1
comment:8 by , 15 years ago
Looks good, although I would change it to return None rather than an empty list, and merge line 486 and 487 so you end up with:
def get_pieces_status(self): if not self.handle.has_metadata(): return None return self.handle.status().pieces
Returning None rather than an empty list is less expensive.
andar do you have any thoughts?
comment:9 by , 15 years ago
bleck, noticed a couple problems. The bar expands to fill the vertical space when the panel is expanded, which looks ugly. Also when a torrent has more pieces than there are pixels wide, the bar shows up as empty. The first shouldn't be too bad, but not sure how easy the second one will be to fix.
comment:10 by , 15 years ago
The first issue can be solved with a gtk setting, can't remember which one it is off the top of my head but widgets can be set to not auto-expand.
As for the second, the only solution I can think of would be to start dropping pieces, or merge pieces together and average, so
if piece_count > bar_width: _pieces = pieces[:] pieces = [] while _pieces: one = _pieces.pop(0) two = _pieces.pop(0) # do calc pieces.append(one + two / 2)
That is of course pseudo code just to give a general idea of what I was saying.
comment:11 by , 15 years ago
You could also change the progress bar to a progress grid if you do not have enough space. This would basically split up the vertical space so you can gain some additional rows without losing any piece information by dropping or merging pieces.
by , 15 years ago
Attachment: | pieces_bar_2.patch added |
---|
comment:12 by , 15 years ago
Ok, fixed the expansion issue at the cost of the height being fixed now. For the other issue I went with grouping the pieces like damoxc suggested. It does lose a little bit of information versus using a grid where you can fit more pieces, but I think it still gives a close enough approximation. Also you could still potentially run into the same issue using the grid if a torrent had more pieces then pixels in the bar (unlikely as that may be).
comment:13 by , 14 years ago
Do you guys have any thoughts on how to do this in the web ui? Looked through the ExtJS docs and didn't see anything promising on first glance. Next thought is to generate an image server-side using cairo.
comment:14 by , 14 years ago
Nah should do this client side, less load you can place on the web server the better.
Could build something along the lines of:
<div class="x-piecesbar-wrapper"> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece"></div> <div class="x-piecesbar-piece"></div> <div class="x-piecesbar-piece"></div> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece"></div> <div class="x-piecesbar-piece"></div> <div class="x-piecesbar-piece x-piece-complete"></div> <div class="x-piecesbar-piece"></div> ... </div>
This should be built up via a class named Deluge.Piecesbar that extends from Ext.BoxComponent.
comment:15 by , 14 years ago
Oh and the css would be something like:
.x-piecesbar-piece { display: inline; /* or float: left; */ color: #fff; width: 1px; } .x-piece-complete { color: #000; }
follow-up: 18 comment:16 by , 14 years ago
Been a little while, but was bored over the weekend so finally took a stab at implementing this for the WebUI as well. Attached a patch against git trunk.
Only concern right now is that it's a little slow on torrents with lots of pieces (i.e. more than 1000). Doesn't seem to be much of a problem on chrome, but firefox is a little laggy when switching between torrents. I think the problem is clearing all the <div>'s, but not sure of any more efficient way of doing that.
by , 14 years ago
Attachment: | piecesbar_gtk_js.patch added |
---|
comment:17 by , 14 years ago
Type: | feature-request → patch |
---|
comment:18 by , 14 years ago
Replying to James_Kern:
Been a little while, but was bored over the weekend so finally took a stab at implementing this for the WebUI as well. Attached a patch against git trunk.
Only concern right now is that it's a little slow on torrents with lots of pieces (i.e. more than 1000). Doesn't seem to be much of a problem on chrome, but firefox is a little laggy when switching between torrents. I think the problem is clearing all the <div>'s, but not sure of any more efficient way of doing that.
How about drawing on a canvas?
comment:20 by , 13 years ago
Ppl, I'm trying to extend the pieces information. Ie, each piece should have 4 states:
- 0 - Missing
- 1 - Present but not downloaded
- 2 - Downloading
- 3 - Downloaded
So far I've managed to build this information, but, I'm at the end of my night shift and my head is getting too tired. How can I adapt the reduce function to this?
Here's an example list:
[3, 2, 1, 1, 1, 0, 0, 2, 0, 1, 0, 2, 0, 2, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 2, 1, 0, 2, 1, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 2, 0, 2, 2, 2, 0, 2, 2, 1]
comment:21 by , 13 years ago
>>> x = [3, 2, 1, 1, 1, 0, 0, 2, 0, 1, 0, 2, 0, 2, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 2, 1, 0, 2, 1, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 2, 0, 2, 2, 2, 0, 2, 2, 1] >>> t = len(x)*1.0 >>> xx = [] >>> v = x.pop(0) >>> n = 1 >>> while True: ... if not x: ... break ... vv = x.pop(0) ... if vv == v: ... n += 1 ... else: ... xx.append(n/t) ... n = 1 ... >>> xx [0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.051724137931034482, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827, 0.017241379310344827] >>> len(xx) 55 >>> t 58.0 >>>
Didn't reduce that much, but the data was not helping much too ;)
Is this the way to go?
The final values and width percentages, considering 58 is 100%
comment:22 by , 13 years ago
Actually:
>>> x = [3, 2, 1, 1, 1, 0, 0, 2, 0, 1, 0, 2, 0, 2, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0, ... 2, 0, 0, 2, 2, 1, 0, 2, 1, 0, 1, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 3, 0, ... 0, 2, 0, 2, 2, 2, 0, 2, 2, 1] >>> t = len(x)*1.0 >>> xx = [] >>> v = None >>> n = None >>> >>> while True: ... if not x: ... break ... if v is None: ... v = x.pop(0) ... n = 1 ... else: ... vv = x.pop(0) ... if v == vv: ... n += 1 ... else: ... xx.append((v, n/t)) ... v = vv ... n = 1 ... >>> >>> >>> print xx [(3, 0.017241379310344827), (2, 0.017241379310344827), (1, 0.051724137931034482), (0, 0.034482758620689655), (2, 0.017241379310344827), (0, 0.017241379310344827), (1, 0.017241379310344827), (0, 0.017241379310344827), (2, 0.017241379310344827), (0, 0.017241379310344827), (2, 0.017241379310344827), (1, 0.017241379310344827), (0, 0.017241379310344827), (2, 0.017241379310344827), (0, 0.051724137931034482), (2, 0.017241379310344827), (0, 0.051724137931034482), (2, 0.017241379310344827), (0, 0.034482758620689655), (2, 0.034482758620689655), (1, 0.017241379310344827), (0, 0.017241379310344827), (2, 0.017241379310344827), (1, 0.017241379310344827), (0, 0.017241379310344827), (1, 0.034482758620689655), (0, 0.034482758620689655), (2, 0.017241379310344827), (0, 0.10344827586206896), (3, 0.034482758620689655), (0, 0.034482758620689655), (2, 0.017241379310344827), (0, 0.017241379310344827), (2, 0.051724137931034482), (0, 0.017241379310344827), (2, 0.034482758620689655)] >>> print len(xx) 36 >>>
comment:23 by , 13 years ago
Here's a GTK example, nevermind the colors used ;)
import pygtk pygtk.require('2.0') import gtk class PiecesBar(gtk.DrawingArea): def __init__(self): gtk.DrawingArea.__init__(self) self.width = 0 self.height = 0 self.pieces = [] self.connect('size-allocate', self.on_size_allocate) self.connect('expose-event', self.update) self.connect('realize', self.on_realize) self.show() def on_realize(self, widget): map = widget.get_colormap() done_color = map.alloc_color("#325891") down_color = map.alloc_color("#67DB63") wait_color = map.alloc_color("#EBF57A") miss_color = map.alloc_color("#FF4D36") outline_color = map.alloc_color("#888888") self.colors = { 0: widget.window.new_gc(foreground=miss_color), 1: widget.window.new_gc(foreground=wait_color), 2: widget.window.new_gc(foreground=down_color), 3: widget.window.new_gc(foreground=done_color) } self.gc_done = widget.window.new_gc(foreground=done_color) self.gc_down = widget.window.new_gc(foreground=down_color) self.gc_wait = widget.window.new_gc(foreground=wait_color) self.gc_miss = widget.window.new_gc(foreground=miss_color) self.gc_outline = widget.window.new_gc(foreground=outline_color) def on_size_allocate(self, widget, size): self.width = size.width self.height = size.height def update(self, widget=None, event=None): num_pieces = len(self.pieces) if num_pieces < 1: self.clear() return None self.window.draw_rectangle(self.gc_outline, False, 0, 0, self.width - 1, self.height - 1) width = self.width - 2 pieces = self.collapse_pieces() start_pos = 1 for state, wpercent in pieces: print state, wpercent pwidth = width*wpercent print 1, pwidth self.draw_piece(state, start_pos, 1, pwidth, self.height - 2) start_pos += pwidth def collapse_pieces(self): num_pieces = len(self.pieces)*1.0 opieces = self.pieces[:] npieces = [] v = None n = None while True: if not opieces: break if v is None: v = opieces.pop(0) n = 1 else: vv = opieces.pop(0) if v == vv: n += 1 else: npieces.append((v, n/num_pieces)) v = vv n = 1 return npieces def draw_piece(self, piece, start_x, start_y, width, height): self.window.draw_rectangle( self.colors[piece], True, start_x, start_y, width, height ) def clear(self): self.pieces = [0] self.update() def get_text(self): return "" def set_text(self, text): pass pieces = PiecesBar() pieces.pieces = [3, 2, 1, 1, 1, 0, 0, 2, 0, 1, 0, 2, 2, 2, 1, 2, 2, 0, 0, 0, 2, 1, 1, 1, 2, 0, 0, 2, 2, 1, 0, 2, 1, 0, 1, 1, 0, 0, 2, 3, 3, 3, 3, 3, 0, 3, 3, 0, 0, 2, 0, 2, 2, 2, 0, 2, 2, 1] window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.add(pieces) window.show_all() gtk.main()
How about this?
by , 13 years ago
Attachment: | pieces_test.py added |
---|
Small test which muliplies the data available by 100, like show on the previsous screenshot attachment
comment:25 by , 13 years ago
Using cairo, like shown on the attached pieces_test.py, not data is lost, and event if there's huge amount of pieces for a really small space, all data will be shown. The pieces are only collapsed to reduce the number of rectangle draws. I like this approach much better. How about it? I'll take up the GTK part of the task of this is accepted.
comment:26 by , 13 years ago
By the way, this is partially done on a local branch. I'll upload it to deluge's git if there's interest.
comment:27 by , 13 years ago
The cairo approach is nice! For the web side of this we'd have to change to using canvas, since I think that's the only way to support using floats for width. I took a first pass at it and it didn't seem too hard to switch to. If there's actual interest in getting this in I'll commit to doing that part.
comment:28 by , 13 years ago
How about also including an overall progress bar on the bottom? Screenshot attached.
follow-up: 30 comment:29 by , 13 years ago
I don't think the progress bar is really necessary, since there's one shown above in the main torrent list. The bar is already a pretty busy area visually so I'd prefer not add something else to it too.
comment:30 by , 13 years ago
Replying to James_Kern:
I don't think the progress bar is really necessary, since there's one shown above in the main torrent list. The bar is already a pretty busy area visually so I'd prefer not add something else to it too.
My idea for this pieces bar is to either show the progress bar in the torrent list, or, show the pieces bar. Not both. In the torrent details, I'm open for discussion, same behavior?
comment:31 by , 13 years ago
Now, I see. The original patch was just for the status tab :) Well, what I'm after is to replace the dull progress bar with the pieces bar.
by , 13 years ago
Attachment: | with-progress-bar1.png added |
---|
by , 13 years ago
Attachment: | with-progress-bar2.png added |
---|
by , 13 years ago
Attachment: | with-progress-bar3.png added |
---|
by , 13 years ago
Attachment: | with-progress-bar4.png added |
---|
comment:33 by , 13 years ago
The last 4 screenshots attached, with-progress-barX.png
, show the current status of the implementation, and removes the need to have the regular progress bar above the pieces bar.
comment:34 by , 13 years ago
There's a testing branch now for every one to try and report bugs before merging to master:
by , 13 years ago
Attachment: | final-progress-bar.png added |
---|
by , 13 years ago
Attachment: | final-progress-bar1.png added |
---|
comment:36 by , 13 years ago
Milestone: | Future → 1.4.0 |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Type: | patch → feature-request |
follow-up: 39 comment:37 by , 13 years ago
I've mostly ported the new implementation to the web ui (haven't looked into hooking it into the preferences) on the pieces-progress-bar branch. Don't know how to push changes back up using git (or if I should even) so I'm attaching a patch here instead
follow-up: 40 comment:38 by , 13 years ago
Excellent thanks, I'm currently in the progress of migrating master to extjs4 (extjs4-port on git) so once I've done that I will integrate your patch!
I might modify it a little bit to change it into a widget so it can be used else where if anyone wants to in a plugin or something if that's okay?
comment:39 by , 13 years ago
Replying to James_Kern:
I've mostly ported the new implementation to the web ui (haven't looked into hooking it into the preferences) on the pieces-progress-bar branch. Don't know how to push changes back up using git (or if I should even) so I'm attaching a patch here instead
Great Stuff!
comment:40 by , 13 years ago
Replying to damoxc:
Excellent thanks, I'm currently in the progress of migrating master to extjs4 (extjs4-port on git) so once I've done that I will integrate your patch!
I might modify it a little bit to change it into a widget so it can be used else where if anyone wants to in a plugin or something if that's okay?
Yea, absolutely. If you need any help with the extjs4 port I'd be happy to lend a hand
comment:41 by , 10 years ago
Component: | GTK-UI → Web-UI |
---|---|
Owner: | removed |
This would be really nice, especially for the individual files view