Make {,back}space pan between the edges of a zoomed page.
[automanga.git] / manga / reader.py
index c5507ee..b753042 100644 (file)
@@ -1,4 +1,4 @@
-import threading, gtk, gio, gobject
+import threading, gtk, gobject
 import lib, profile
 
 class notdone(Exception): pass
@@ -75,23 +75,22 @@ class imgload(future):
         self.start()
 
     def value(self):
-        buf = bytearray()
-        with self.page.open() as st:
-            self.p = 0
-            self.st = st
-            while True:
-                read = st.read(1024)
-                if read == "":
-                    break
-                self.p += len(read)
-                buf.extend(read)
-                self.progcb()
-        self.st = None
-        with gtk.gdk.lock:
-            try:
-                return gtk.gdk.pixbuf_new_from_stream(gio.memory_input_stream_new_from_data(str(buf)))
-            finally:
-                gtk.gdk.flush()
+        buf = gtk.gdk.PixbufLoader()
+        try:
+            with self.page.open() as st:
+                self.p = 0
+                self.st = st
+                while True:
+                    read = st.read(1024)
+                    if read == "":
+                        break
+                    self.p += len(read)
+                    buf.write(read)
+                    self.progcb()
+            self.st = None
+        finally:
+            buf.close()
+        return buf.get_pixbuf()
 
     @property
     def prog(self):
@@ -296,11 +295,12 @@ class msgproc(object):
         self._prog = None
 
     def prog(self, p):
-        if p is not None and self._prog is None:
-            self._prog = gtk.ProgressBar()
+        if p is not None:
+            if self._prog is None:
+                self._prog = gtk.ProgressBar()
+                self.hlay.pack_start(self._prog, padding=5)
+                self._prog.show()
             self._prog.set_fraction(p)
-            self.hlay.pack_start(self._prog, padding=5)
-            self._prog.show()
         elif p is None and self._prog is not None:
             self.hlay.remove(self._prog)
             self._prog = None
@@ -462,6 +462,22 @@ class sbox(gtk.ComboBox):
     def changed_cb(self, wdg, data=None):
         self.rd.fetchpage(pageget(self.pnode[self.get_active()]))
 
+class profprop(object):
+    def __init__(self, key, default=None):
+        self.key = key
+        self.default = default
+
+    def __get__(self, ins, cls):
+        return ins.profile.props.get(self.key, self.default)
+
+    def __set__(self, ins, val):
+        ins.profile.props[self.key] = val
+        ins.profile.save()
+
+    def __delete__(self, ins):
+        del ins.profile.props[self.key]
+        ins.profile.save()
+
 class reader(gtk.Window):
     def __init__(self, manga, prof=None):
         super(reader, self).__init__(gtk.WINDOW_TOPLEVEL)
@@ -505,12 +521,15 @@ class reader(gtk.Window):
         self.add(vlay)
         vlay.show()
 
-        if "curpage" in self.profile.props:
-            self.fetchpage(idpageget(self.manga, self.profile.props["curpage"]))
+        if self.curpage is not None:
+            self.fetchpage(idpageget(self.manga, self.curpage))
         else:
             self.fetchpage(pageget(self.manga))
         self.updtitle()
 
+    zmode = profprop("zmode", "fit")
+    curpage = profprop("curpage")
+
     def updpagelbl(self):
         if self.page is None:
             self.pagelbl.set_text("")
@@ -540,6 +559,9 @@ class reader(gtk.Window):
             self.page = None
         if img is not None:
             self.page = pageview(img)
+            if self.zmode == "1":
+                self.page.set_zoom(1)
+                self.page.set_off((0, 0))
             self.pfr.add(self.page)
             self.page.show()
         self.updpagelbl()
@@ -548,8 +570,7 @@ class reader(gtk.Window):
         if self.point is not None:
             self.point = None
         if page is not None:
-            self.profile.props["curpage"] = page.idlist()
-            self.profile.save()
+            self.curpage = page.idlist()
             self.point = ccursor(page, self.cache)
             self.imgfetch.set(imgfetch(self.cache[page]))
         else:
@@ -588,8 +609,10 @@ class reader(gtk.Window):
         if self.page is not None:
             if ev.keyval in [ord('O'), ord('o')]:
                 self.zoom = 1.0
+                self.zmode = "1"
             elif ev.keyval in [ord('P'), ord('p')]:
                 self.zoom = None
+                self.zmode = "fit"
             elif ev.keyval in [ord('[')]:
                 self.zoom = min(self.zoom * 1.25, 3)
             elif ev.keyval in [ord(']')]:
@@ -612,9 +635,15 @@ class reader(gtk.Window):
                 self.page.set_off((self.page.get_asize()[0], self.page.off[1]))
         if self.point is not None:
             if ev.keyval in [ord(' ')]:
-                self.fetchpage(self.point.next, lambda page: self.preload.set(preload(relpageget(page, False, self.cache))))
+                if self.page and self.page.off[1] + self.page.get_asize()[1] < self.page.get_zsize()[1]:
+                    self.pan((0, self.page.get_asize()[1] - 50))
+                else:
+                    self.fetchpage(self.point.next, lambda page: self.preload.set(preload(relpageget(page, False, self.cache))))
             elif ev.keyval in [65288]:
-                self.fetchpage(self.point.prev, lambda page: self.preload.set(preload(relpageget(page, True, self.cache))))
+                if self.page and self.page.off[1] > 0:
+                    self.pan((0, -(self.page.get_asize()[1] - 50)))
+                else:
+                    self.fetchpage(self.point.prev, lambda page: self.preload.set(preload(relpageget(page, True, self.cache))))
             elif ev.keyval in [ord('R'), ord('r')]:
                 page = self.point.cur.cur
                 del self.cache[page]