OSDN Git Service

Simple popup res view is implemented. (#16088)
authorAiwota Programmer <aiwotaprog@tetteke.tk>
Sat, 18 Apr 2009 10:28:35 +0000 (19:28 +0900)
committerAiwota Programmer <aiwotaprog@tetteke.tk>
Sat, 18 Apr 2009 10:28:35 +0000 (19:28 +0900)
src/FukuiNoNamari/thread_popup.py [new file with mode: 0644]
src/FukuiNoNamari/thread_view.py
src/FukuiNoNamari/thread_window.py

diff --git a/src/FukuiNoNamari/thread_popup.py b/src/FukuiNoNamari/thread_popup.py
new file mode 100644 (file)
index 0000000..4156246
--- /dev/null
@@ -0,0 +1,146 @@
+
+import gtk
+import gobject
+import re
+import urlparse
+import copy
+import thread_view
+
+class ThreadPopup:
+    '''
+    classdocs
+    '''
+
+    _INTERVAL = 100
+
+    def __init__(self, bbs_type):
+        self._thread_view_list = []
+        self._bbs_type = bbs_type
+        self._timer_started = False
+
+    def push_thread_view(self, threadview):
+        threadview.connect("cursor-over-link-event", self.on_cursor_over_link)
+        self._thread_view_list.append(threadview)
+
+    def pop_thread_view(self):
+        view = self._thread_view_list.pop()
+        top = view.get_toplevel()
+        top.destroy()
+
+    def _collapse(self, threadview):
+        length = len(self._thread_view_list)
+        for idx in range(length):
+            idx = length - idx - 1
+            view = self._thread_view_list[idx]
+            if view == threadview:
+                break
+            self.pop_thread_view()
+
+    def _is_thread_view_top(self, threadview):
+        listnum = len(self._thread_view_list)
+        if listnum == 0:
+            return False
+        last = self._thread_view_list[listnum-1]
+        return threadview == last
+
+    def on_cursor_over_link(self, widget, event, uri):
+        orig_uri = uri
+        if not uri.startswith("http://"):
+            # maybe a relative uri.
+            uri = urlparse.urljoin(self._bbs_type.get_uri_base(), uri)
+
+        strict_uri = self._bbs_type.get_thread_uri()
+        idx = self._thread_view_list.index(widget)
+        if idx != len(self._thread_view_list)-1 and orig_uri == self._thread_view_list[idx+1].get_toplevel().uri:
+            return
+        if uri != strict_uri and uri.startswith(strict_uri):
+            resnum = uri[len(strict_uri):]
+            match = re.match("\d+", resnum)
+            if match:
+                resnum = int(match.group())
+                if self._check_to_need_hint(widget, resnum):
+                    self._show_hint(widget, resnum, orig_uri)
+
+    def _get_owner(self, gdk_win):
+        top = gdk_win.get_toplevel()
+        for threadview in self._thread_view_list:
+            if threadview.window.get_toplevel() == top:
+                return threadview
+        return None
+
+    def on_timeout(self):
+        ret = gtk.gdk.window_at_pointer()
+        if ret is None:
+            # print "unknown window"
+            self._collapse(self._thread_view_list[0])
+            self._timer_started = False
+            return False
+
+        gdk_win, x, y = ret
+        threadview = self._get_owner(gdk_win)
+        if threadview is None:
+            # print "unknown gdk window"
+            self._collapse(self._thread_view_list[0])
+            self._timer_started = False
+            return False
+
+        length = len(self._thread_view_list)
+        if length == 1:
+            # print "no popup window"
+            self._collapse(threadview)
+            self._timer_started = False
+            return False
+
+        if self._is_thread_view_top(threadview):
+            return True
+
+        uri, layout, element = threadview.ptrpos_to_uri(x, y)
+        view = self._thread_view_list[self._thread_view_list.index(threadview)+1]           
+        if layout is None or uri is None or uri != view.get_toplevel().uri:
+            self._collapse(threadview)
+
+        return True
+
+    def _show_hint(self, threadview, num, uri):
+        top = threadview.get_toplevel()
+        relative_x, relative_y = top.get_pointer()
+        gdk_win_x, gdk_win_y = top.window.get_origin()
+        abs_x = gdk_win_x + relative_x
+        abs_y = gdk_win_y + relative_y
+        popupwin = gtk.Window(gtk.WINDOW_POPUP)
+        popupwin.move(abs_x, abs_y)
+        view = thread_view.ThreadView()
+        self.push_thread_view(view)
+        for layout in self._thread_view_list[0].res_layout_list:
+            if layout.resnum == num:
+                clone = layout.clone()
+                view.add_layout(clone)             
+        popupwin.view = view
+        popupwin.uri = uri
+        popupwin.add(view)
+        popupwin.set_property("border_width", 1)
+
+
+        def on_value_changed(widget, popupwin):
+            width, height = popupwin.get_size()
+            if height == widget.upper:
+                return
+            value = int(min(widget.upper+2, 400))
+            popupwin.resize(400, value)
+
+        #view.adjustment.connect("changed", on_value_changed, popupwin)
+
+        popupwin.set_default_size(300, 100)
+
+        popupwin.show_all()
+
+        if not self._timer_started:
+            self._timer_started = True
+            gobject.timeout_add(ThreadPopup._INTERVAL, self.on_timeout)
+
+    def _check_to_need_hint(self, threadview, num):
+        if self._is_thread_view_top(threadview):
+            return True
+
+
index bdb4804..580feec 100644 (file)
@@ -463,10 +463,22 @@ class ResLayout:
         else:
             for element in self.element_list:
                 element.draw(drawingarea, y_offset, self.pango_layout)
-                
+
+    def clone(self):
+        import copy
+        layout = ResLayout(self.left_margin, self.resnum, self.pango_layout)
+        layout.element_list = []
+        for element in self.element_list:
+            layout.element_list.append(copy.copy(element))
+        return layout
 
 
 class ThreadView(gtk.HBox):
+    __gsignals__ = {
+        "cursor-over-link-event":
+        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object, object, ))
+        }
+
     hand_cursor = gtk.gdk.Cursor(gtk.gdk.HAND2)
     regular_cursor = gtk.gdk.Cursor(gtk.gdk.XTERM)
     arrow_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
@@ -867,6 +879,7 @@ class ThreadView(gtk.HBox):
         else:
             if uri is not None and uri != "":
                 cursor = ThreadView.hand_cursor
+                self.emit("cursor-over-link-event", event, uri)
 
         self.drawingarea.window.set_cursor(cursor)
 
index 0583cae..b97da8f 100644 (file)
@@ -50,6 +50,7 @@ import winwrapbase
 import bookmark_list
 import bookmark_window
 import thread_view
+import thread_popup
 
 GLADE_FILENAME = "thread_window.glade"
 
@@ -146,6 +147,8 @@ class WinWrap(winwrapbase.WinWrapBase):
         self.vbox = self.widget_tree.get_widget("vbox")
 
         self.threadview = thread_view.ThreadView()
+        self.threadpopup = thread_popup.ThreadPopup(self.bbs_type)
+        self.threadpopup.push_thread_view(self.threadview)
         self.vbox.pack_start(self.threadview)
         self.vbox.reorder_child(self.threadview, 2)