kuuko pushed a commit to branch master.

http://git.enlightenment.org/apps/epour.git/commit/?id=a3b8af7d4dce795f4eb432759059d4c1f5cc2aa5

commit a3b8af7d4dce795f4eb432759059d4c1f5cc2aa5
Author: Kai Huuhko <[email protected]>
Date:   Thu Jul 10 02:13:11 2014 +0300

    Make block graph a widget, have it update
---
 epour/gui/Widgets.py  | 117 ++++++++++++++++++++++++++++++++++++++++++++++++--
 epour/gui/__init__.py |  81 +++++++++++-----------------------
 2 files changed, 138 insertions(+), 60 deletions(-)

diff --git a/epour/gui/Widgets.py b/epour/gui/Widgets.py
index 6262558..2495fb1 100644
--- a/epour/gui/Widgets.py
+++ b/epour/gui/Widgets.py
@@ -1,3 +1,4 @@
+from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL, Rectangle
 from efl.ecore import Timer
 from efl.elementary.box import Box
 from efl.elementary.spinner import Spinner
@@ -6,11 +7,16 @@ from efl.elementary.label import Label
 from efl.elementary.notify import Notify
 from efl.elementary.popup import Popup
 from efl.elementary.button import Button
+from efl.elementary.grid import Grid
 
-EXPAND_BOTH = 1.0, 1.0
-EXPAND_HORIZ = 1.0, 0.0
-FILL_BOTH = -1.0, -1.0
-FILL_HORIZ = -1.0, 0.5
+EXPAND_BOTH = EVAS_HINT_EXPAND, EVAS_HINT_EXPAND
+EXPAND_HORIZ = EVAS_HINT_EXPAND, 0.0
+FILL_BOTH = EVAS_HINT_FILL, EVAS_HINT_FILL
+FILL_HORIZ = EVAS_HINT_FILL, 0.5
+
+
+def chunker(seq, size):
+    return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))
 
 
 class UnitSpinner(Box):
@@ -122,3 +128,106 @@ class ConfirmExit(object):
         b.callback_clicked_add(lambda x: n.delete())
         n.part_content_set("button2", b)
         n.show()
+
+
+class BlockGraph(Grid):
+
+    colors = (
+        (255, 0, 0, 255),
+        (255, 255, 0, 255),
+        (0, 255, 0, 255)
+    )
+
+    def __init__(self, parent, pieces, num_complete_pieces=0, *args, **kwargs):
+
+        self.num_complete_pieces = num_complete_pieces
+
+        self._blocks = None
+        self._block_size = None
+        self.rects = []
+
+        super(self.__class__, self).__init__(parent, *args, **kwargs)
+
+        self.pieces = pieces
+        self.num_total_pieces = len(pieces)
+
+        self.pack_rects()
+
+    def block_size_get(self):
+        if self._block_size is not None:
+            return self._block_size
+
+        width, height = self.size
+        num_pieces = self.num_total_pieces
+        grid_size = width * height
+        block_size = \
+            num_pieces//grid_size + bool(num_pieces % grid_size)
+
+        self._block_size = block_size
+        return block_size
+
+    block_size = property(block_size_get)
+
+    def blocks_get(self):
+        if self._blocks is not None:
+            return self._blocks
+
+        blocks = []
+
+        for block in chunker(self.pieces, self.block_size):
+            if all(block):
+                blocks.append(2)
+            elif any(block):
+                blocks.append(1)
+            else:
+                blocks.append(0)
+
+        self._blocks = blocks
+        return blocks
+
+    blocks = property(blocks_get)
+
+    def pack_rects(self):
+        blocks = self.blocks
+        width, height = self.size
+        len_blocks = len(blocks)
+
+        p = 0
+        for y in xrange(height):
+            for x in xrange(width):
+                if p >= len_blocks:
+                    continue
+                else:
+                    block = blocks[p]
+                    if block == 0:
+                        color = self.colors[0]
+                    elif block == 1:
+                        color = self.colors[1]
+                    else:
+                        color = self.colors[2]
+
+                rect = Rectangle(self.evas, color=color)
+                self.rects.append(rect)
+                self.pack(rect, x, y, 1, 1)
+                rect.show()
+                p += 1
+
+    def update(self, pieces):
+        width, height = self.size
+        old_blocks = self.blocks
+        self.pieces = pieces
+        self._blocks = None
+        new_blocks = self.blocks
+        row = 0
+        col = 0
+        for ov, nv in zip(old_blocks, new_blocks):
+            if ov != nv:
+                self.rects[(row * width) + col].color = self.colors[nv]
+
+            if (col + 1) >= width:
+                row += 1
+                col = 0
+            else:
+                col += 1
+
+        return True
diff --git a/epour/gui/__init__.py b/epour/gui/__init__.py
index 93ec847..9d4cce1 100644
--- a/epour/gui/__init__.py
+++ b/epour/gui/__init__.py
@@ -42,9 +42,8 @@ from efl.elementary.table import Table
 from efl.elementary.menu import Menu
 from efl.elementary.configuration import Configuration
 from efl.elementary.toolbar import Toolbar, ELM_TOOLBAR_SHRINK_NONE
-from efl.elementary.grid import Grid
 
-from Widgets import ConfirmExit, Error, Information
+from Widgets import ConfirmExit, Error, Information, BlockGraph
 
 from intrepr import intrepr
 
@@ -59,10 +58,6 @@ scale = elm_conf.scale
 log = logging.getLogger("epour.gui")
 
 
-def chunker(seq, size):
-    return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))
-
-
 class MainInterface(object):
     def __init__(self, parent, session):
         self.parent = parent
@@ -593,7 +588,7 @@ class TorrentTooltip(Table):
 
         Table.__init__(self, parent, size_hint_weight=EXPAND_BOTH)
 
-        s = h.status()
+        s = h.status(8)
 
         value_labels = []
 
@@ -611,65 +606,39 @@ class TorrentTooltip(Table):
 
         i += 1
 
-        l = Label(self, text="Pieces")
+        l = Label(self)
         self.pack(l, 0, i, 1, 1)
         l.show()
 
         WIDTH = 30
         HEIGHT = 4
-        TOTAL = WIDTH * HEIGHT
-
-        pieces = s.pieces
-        len_pieces = len(pieces)
-        block_size = len_pieces//TOTAL + bool(len_pieces % TOTAL)
-
-        g = Grid(self, size=(WIDTH, HEIGHT), size_hint_align=FILL_BOTH)
 
-        blocks = []
+        g = BlockGraph(
+            self, s.pieces, s.num_pieces,
+            size=(WIDTH, HEIGHT), size_hint_align=FILL_BOTH
+            )
 
-        for block in chunker(pieces, block_size):
-            if all(block):
-                blocks.append(2)
-            elif any(block):
-                blocks.append(1)
-            else:
-                blocks.append(0)
-
-        len_blocks = len(blocks)
-
-        p = 0
-        for y in xrange(HEIGHT):
-            for x in xrange(WIDTH):
-                if p >= len_blocks:
-                    continue
-                else:
-                    block = blocks[p]
-                    if block == 0:
-                        color = 255, 0, 0
-                    elif block == 1:
-                        color = 255, 255, 0
-                    else:
-                        color = 0, 255, 0
-
-                rect = Rectangle(g.evas, color=color)
-                g.pack(rect, x, y, 1, 1)
-                rect.show()
-                p += 1
+        l.text = "Pieces (scaled 1:%d)" % g.block_size
 
         self.pack(g, 1, i, 1, 1)
         g.show()
 
-        def update_labels(h, items, value_labels):
-            s = h.status()
-            for i, l in enumerate(value_labels):
-                conv, attr_name = items[i][1:]
-                v = getattr(s, attr_name)
-                if conv:
-                    v = conv(v)
-                l.text = str(v)
-            return True
+        self.timer = Timer(1.0, self.update, h, self.items, value_labels, g)
+        self.on_del_add(lambda x: self.timer.delete())
 
-        # TODO: Update block graph
+    @staticmethod
+    def update(h, items, value_labels, g):
+        s = h.status(8)
+        for i, l in enumerate(value_labels):
+            conv, attr_name = items[i][1:]
+            v = getattr(s, attr_name)
+            if conv:
+                v = conv(v)
+            l.text = str(v)
 
-        self.timer = Timer(1.0, update_labels, h, self.items, value_labels)
-        self.on_del_add(lambda x: self.timer.delete())
+        num_pieces = s.num_pieces
+        if g.num_complete_pieces != num_pieces:
+            g.update(s.pieces)
+            g.num_complete_pieces = num_pieces
+
+        return True

-- 


Reply via email to