def _draw(self, gc, view_bounds=None, mode="default"): if self.layout_needed: self._do_layout() with gc: self._draw_container(gc, mode) self._draw_inside_border(gc, view_bounds, mode) dx, dy = self.bounds x, y = self.position if view_bounds: tmp = intersect_bounds((x, y, dx, dy), view_bounds) if tmp is empty_rectangle: new_bounds = tmp else: new_bounds = (tmp[0] - x, tmp[1] - y, tmp[2], tmp[3]) else: new_bounds = view_bounds if new_bounds is not empty_rectangle: for component in self.components: if component is not None: with gc: gc.translate_ctm(*self.position) component.draw(gc, new_bounds, mode)
def _get_visible_components(self, bounds): """ Returns a list of this plot's children that are in the bounds. """ if bounds is None: return [c for c in self.components if c.visible] visible_components = [] for component in self.components: if not component.visible: continue tmp = intersect_bounds(component.outer_position + component.outer_bounds, bounds) if tmp != empty_rectangle: visible_components.append(component) return visible_components
def _draw_mainlayer(self, gc, view_bounds=None, mode="normal"): # For now, ViewPort ignores the view_bounds that are passed in... # Long term, it should be intersected with the view_position to # compute a new view_bounds to pass in to our component. if self.component is not None: x, y = self.position view_x, view_y = self.view_position with gc: # Clip in the viewport's space (screen space). This ensures # that the half-pixel offsets we us are actually screen pixels, # and it's easier/more accurate than transforming the clip # rectangle down into the component's space (especially if zoom # is involved). gc.clip_to_rect(x-0.5, y-0.5, self.width+1, self.height+1) # There is a two-step transformation from the viewport's "outer" # coordinates into the coordinates space of the viewed component: # scaling, followed by a translation. if self.enable_zoom: if self.zoom != 0: gc.scale_ctm(self.zoom, self.zoom) gc.translate_ctm(x/self.zoom - view_x, y/self.zoom - view_y) else: raise RuntimeError("Viewport zoomed out too far.") else: gc.translate_ctm(x - view_x, y - view_y) # Now transform the passed-in view_bounds; this is not the same thing as # self.view_bounds! if view_bounds: # Find the intersection rectangle of the viewport with the view_bounds, # and transform this into the component's space. clipped_view = intersect_bounds(self.position + self.bounds, view_bounds) if clipped_view != empty_rectangle: # clipped_view and self.position are in the space of our parent # container. we know that self.position -> view_x,view_y # in the coordinate space of our component. So, find the # vector from self.position to clipped_view, then add this to # view_x and view_y to generate the transformed coordinates # of clipped_view in our component's space. offset = array(clipped_view[:2]) - array(self.position) new_bounds = ((offset[0]/self.zoom + view_x), (offset[1]/self.zoom + view_y), clipped_view[2] / self.zoom, clipped_view[3] / self.zoom) self.component.draw(gc, new_bounds, mode=mode) return
def _draw_children(self, gc, view_bounds=None, mode="normal"): new_bounds = self._transform_view_bounds(view_bounds) if new_bounds == empty_rectangle: return with gc: gc.set_antialias(False) gc.translate_ctm(*self.position) for component in self.components: if new_bounds: tmp = intersect_bounds(component.outer_position + component.outer_bounds, new_bounds) if tmp == empty_rectangle: continue with gc: component.draw(gc, new_bounds, mode) return
def _transform_view_bounds(self, view_bounds): """ Transforms the given view bounds into our local space and computes a new region that can be handed off to our children. Returns a 4-tuple of the new position+bounds, or None (if None was passed in), or the value of empty_rectangle (from enable.base) if the intersection resulted in a null region. """ if view_bounds: # Check if we are visible tmp = intersect_bounds(self.position + self.bounds, view_bounds) if tmp == empty_rectangle: return empty_rectangle # Compute new_bounds, which is the view_bounds transformed into # our coordinate space v = view_bounds new_bounds = (v[0]-self.x, v[1]-self.y, v[2], v[3]) else: new_bounds = None return new_bounds