class ThreadView(gtk.HBox):
+ 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)
def __init__(self):
gtk.HBox.__init__(self, False, 0)
self.pack_start(self.vscrollbar, expand=False)
self.adjustment = self.vscrollbar.get_adjustment()
- self.drawingarea.add_events(gtk.gdk.SCROLL_MASK)
+ self.drawingarea.add_events(
+ gtk.gdk.SCROLL_MASK |
+ gtk.gdk.POINTER_MOTION_MASK |
+ gtk.gdk.BUTTON_PRESS_MASK |
+ gtk.gdk.BUTTON_RELEASE_MASK)
self.adjustment.step_increment = 20
self.drawingarea_prev_width = 0
self.drawingarea.connect(
"size-allocate", self.on_drawingarea_size_allocate)
self.drawingarea.connect(
+ "scroll-event", self.on_drawingarea_scroll_event)
+ self.drawingarea.connect(
+ "motion-notify-event", self.on_drawingrarea_motion_notify_event)
+ self.drawingarea.connect(
"button-press-event", self.on_drawingarea_button_press_event)
self.drawingarea.connect(
- "scroll-event", self.on_drawingarea_scroll_event)
+ "button-release-event", self.on_drawingarea_button_release_event)
self.vscrollbar.connect(
"value-changed", self.on_vscrollbar_value_changed)
self.initialize_buffer()
+ self.on_uri_clicked = self._on_uri_clicked
+
+ self.button1_pressed = False
+ self.current_pressed_uri = None
+
+ self.popupmenu = None
+ self.menu_openuri = None
+ self.menu_copylinkaddress = None
+ self.menu_separator_link = None
+ self.menu_copyselection = None
+ self.menu_openasuri = None
+ self.menu_separator_selection = None
+
+ self.menud_uri = None
+
+ def _on_uri_clicked(self, uri):
+ print uri, "clicked!!!!"
+
def initialize_buffer(self):
self.pangolayout = []
self.adjustment.upper = pangolayout.posY + y
self.prevent_adjustment_overflow()
self.redraw()
+ self.change_vscrollbar_visible()
def create_pango_layout(self, text):
return self.drawingarea.create_pango_layout(text)
sum_height += y
self.adjustment.upper = sum_height
self.prevent_adjustment_overflow()
+ self.change_vscrollbar_visible()
+
+ def change_vscrollbar_visible(self):
+ if self.adjustment.upper < self.adjustment.page_size:
+ self.vscrollbar.hide()
+ else:
+ self.vscrollbar.show()
def jump(self, value):
if value > self.adjustment.upper - self.adjustment.page_size:
self.drawingarea.window.draw_layout(
gc, layout.marginleft, layout.posY - int(view_y), layout)
+ def transform_coordinate_gdk_to_adj(self, y):
+ return y + self.adjustment.value
+
+ def transform_coordinate_adj_to_layout(self, x, y, layout):
+ return x - layout.marginleft, y - layout.posY
+
+ def transform_coordinate_gdk_to_layout(self, x, y, layout):
+ return self.transform_coordinate_adj_to_layout(
+ x, self.transform_coordinate_gdk_to_adj(y), layout)
+
+ def ptrpos_to_layout(self, x, y):
+ # transform coordinate, GdkWindow -> adjustment
+ adj_x = x
+ adj_y = self.transform_coordinate_gdk_to_adj(y)
+ for lay in self.pangolayout:
+ width, height = lay.get_pixel_size()
+ if (adj_y >= lay.posY and adj_y < lay.posY + height and
+ adj_x >= lay.marginleft):
+ return lay
+ return None
+
+ def ptrpos_to_uri(self, x, y):
+ # x, y is GdkWindow coordinate
+
+ layout = self.ptrpos_to_layout(x, y)
+
+ if layout is None:
+ return None, None, None
+
+ # transform coordinate, GdkWindow -> pangolayout
+ lay_x, lay_y = self.transform_coordinate_gdk_to_layout(x, y, layout)
+
+ # xy -> index
+ idx, clk = layout.xy_to_index(
+ int(lay_x)*pango.SCALE, int(lay_y)*pango.SCALE)
+
+ x, y, width, height = layout.index_to_pos(idx)
+ x /= pango.SCALE
+ y /= pango.SCALE
+ width /= pango.SCALE
+ height /= pango.SCALE
+ if (lay_x >= x and lay_x < x + width and
+ lay_y >= y and lay_y < y + height):
+
+ for i, (start, end, href) in enumerate(layout.urilist):
+ if idx >= start and idx < end:
+ return href, layout, i
+
+ return None, layout, None
+
def on_drawingarea_expose_event(self, widget, event, data=None):
self.draw_viewport()
self.adjustment.page_increment = self.drawingarea.allocation.height
self.prevent_adjustment_overflow()
+ self.change_vscrollbar_visible()
def prevent_adjustment_overflow(self):
if (self.adjustment.value >
if self.adjustment.value < 0:
self.adjustment.value = 0
- def on_drawingarea_button_press_event(self, widget, event, data=None):
- self.drawingarea.queue_draw()
-
def on_vscrollbar_value_changed(self, widget, data=None):
self.drawingarea.queue_draw()
def on_drawingarea_scroll_event(self, widget, event, data=None):
- if event.direction == gtk.gdk.SCROLL_UP:
- self.adjustment.value -= 66.476200804
- if self.adjustment.value < self.adjustment.lower:
- self.adjustment.value = self.adjustment.lower
- if event.direction == gtk.gdk.SCROLL_DOWN:
- self.adjustment.value += 66.476200804
- max_value = self.adjustment.upper - self.adjustment.page_size
- if self.adjustment.value > max_value:
- self.adjustment.value = max_value
- self.prevent_adjustment_overflow()
+ self.vscrollbar.emit("scroll-event", event)
+
+ def on_drawingrarea_motion_notify_event(self, widget, event, data=None):
+ if event.state & gtk.gdk.BUTTON1_MASK != gtk.gdk.BUTTON1_MASK:
+ self.button1_pressed = False
+
+ cursor = ThreadView.regular_cursor
+
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ if layout is None:
+ cursor = ThreadView.arrow_cursor
+ else:
+ if uri is not None and uri != "":
+ cursor = ThreadView.hand_cursor
+
+ self.drawingarea.window.set_cursor(cursor)
+
+ def on_drawingarea_button_press_event(self, widget, event, data=None):
+ if event.button == 1:
+ self.current_pressed_uri = None
+ self.button1_pressed = True
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ if uri is not None and layout is not None and index is not None:
+ self.current_pressed_uri = (uri, layout, index)
+ elif event.button == 3:
+ time = event.time
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ if uri is not None and layout is not None and index is not None:
+ self.menu_openuri.show()
+ self.menu_copylinkaddress.show()
+ self.menu_separator_link.show()
+ self.menu_openuri.uri = uri
+ self.menu_copylinkaddress.uri = uri
+ else:
+ self.menu_openuri.hide()
+ self.menu_copylinkaddress.hide()
+ self.menu_separator_link.hide()
+ self.menu_openuri.uri = None
+ self.menu_copylinkaddress.uri = None
+
+ self.menu_copyselection.hide()
+ self.menu_openasuri.hide()
+ self.menu_separator_selection.hide()
+
+ self.popupmenu.popup(None, None, None, event.button, time)
+ return True
+
+
+ def on_drawingarea_button_release_event(self, widget, event, data=None):
+ if event.button == 1:
+ button1_pressed = self.button1_pressed
+ self.button1_pressed = False
+
+ if button1_pressed and self.current_pressed_uri is not None:
+ uri, layout, index = self.ptrpos_to_uri(event.x, event.y)
+ p_uri, p_layout, p_index = self.current_pressed_uri
+ self.current_preesed_uri = None
+ if uri == p_uri and layout == p_layout and index == p_index:
+ self.on_uri_clicked(uri)