Opened 15 years ago
Last modified 6 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@…, kernja@… |
Description
Attachments (15)
Change History (57)
comment:1 Changed 15 years ago by mvoncken
- Milestone changed from 1.1.0 to 1.2.0
comment:2 Changed 14 years ago by anonymous
comment:3 Changed 14 years ago by s0undt3ch
- Cc ufs@… added
comment:4 Changed 14 years ago by andar
- Milestone changed from 1.2.0 to Future
- Version 1.1.0_dev deleted
comment:5 Changed 13 years ago by James_Kern
- Cc kernja@… 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.
comment:6 Changed 13 years ago by damoxc
Attach a patch so we can have a look at it?
comment:7 Changed 13 years ago by James_Kern
Yea I should've guessed that :)
comment:8 Changed 13 years ago by damoxc
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 Changed 13 years ago by James_Kern
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 Changed 13 years ago by damoxc
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 Changed 13 years ago by andar
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.
Changed 13 years ago by James_Kern
comment:12 Changed 13 years ago by James_Kern
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 Changed 13 years ago by James_Kern
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 Changed 13 years ago by damoxc
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 Changed 13 years ago by damoxc
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; }
comment:16 follow-up: ↓ 18 Changed 13 years ago by 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.
Changed 13 years ago by James_Kern
comment:17 Changed 12 years ago by Cas
- Type changed from feature-request to patch
comment:18 in reply to: ↑ 16 Changed 12 years ago by s0undt3ch
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:19 Changed 12 years ago by s0undt3ch
So, should this be done for 1.4?
comment:20 Changed 12 years ago by s0undt3ch
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 Changed 12 years ago by s0undt3ch
>>> 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 Changed 12 years ago by s0undt3ch
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 Changed 12 years ago by s0undt3ch
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?
comment:24 Changed 12 years ago by s0undt3ch
Still needs a percent complete label added, like the progressbar has.
Changed 12 years ago by s0undt3ch
Small test which muliplies the data available by 100, like show on the previsous screenshot attachment
comment:25 Changed 12 years ago by s0undt3ch
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 Changed 12 years ago by s0undt3ch
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 Changed 12 years ago by James_Kern
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 Changed 12 years ago by s0undt3ch
How about also including an overall progress bar on the bottom? Screenshot attached.
comment:29 follow-up: ↓ 30 Changed 12 years ago by 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.
comment:30 in reply to: ↑ 29 Changed 12 years ago by s0undt3ch
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 Changed 12 years ago by s0undt3ch
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.
comment:32 Changed 12 years ago by shnurapet
Keep it nice and simple, please.
Changed 12 years ago by s0undt3ch
Changed 12 years ago by s0undt3ch
Changed 12 years ago by s0undt3ch
Changed 12 years ago by s0undt3ch
comment:33 Changed 12 years ago by s0undt3ch
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 Changed 12 years ago by s0undt3ch
There's a testing branch now for every one to try and report bugs before merging to master:
Changed 12 years ago by s0undt3ch
Changed 12 years ago by s0undt3ch
comment:35 Changed 12 years ago by s0undt3ch
Final pieces bar screenshots(2)
comment:36 Changed 12 years ago by Cas
- Milestone changed from Future to 1.4.0
- Owner changed from andar to s0undt3ch
- Status changed from new to assigned
- Type changed from patch to feature-request
comment:37 follow-up: ↓ 39 Changed 12 years ago by 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
comment:38 follow-up: ↓ 40 Changed 12 years ago by 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?
comment:39 in reply to: ↑ 37 Changed 12 years ago by s0undt3ch
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 in reply to: ↑ 38 Changed 12 years ago by James_Kern
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 Changed 9 years ago by Cas
- Component changed from GTK-UI to Web-UI
- Owner s0undt3ch deleted
This would be really nice, especially for the individual files view