def select_down_item(self): ''' Select next row item. ''' if len(self.items) > 0: vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_lower()) else: item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) if self.focus_index + columns <= len(self.items) - 1: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index += columns self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to item. row = int(self.focus_index / columns) if vadjust.get_value() + vadjust.get_page_size() - self.padding_y < (row + 1) * item_height: vadjust.set_value(vadjust.get_lower() + (row + 1) * item_height - vadjust.get_page_size() + self.padding_y) elif vadjust.get_value() + vadjust.get_page_size() - self.padding_y == (row + 1) * item_height: vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size())
def select_right_item(self): ''' Select right item. ''' if len(self.items) > 0: vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_lower()) else: item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) row = int(self.focus_index / columns) max_index = min((row + 1) * columns - 1, len(self.items) - 1) if self.focus_index + 1 <= max_index: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index += 1 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0)
def scroll_page_down(self): ''' Scroll page down of iconview. ''' if len(self.items): vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = len(self.items) - 1 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size()) else: item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) column = int(self.focus_index % columns) if (vadjust.get_value() - vadjust.get_lower() + vadjust.get_page_size()) % item_height == 0: row = int((vadjust.get_value() - vadjust.get_lower() + vadjust.get_page_size() - self.padding_y) / item_height) - 1 else: row = int((vadjust.get_value() - vadjust.get_lower() + vadjust.get_page_size() - self.padding_y) / item_height) if row * columns + column <= len(self.items) - 1: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index = row * columns + column self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) else: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index = (row - 1) * columns + column self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) vadjust.set_value(min(vadjust.get_upper() - vadjust.get_page_size(), vadjust.get_value() + vadjust.get_page_size() - self.padding_y))
def select_up_item(self): ''' Select up row item. ''' if len(self.items) > 0: vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_lower()) else: item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) if self.focus_index - columns >= 0: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index -= columns self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to item. row = int(self.focus_index / columns) if vadjust.get_value() - self.padding_y > row * item_height: vadjust.set_value(vadjust.get_lower() + row * item_height + self.padding_y) elif vadjust.get_value() - self.padding_y == row * item_height: vadjust.set_value(vadjust.get_lower())
def leave_icon_view(self, widget, event): '''leave-notify-event signal handler.''' # Hide hover row when cursor out of viewport area. vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() hadjust = get_match_parent(self, ["ScrolledWindow"]).get_hadjustment() if not is_in_rect((event.x, event.y), (hadjust.get_value(), vadjust.get_value(), hadjust.get_page_size(), vadjust.get_page_size())): self.clear_focus_item()
def scroll_page_down(self): ''' Scroll page down of iconview. ''' if len(self.items): vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = len(self.items) - 1 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size()) else: item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) column = int(self.focus_index % columns) if (vadjust.get_value() - vadjust.get_lower() + vadjust.get_page_size()) % item_height == 0: row = int((vadjust.get_value() - vadjust.get_lower() + vadjust.get_page_size() - self.padding_y) / item_height) - 1 else: row = int((vadjust.get_value() - vadjust.get_lower() + vadjust.get_page_size() - self.padding_y) / item_height) if row * columns + column <= len(self.items) - 1: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index = row * columns + column self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) else: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index = (row - 1) * columns + column self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) vadjust.set_value( min( vadjust.get_upper() - vadjust.get_page_size(), vadjust.get_value() + vadjust.get_page_size() - self.padding_y))
def expose_icon_view(self, widget, event): ''' Internal callback for `expose-event` signal. ''' # Update vadjustment. self.update_vadjustment() # Init. cr = widget.window.cairo_create() rect = widget.allocation # Get offset. (offset_x, offset_y, viewport) = self.get_offset_coordinate(widget) # Draw background. with cairo_state(cr): scrolled_window = get_match_parent(self, ["ScrolledWindow"]) cr.translate(-scrolled_window.allocation.x, -scrolled_window.allocation.y) cr.rectangle(offset_x, offset_y, scrolled_window.allocation.x + scrolled_window.allocation.width, scrolled_window.allocation.y + scrolled_window.allocation.height) cr.clip() (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel()) skin_config.render_background(cr, self, offset_x + shadow_x, offset_y + shadow_y) # Draw mask. self.draw_mask(cr, offset_x, offset_y, viewport.allocation.width, viewport.allocation.height) # Draw items. self.draw_items(cr, rect, offset_x, offset_y, viewport)
def get_render_item_info(self): ''' Internal function to get information of render items. ''' # Get offset. (offset_x, offset_y, viewport) = self.get_offset_coordinate(self) # Get item size. item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) # Get viewport index. start_y = offset_y - self.padding_y start_row = max(int(start_y / item_height), 0) start_index = start_row * columns end_y = offset_y - self.padding_y + viewport.allocation.height if end_y % item_height == 0: end_row = end_y / item_height - 1 else: end_row = end_y / item_height end_index = min((end_row + 1) * columns, len(self.items)) return (item_width, item_height, columns, start_index, end_index)
def update_redraw_request_list(self): ''' Internal function to update redraw request list. ''' # Redraw when request list is not empty. if len(self.redraw_request_list) > 0: # Get offset. (offset_x, offset_y, viewport) = self.get_offset_coordinate(self) # Get viewport index. item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) start_y = offset_y - self.padding_y start_row = max(int(start_y / item_height), 0) start_index = start_row * columns end_y = offset_y - self.padding_y + viewport.allocation.height if end_y % item_height == 0: end_row = end_y / item_height - 1 else: end_row = end_y / item_height end_index = min((end_row + 1) * columns, len(self.items)) # Redraw whole viewport area once found any request item in viewport. for item in self.redraw_request_list: if item in self.items[start_index:end_index]: self.queue_draw() break # Clear redraw request list. self.redraw_request_list = [] return True
def realize_icon_view(self, widget): ''' Realize icon view. ''' scrolled_window = get_match_parent(self, ["ScrolledWindow"]) scrolled_window.connect("button-release-event", self.button_release_scrolled_window)
def update_vadjustment(self): ''' Update vertical adjustment. ''' scrolled_window = get_match_parent(self, ["ScrolledWindow"]) if len(self.items) > 0: item_width, item_height = self.items[0].get_width(), self.items[0].get_height() columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) if columns > 0: if len(self.items) % columns == 0: view_height = int(len(self.items) / columns) * item_height else: view_height = (int(len(self.items) / columns) + 1) * item_height self.set_size_request(columns * item_width + self.padding_x * 2, view_height + self.padding_y * 2) if scrolled_window != None: vadjust = scrolled_window.get_vadjustment() vadjust.set_upper(max(view_height + self.padding_y * 2, scrolled_window.allocation.height)) else: self.set_size_request(scrolled_window.allocation.width, scrolled_window.allocation.height) vadjust = scrolled_window.get_vadjustment() vadjust.set_upper(scrolled_window.allocation.height)
def icon_view_get_event_index(self, event): '''Get index at event.''' if len(self.items) > 0: (event_x, event_y) = get_event_coords(event) item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) if len(self.items) % columns == 0: rows = int(len(self.items) / columns) else: rows = int(len(self.items) / columns) + 1 if event_x > columns * item_width: return None elif event_y > rows * item_height: return None else: if event_x % item_width == 0: column_index = max(event_x / item_width - 1, 0) else: column_index = min(event_x / item_width, columns - 1) if event_y % item_height == 0: row_index = max(event_y / item_height - 1, 0) else: row_index = min(event_y / item_height, rows - 1) item_index = row_index * columns + column_index if item_index > len(self.items) - 1: return None else: return (row_index, column_index, item_index, event_x - column_index * item_width, event_y - row_index * item_height)
def draw_icon_view_mask(widget, x, y, w, h, render_callback): ''' Draw icon view mask with given render method. @param widget: Target widget. @param x: X coordinate of draw area. @param y: Y coordinate of draw area. @param w: Width of draw area. @param h: Height of draw area. @param render_callback: Render callback. ''' cr = widget.window.cairo_create() viewport = get_match_parent(widget, ["Viewport"]) toplevel = widget.get_toplevel() (offset_x, offset_y) = viewport.translate_coordinates(toplevel, 0, 0) (shadow_x, shadow_y) = get_window_shadow_size(toplevel) with cairo_state(cr): cr.rectangle(x, y, w, h) cr.clip() render_callback( cr, x - offset_x + shadow_x, y - offset_y + shadow_y, toplevel.allocation.width, toplevel.allocation.height)
def get_render_item_info(self): ''' Internal function to get information of render items. ''' # Get offset. (offset_x, offset_y, viewport) = self.get_offset_coordinate(self) # Get item size. item_width = 1 item_height = 1 if len(self.items): item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) # Get viewport index. start_y = offset_y - self.padding_y start_row = max(int(start_y / item_height), 0) start_index = start_row * columns end_y = offset_y - self.padding_y + viewport.allocation.height if end_y % item_height == 0: end_row = end_y / item_height - 1 else: end_row = end_y / item_height end_index = min((end_row + 1) * columns, len(self.items)) return (item_width, item_height, columns, start_index, end_index)
def draw_items(self, cr, rect): # Draw items. if len(self.items) > 0: with cairo_state(cr): scrolled_window = get_match_parent(self, ["ScrolledWindow"]) vadjust_value = int(scrolled_window.get_vadjustment().get_value()) hadjust_value = int(scrolled_window.get_hadjustment().get_value()) # Draw on drawing area. (item_width, item_height, columns, start_index, end_index) = self.get_render_item_info() for (index, item) in enumerate(self.items[start_index:end_index]): row = int((start_index + index) / columns) column = (start_index + index) % columns render_x = self.padding_x + column * item_width - hadjust_value render_y = self.padding_y + row * item_height - vadjust_value # Draw row background. self.draw_row_mask(cr, gtk.gdk.Rectangle(render_x, render_y, rect.width, item_height), row) item.row_index = row with cairo_state(cr): # Don't allow draw out of item area. cr.rectangle(render_x, render_y, item_width, item_height) cr.clip() item.render(cr, gtk.gdk.Rectangle(render_x, render_y, item_width, item_height))
def update_vadjustment(self): ''' Update vertical adjustment. ''' scrolled_window = get_match_parent(self, ["ScrolledWindow"]) if len(self.items) > 0: item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) if columns > 0: if len(self.items) % columns == 0: view_height = int(len(self.items) / columns) * item_height else: view_height = (int(len(self.items) / columns) + 1) * item_height self.set_size_request( columns * item_width + self.padding_x * 2, view_height + self.padding_y * 2) if scrolled_window != None: vadjust = scrolled_window.get_vadjustment() vadjust.set_upper( max(view_height + self.padding_y * 2, scrolled_window.allocation.height)) else: self.set_size_request(scrolled_window.allocation.width, scrolled_window.allocation.height) vadjust = scrolled_window.get_vadjustment() vadjust.set_upper(scrolled_window.allocation.height)
def set_double_items(self, item): # 设置双击items. self.__double_items = item # print "__listview_down_event..." vadjustment = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() # 获取 start, end index. start_index, end_index = self.__get_start_end_index() row_index = self.items.index(self.__double_items) if vadjustment: value = vadjustment.get_value() # if start_index <= row_index <= end_index: # row_index += 1 if row_index <= len(self.items) - 1: # 滚动窗口. if row_index + 1 == end_index: if row_index == len(self.items) - 1: self.__listview_end_event() else: vadjustment.set_value(value + self.__items_padding_height) else: # 超出范围,需要处理. 比如随机播放... # value = vadjustment.get_value() # start_index, end_index = self.__get_start_end_index() # 滚动窗口. max_value = vadjustment.get_upper() - vadjustment.get_page_size() move_value = self.__items_padding_height * self.items.index(item) # abs(end_index - start_index - 1) value = move_value # 如果滚动的页超出了,直接到末尾. if value > max_value: vadjustment.set_value(max_value + self.__items_padding_height) else: print value vadjustment.set_value(value) # self.on_queue_draw_area()
def __listview_realize_event(self, widget): widget.set_realized(True) scroll_win = get_match_parent(widget, "ScrolledWindow") if scroll_win: scroll_win.get_vadjustment().connect("value-changed", self.__scroll_win_vajustment_changed) scroll_win.get_hadjustment().connect("value-changed", self.__scroll_win_hajustment_changed) scroll_win.connect("scroll-event", self.__scroll_win_scroll_event)
def __init_scroll_win(self): self.scroll_win = get_match_parent(self, ["ScrolledWindow"]) self.hadjustment = self.scroll_win.get_hadjustment() self.vadjustment = self.scroll_win.get_vadjustment() self.hadjustment.connect("value-changed", self.__list_view_adjustments_changed) self.vadjustment.connect("value-changed", self.__list_view_adjustments_changed)
def size_allocated_icon_view(self, widget, rect): # Cairo render surface. scrolled_window = get_match_parent(self, ["ScrolledWindow"]) try: self.render_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, scrolled_window.allocation.width, scrolled_window.allocation.height) self.render_surface_cr = gtk.gdk.CairoContext(cairo.Context(self.render_surface)) except Exception: pass
def __listview_end_event(self): # 最末尾项. #print "__listview_end_event..." vadjustment = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_upper() - vadjustment.get_page_size() # 设置选中items. if self.items != []: self.__single_items = [self.items[len(self.items) - 1]] vadjustment.set_value(value) self.on_queue_draw_area()
def __listview_realize_event(self, widget): widget.set_realized(True) scroll_win = get_match_parent(widget, "ScrolledWindow") if scroll_win: scroll_win.get_vadjustment().connect( "value-changed", self.__scroll_win_vajustment_changed) scroll_win.get_hadjustment().connect( "value-changed", self.__scroll_win_hajustment_changed) scroll_win.connect("scroll-event", self.__scroll_win_scroll_event)
def __listview_home_event(self): # 开头第一个项. #print "__listview_home_event..." vadjustment = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_lower() # 设置选中items. if self.items != []: self.__single_items = [self.items[0]] vadjustment.set_value(value) self.on_queue_draw_area()
def select_last_item(self): '''Select last item.''' if len(self.items) > 0: self.clear_focus_item() self.focus_index = len(self.items) - 1 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to bottom. vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size())
def __on_draw_item_fg(self, cr, rect): top_pixbuf = app_theme.get_pixbuf("playlist/list_top.png").get_pixbuf() bottom_pixbuf = app_theme.get_pixbuf("playlist/list_bottom.png").get_pixbuf() # scroll_win = get_match_parent(self, "ScrolledWindow") vadjust = scroll_win.get_vadjustment() if vadjust.get_value() != vadjust.get_lower(): draw_pixbuf(cr, top_pixbuf, 0, vadjust.get_value() - 1) if vadjust.get_value() + vadjust.get_page_size() != vadjust.get_upper(): y = vadjust.get_value() + vadjust.get_page_size() - bottom_pixbuf.get_height() draw_pixbuf(cr, bottom_pixbuf, 0, y)
def select_first_item(self): '''Select first item.''' if len(self.items) > 0: self.clear_focus_item() self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() vadjust.set_value(vadjust.get_lower())
def size_allocated_icon_view(self, widget, rect): # Cairo render surface. scrolled_window = get_match_parent(self, ["ScrolledWindow"]) try: self.render_surface = cairo.ImageSurface( cairo.FORMAT_ARGB32, scrolled_window.allocation.width, scrolled_window.allocation.height) self.render_surface_cr = gtk.gdk.CairoContext( cairo.Context(self.render_surface)) except Exception: pass
def select_right_item(self): '''Select next column.''' if len(self.items) > 0: vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_lower()) else: item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) row = int(self.focus_index / columns) max_index = min((row + 1) * columns - 1, len(self.items) - 1) if self.focus_index + 1 <= max_index: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index += 1 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0)
def select_down_item(self): ''' Select next row item. ''' if len(self.items) > 0: vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_lower()) else: item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) if self.focus_index + columns <= len(self.items) - 1: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index += columns self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to item. row = int(self.focus_index / columns) if vadjust.get_value() + vadjust.get_page_size( ) - self.padding_y < (row + 1) * item_height: vadjust.set_value(vadjust.get_lower() + (row + 1) * item_height - vadjust.get_page_size() + self.padding_y) elif vadjust.get_value() + vadjust.get_page_size( ) - self.padding_y == (row + 1) * item_height: vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size())
def icon_view_get_event_index(self, event): ''' Internal function to get item index at event coordinate.. ''' if len(self.items) > 0: (event_x, event_y) = get_event_coords(event) item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) if columns == 0: return None if len(self.items) % max(columns, 1) == 0: rows = int(len(self.items) / columns) else: rows = int(len(self.items) / columns) + 1 if event_x > columns * item_width + self.padding_x: return None elif event_y > rows * item_height + self.padding_y: return None else: ''' TODO: total_width % item_width is item count in the row, but when padding_x reduce the total_width, event_x need to -self.padding_x ''' padding_event_x = event_x - self.padding_x padding_event_y = event_y - self.padding_y if padding_event_x % item_width == 0: column_index = max(padding_event_x / item_width - 1, 0) else: column_index = min(padding_event_x / item_width, columns - 1) if padding_event_y % item_height == 0: row_index = max(padding_event_y / item_height - 1, 0) else: row_index = min(padding_event_y / item_height, rows - 1) item_index = row_index * columns + column_index if item_index > len(self.items) - 1: return None else: ''' TODO: it need to use event_x NOT padding_event_x return the item pos_x ''' return (row_index, column_index, item_index, event_x - column_index * item_width, event_y - row_index * item_height)
def select_last_item(self): ''' Select last item. ''' if len(self.items) > 0: self.clear_focus_item() self.focus_index = len(self.items) - 1 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to bottom. vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size())
def select_first_item(self): ''' Select first item. ''' if len(self.items) > 0: self.clear_focus_item() self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() vadjust.set_value(vadjust.get_lower())
def __on_draw_item_fg(self, cr, rect): top_pixbuf = app_theme.get_pixbuf("playlist/list_top.png").get_pixbuf() bottom_pixbuf = app_theme.get_pixbuf( "playlist/list_bottom.png").get_pixbuf() # scroll_win = get_match_parent(self, "ScrolledWindow") vadjust = scroll_win.get_vadjustment() if vadjust.get_value() != vadjust.get_lower(): draw_pixbuf(cr, top_pixbuf, 0, vadjust.get_value() - 1) if vadjust.get_value() + vadjust.get_page_size() != vadjust.get_upper( ): y = vadjust.get_value() + vadjust.get_page_size( ) - bottom_pixbuf.get_height() draw_pixbuf(cr, bottom_pixbuf, 0, y)
def tree_view_find_node_in_draw_area(self, node): if node in self.__nodes_list: index = self.__nodes_list.index(node) # self.scroll_win = get_match_parent(self, "ScrolledWindow") if self.scroll_win: start_index = max(int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0) end_index = (start_index + (self.scroll_win.allocation.height) / self.node_height) + 1 else: start_index = 0 end_index = 0 if start_index <= index <= end_index: return True return False
def __get_start_end_index(self): rect = self.allocation offset_x, offset_y, viewport = get_offset_coordinate(self) # # 获取滚动窗口. scroll_win = get_match_parent(self, "ScrolledWindow") scroll_rect_h = rect.height if scroll_win: # 如果没有滚动窗口,直接获取listview的高度. scroll_rect_h = scroll_win.allocation.height start_y = offset_y - self.__columns_padding_height end_y = offset_y + viewport.allocation.height - self.__columns_padding_height start_index = max(int(scroll_win.get_vadjustment().get_value() / self.__items_padding_height), 0) end_index = (start_index + (scroll_rect_h - self.__columns_padding_height)/ self.__items_padding_height) + 1 return start_index, end_index
def tree_view_queue_draw_area(self): self.scroll_win = get_match_parent(self, ["ScrolledWindow"]) if self.scroll_win: start_index = max(int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0) end_index = (start_index + (self.scroll_win.allocation.height) / self.node_height) + 1 w = self.scroll_win.allocation.width h = self.scroll_win.allocation.height else: start_index = 0 end_index = self.allocation.height / self.allocation.height w = self.allocation.width h = self.allocation.height x = 0 y = 0 + start_index * self.node_height self.queue_draw_area(x, y, w, h)
def select_up_item(self): ''' Select up row item. ''' if len(self.items) > 0: vadjust = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if self.focus_index == None: self.focus_index = 0 self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to top. vadjust.set_value(vadjust.get_lower()) else: item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) if self.focus_index - columns >= 0: self.emit("lost-focus-item", self.items[self.focus_index]) self.focus_index -= columns self.emit("motion-notify-item", self.items[self.focus_index], 0, 0) # Scroll to item. row = int(self.focus_index / columns) if vadjust.get_value() - self.padding_y > row * item_height: vadjust.set_value(vadjust.get_lower() + row * item_height + self.padding_y) elif vadjust.get_value() - self.padding_y == row * item_height: vadjust.set_value(vadjust.get_lower())
def icon_view_get_event_index(self, event): ''' Internal function to get item index at event coordinate.. ''' if len(self.items) > 0: (event_x, event_y) = get_event_coords(event) item_width, item_height = self.items[0].get_width(), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int((scrolled_window.allocation.width - self.padding_x * 2) / item_width) if columns == 0: return None if len(self.items) % max(columns, 1) == 0: rows = int(len(self.items) / columns) else: rows = int(len(self.items) / columns) + 1 if event_x > columns * item_width + self.padding_x: return None elif event_y > rows * item_height + self.padding_y: return None else: ''' TODO: total_width % item_width is item count in the row, but when padding_x reduce the total_width, event_x need to -self.padding_x ''' padding_event_x = event_x - self.padding_x padding_event_y = event_y - self.padding_y if padding_event_x % item_width == 0: column_index = max(padding_event_x / item_width - 1, 0) else: column_index = min(padding_event_x / item_width, columns - 1) if padding_event_y % item_height == 0: row_index = max(padding_event_y / item_height - 1, 0) else: row_index = min(padding_event_y / item_height, rows - 1) item_index = row_index * columns + column_index if item_index > len(self.items) - 1: return None else: ''' TODO: it need to use event_x NOT padding_event_x return the item pos_x ''' return (row_index, column_index, item_index, event_x - column_index * item_width, event_y - row_index * item_height)
def __listview_up_event(self): #print "__listview_up_event.." if self.__single_items == []: # 如果为空,则跳转到开头. self.__listview_home_event() else: vadjustment = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_value() start_index, end_index = self.__get_start_end_index() row_index = self.items.index(self.__single_items[len(self.__single_items)-1]) if (row_index - 1) >= 0: self.__single_items = [self.items[max(row_index - 1, 0)]] self.on_queue_draw_area() # 滚动窗口. if row_index - 1 == start_index: vadjustment.set_value(value - self.__items_padding_height)
def get_offset_coordinate(self, widget): '''Get offset coordinate.''' # Init. rect = widget.allocation # Get coordinate. viewport = get_match_parent(widget, "Viewport") if viewport: coordinate = widget.translate_coordinates(viewport, rect.x, rect.y) if len(coordinate) == 2: (offset_x, offset_y) = coordinate return (-offset_x, -offset_y, viewport) else: return (0, 0, viewport) else: return (0, 0, viewport)
def tree_view_queue_draw_area(self): self.scroll_win = get_match_parent(self, ["ScrolledWindow"]) if self.scroll_win: start_index = max( int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0) #end_index = (start_index + (self.scroll_win.allocation.height) / self.node_height) + 1 w = self.scroll_win.allocation.width h = self.scroll_win.allocation.height else: start_index = 0 #end_index = self.allocation.height / self.allocation.height w = self.allocation.width h = self.allocation.height x = 0 y = 0 + start_index * self.node_height self.queue_draw_area(x, y, w, h)
def draw_background(self, widget, cr): with cairo_state(cr): scrolled_window = get_match_parent(self, ["ScrolledWindow"]) (shadow_x, shadow_y) = get_window_shadow_size(self.get_toplevel()) (offset_x, offset_y) = self.translate_coordinates(self.get_toplevel(), 0, 0) vadjust = scrolled_window.get_vadjustment() vadjust_value = int(vadjust.get_value()) hadjust = scrolled_window.get_hadjustment() hadjust_value = int(hadjust.get_value()) x = shadow_x - offset_x y = shadow_y - offset_y cr.rectangle(hadjust_value, vadjust_value, scrolled_window.allocation.width, scrolled_window.allocation.height) cr.clip() cr.translate(x, y) skin_config.render_background(cr, widget, 0, 0)
def tree_view_find_node_in_draw_area(self, node): if node in self.__nodes_list: index = self.__nodes_list.index(node) # self.scroll_win = get_match_parent(self, "ScrolledWindow") if self.scroll_win: start_index = max( int(self.scroll_win.get_vadjustment().get_value() / self.node_height), 0) end_index = ( start_index + (self.scroll_win.allocation.height) / self.node_height) + 1 else: start_index = 0 end_index = 0 if start_index <= index <= end_index: return True return False
def on_queue_draw_area(self): # 重绘区域. if self.__expose_check: scroll_win = get_match_parent(self, "ScrolledWindow") offset_x, offset_y , viewport = get_offset_coordinate(self) rect = self.allocation if scroll_win: rect = scroll_win.allocation x = 0 + offset_x #rect.x + offset_x y = 0 + offset_y #rect.y + offset_y w = rect.width h = rect.height else: x = rect.x + offset_x y = rect.y + offset_y w = rect.width h = rect.height self.queue_draw_area(x, y, w, h)
def draw_list_view_mask(widget, x, y, w, h, render_callback): '''Draw skin preview view mask.''' cr = widget.window.cairo_create() viewport = get_match_parent(widget, ["Viewport"]) toplevel = widget.get_toplevel() (offset_x, offset_y) = viewport.translate_coordinates(toplevel, 0, 0) (shadow_x, shadow_y) = get_window_shadow_size(toplevel) with cairo_state(cr): cr.rectangle(x, y, w, h) cr.clip() render_callback( cr, x - offset_x + shadow_x, y - offset_y + shadow_y, toplevel.allocation.width, toplevel.allocation.height)
def get_offset_coordinate(self, widget): ''' Internal function to get offset coordinate. ''' # Init. rect = widget.allocation # Get coordinate. viewport = get_match_parent(widget, "Viewport") if viewport: coordinate = widget.translate_coordinates(viewport, rect.x, rect.y) if len(coordinate) == 2: (offset_x, offset_y) = coordinate return (-offset_x, -offset_y, viewport) else: return (0, 0, viewport) else: return (0, 0, viewport)
def __get_start_end_index(self): rect = self.allocation offset_x, offset_y, viewport = get_offset_coordinate(self) # # 获取滚动窗口. scroll_win = get_match_parent(self, "ScrolledWindow") scroll_rect_h = rect.height if scroll_win: # 如果没有滚动窗口,直接获取listview的高度. scroll_rect_h = scroll_win.allocation.height start_y = offset_y - self.__columns_padding_height end_y = offset_y + viewport.allocation.height - self.__columns_padding_height start_index = max( int(scroll_win.get_vadjustment().get_value() / self.__items_padding_height), 0) end_index = (start_index + (scroll_rect_h - self.__columns_padding_height) / self.__items_padding_height) + 1 return start_index, end_index
def set_double_items(self, item): self.__double_items = item # vadjustment = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_value() start_index, end_index = self.__get_start_end_index() # 滚动窗口. max_value = vadjustment.get_upper() - vadjustment.get_page_size() move_value = self.__items_padding_height * self.items.index(item) #abs(end_index - start_index - 1) #value = value + move_value value = move_value # 如果滚动的页超出了,直接到末尾. if value > max_value: vadjustment.set_value(max_value) else: vadjustment.set_value(value) # self.on_queue_draw_area()
def __draw_view_details(self, cr, rect, widget): # offset_x, offset_y, viewport = get_offset_coordinate(widget) # e = ItemEventArgs() save_rect = rect e.cr = cr e.rect = (rect.x, rect.y + offset_y + self.__columns_padding_height, rect.width, rect.height) e.drag_rect = self.__drag_rect self.on_draw_item(e) # 画标题头. if self.__columns_show_check: self.__draw_view_details_column(offset_y, cr, rect) # 优化listview. # 获取滚动窗口. scroll_win = get_match_parent(self, "ScrolledWindow") scroll_rect_h = rect.height if scroll_win: # 如果没有滚动窗口,直接获取listview的高度. scroll_rect_h = scroll_win.allocation.height # dtk.ui.listview ===>>> start_y = offset_y - self.__columns_padding_height end_y = offset_y + viewport.allocation.height - self.__columns_padding_height #start_index = max(start_y / self.__items_padding_height, 0) start_index = max( int(scroll_win.get_vadjustment().get_value() / self.__items_padding_height), 0) end_index = (start_index + (scroll_rect_h - self.__columns_padding_height) / self.__items_padding_height) + 2 # # 剪切出绘制items的区域,防止绘制到标题头上. cr.save() cr.rectangle(rect.x + offset_x, rect.y + offset_y + self.__columns_padding_height, scroll_win.allocation.width, scroll_win.allocation.height) cr.clip() # 画 items. self.__draw_view_details_items(start_index, end_index, cr, rect) cr.restore() # # 画上面和下面的效果. self.on_draw_item_fg(cr, rect)
def __listview_up_event(self): #print "__listview_up_event.." if self.__single_items == []: # 如果为空,则跳转到开头. self.__listview_home_event() else: vadjustment = get_match_parent( self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_value() start_index, end_index = self.__get_start_end_index() row_index = self.items.index( self.__single_items[len(self.__single_items) - 1]) if (row_index - 1) >= 0: self.__single_items = [self.items[max(row_index - 1, 0)]] self.on_queue_draw_area() # 滚动窗口. if row_index - 1 == start_index: vadjustment.set_value(value - self.__items_padding_height)
def __listview_page_up_event(self): # 向下翻页. #print "__listview_page_up_event..." if self.__single_items == []: # 如果为空,则跳转到开头. self.__listview_home_event() else: vadjustment = get_match_parent( self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_value() start_index, end_index = self.__get_start_end_index() min_value = vadjustment.get_lower() move_value = self.__items_padding_height * abs(start_index - end_index - 1) # 滚动窗口. value = value - move_value # 如果滚动的页超出了最小值,直接到开头. if value < min_value: vadjustment.set_value(min_value) else: vadjustment.set_value(value) self.on_queue_draw_area()
def set_double_items(self, item): # 设置双击items. self.__double_items = item #print "__listview_down_event..." vadjustment = get_match_parent(self, ["ScrolledWindow"]).get_vadjustment() # 获取 start, end index. start_index, end_index = self.__get_start_end_index() row_index = self.items.index(self.__double_items) if vadjustment: value = vadjustment.get_value() # if start_index <= row_index <= end_index: #row_index += 1 if row_index <= len(self.items) - 1: # 滚动窗口. if row_index + 1 == end_index: if row_index == len(self.items) - 1: self.__listview_end_event() else: vadjustment.set_value(value + self.__items_padding_height) else: # 超出范围,需要处理. 比如随机播放... #value = vadjustment.get_value() #start_index, end_index = self.__get_start_end_index() # 滚动窗口. max_value = vadjustment.get_upper( ) - vadjustment.get_page_size() move_value = self.__items_padding_height * self.items.index( item) #abs(end_index - start_index - 1) value = move_value # 如果滚动的页超出了,直接到末尾. if value > max_value: vadjustment.set_value(max_value + self.__items_padding_height) else: print value vadjustment.set_value(value) # self.on_queue_draw_area()
def __listview_page_down_event(self): # 向上翻页. #print "__listview_page_down_event.." if self.__single_items == []: # 如果为空,则跳转到结尾. self.__listview_end_event() else: vadjustment = get_match_parent( self, ["ScrolledWindow"]).get_vadjustment() if vadjustment: value = vadjustment.get_value() start_index, end_index = self.__get_start_end_index() # 滚动窗口. max_value = vadjustment.get_upper( ) - vadjustment.get_page_size() move_value = self.__items_padding_height * abs(end_index - start_index - 1) value = value + move_value # 如果滚动的页超出了,直接到末尾. if value > max_value: vadjustment.set_value(max_value) else: vadjustment.set_value(value) self.on_queue_draw_area()
def draw_items(self, cr, rect): # Draw items. if len(self.items) > 0: with cairo_state(cr): scrolled_window = get_match_parent(self, ["ScrolledWindow"]) vadjust_value = int( scrolled_window.get_vadjustment().get_value()) hadjust_value = int( scrolled_window.get_hadjustment().get_value()) # Draw on drawing area. (item_width, item_height, columns, start_index, end_index) = self.get_render_item_info() for (index, item) in enumerate(self.items[start_index:end_index]): row = int((start_index + index) / columns) column = (start_index + index) % columns render_x = self.padding_x + column * item_width - hadjust_value render_y = self.padding_y + row * item_height - vadjust_value # Draw row background. self.draw_row_mask( cr, gtk.gdk.Rectangle(render_x, render_y, rect.width, item_height), row) item.row_index = row with cairo_state(cr): # Don't allow draw out of item area. cr.rectangle(render_x, render_y, item_width, item_height) cr.clip() item.render( cr, gtk.gdk.Rectangle(render_x, render_y, item_width, item_height))
def update_redraw_request_list(self): ''' Internal function to update redraw request list. ''' # Redraw when request list is not empty. if len(self.redraw_request_list) > 0: # Get offset. (offset_x, offset_y, viewport) = self.get_offset_coordinate(self) # Get viewport index. item_width, item_height = self.items[0].get_width( ), self.items[0].get_height() scrolled_window = get_match_parent(self, ["ScrolledWindow"]) columns = int( (scrolled_window.allocation.width - self.padding_x * 2) / item_width) start_y = offset_y - self.padding_y start_row = max(int(start_y / item_height), 0) start_index = start_row * columns end_y = offset_y - self.padding_y + viewport.allocation.height if end_y % item_height == 0: end_row = end_y / item_height - 1 else: end_row = end_y / item_height end_index = min((end_row + 1) * columns, len(self.items)) # Redraw whole viewport area once found any request item in viewport. for item in self.redraw_request_list: if item in self.items[start_index:end_index]: self.queue_draw() break # Clear redraw request list. self.redraw_request_list = [] return True
def draw_icon_view_mask(widget, x, y, w, h, render_callback): ''' Draw icon view mask with given render method. @param widget: Target widget. @param x: X coordinate of draw area. @param y: Y coordinate of draw area. @param w: Width of draw area. @param h: Height of draw area. @param render_callback: Render callback. ''' cr = widget.window.cairo_create() viewport = get_match_parent(widget, ["Viewport"]) toplevel = widget.get_toplevel() (offset_x, offset_y) = viewport.translate_coordinates(toplevel, 0, 0) (shadow_x, shadow_y) = get_window_shadow_size(toplevel) with cairo_state(cr): cr.rectangle(x, y, w, h) cr.clip() render_callback(cr, x - offset_x + shadow_x, y - offset_y + shadow_y, toplevel.allocation.width, toplevel.allocation.height)