def __init__(self, master=None, palette=None, cell_size=20, **kw): if not kw.has_key('width'): kw['width'] = cell_size apply(PyWidget.__init__, (self, master), kw) self.cell_size = cell_size self.num_cells = 0 self.gc_initialized = 0 self.gc = GraphicsDevice() self.gc.SetViewportTransform(1.0, Identity, Identity) self.start_idx = 0 self.dragging = 0 self.bind('<ButtonPress-1>', self.release_1) self.bind('<ButtonPress-3>', self.apply_color_2)
def __init__(self, master=None, toplevel=None, document=None, show_visible=0, show_printable=1, resolution=None, **kw): apply(PyWidget.__init__, (self, master), kw) Viewport.__init__(self, resolution) QueueingPublisher.__init__(self) self.toplevel = toplevel self.move_window_count = 0 self.show_page_outline = 1 self.show_visible = show_visible self.show_printable = show_printable self.gcs_initialized = 0 self.gc = GraphicsDevice() self.renderer = DocRenderer(self) self.widget_size = () self.init_transactions() if document is not None: self.SetDocument(document) else: self.SetDocument(Document(create_layer=1))
class PaletteWidget(PyWidget, Publisher): def __init__(self, master=None, palette=None, cell_size=20, **kw): if not kw.has_key('width'): kw['width'] = cell_size apply(PyWidget.__init__, (self, master), kw) self.cell_size = cell_size self.num_cells = 0 self.gc_initialized = 0 self.gc = GraphicsDevice() self.gc.SetViewportTransform(1.0, Identity, Identity) self.start_idx = 0 self.dragging = 0 self.bind('<ButtonPress-1>', self.release_1) self.bind('<ButtonPress-3>', self.apply_color_2) def DestroyMethod(self): Publisher.Destroy(self) def compute_num_cells(self): self.num_cells = self.tkwin.height / self.cell_size + 1 def MapMethod(self): self.compute_num_cells() if not self.gc_initialized: self.init_gc() self.gc_initialized = 1 def init_gc(self): self.gc.init_gc(self.tkwin) def get_color(self, x, y): if 0 <= x < self.tkwin.width and 0 <= y < self.tkwin.height: i = self.start_idx + y / self.cell_size if i < len(self.unipalette.colors): return self.unipalette.colors[i] def release_1(self, event): try: self.apply_color_1(event) finally: self.dragging = 0 def apply_color_1(self, event): c = self.get_color(event.x, event.y) if c: self.issue(COLOR1, c) def apply_color_2(self, event): c = self.get_color(event.x, event.y) if c: self.issue(COLOR2, c) drag_start = (0, 0, 0) def press_1(self, event): self.drag_start = self.get_color(event.x, event.y) def move_1(self, event):pass def Palette(self): return self.unipalette def SetPalette(self, palette): self.unipalette = palette self.palette_changed() def palette_changed(self): self.compute_num_cells() self.normalize_start() self.tk.call(self._w, 'update') def RedrawMethod(self, region=None): win = self.tkwin width = win.width height = win.height self.gc.StartDblBuffer() self.gc.SetFillColor(StandardColors.black) self.gc.FillRectangle(0, 0, height, width) x = 0 FillRectangle = self.gc.FillRectangle DrawRectangle = self.gc.DrawRectangle DrawLine = self.gc.DrawLine SetFillColor = self.gc.SetFillColor create_color = CreateRGBColor rgbs = self.unipalette.colors rgbs = rgbs[self.start_idx:self.start_idx + self.num_cells] ###widget refresh### r, g, b = tk_to_rgb(app.uimanager.currentColorTheme.bg) SetFillColor(apply(create_color, (r, g, b))) FillRectangle(0, 0, width, height) #################### for rgb in rgbs: SetFillColor(apply(create_color, (1.0, 1.0, 1.0))) FillRectangle(0, x, width, x + width) SetFillColor(apply(create_color, (0.5, 0.5, 0.5))) FillRectangle(1, x, width, x + width - 1) SetFillColor(rgb.RGB()) FillRectangle(2, x + 1, width - 1, x + width - 2) if rgb.name == 'Registration Color': cw = 5 lx = 0 + cw + 1 ly = x + cw + 2 rx = width - cw - 1 ry = x + width - cw - 2 SetFillColor(apply(create_color, (1.0, 1.0, 1.0))) DrawRectangle(Point(lx, ly - 2), Point(rx, ry)) DrawLine(Point(lx + 4, ly - 4), Point(lx + 4, ry + 2)) DrawLine(Point(lx - 2, ly + 2), Point(rx + 2, ly + 2)) x = x + width self.gc.EndDblBuffer() def ResizedMethod(self, width, height): self.compute_num_cells() self.gc.WindowResized(width, height) self.normalize_start() self.UpdateWhenIdle() def normalize_start(self): length = len(self.unipalette.colors) if self.start_idx < 0: self.start_idx = 0 if length < self.num_cells: self.start_idx = 0 elif length - self.start_idx < self.num_cells: self.start_idx = length - self.num_cells def CanScrollLeft(self): return self.start_idx > 0 def CanScrollRight(self): return len(self.unipalette.colors) - self.start_idx > self.num_cells def ScrollXPages(self, count): length = self.tkwin.height / self.cell_size start = self.start_idx self.start_idx = self.start_idx + count * length self.normalize_start() if start != self.start_idx: self.UpdateWhenIdle() def ScrollXUnits(self, count): start = self.start_idx self.start_idx = self.start_idx + count self.normalize_start() if start != self.start_idx: self.UpdateWhenIdle()
class SketchView(PyWidget, Viewport, QueueingPublisher): document = None def __init__(self, master=None, toplevel=None, document=None, show_visible=0, show_printable=1, resolution=None, **kw): apply(PyWidget.__init__, (self, master), kw) Viewport.__init__(self, resolution) QueueingPublisher.__init__(self) self.toplevel = toplevel self.move_window_count = 0 self.show_page_outline = 1 self.show_visible = show_visible self.show_printable = show_printable self.gcs_initialized = 0 self.gc = GraphicsDevice() self.renderer = DocRenderer(self) self.widget_size = () self.init_transactions() if document is not None: self.SetDocument(document) else: self.SetDocument(Document(create_layer=1)) def destroy(self): self.unsubscribe_doc() PyWidget.destroy(self) QueueingPublisher.Destroy(self) def MapMethod(self): # when being mapped the first time, initialise the gcs. this cannot be # done earlier, because the hitgc creates a pixmap which currently # only works after the window (id) has been created. In Xt this can be # done in the Realize widget method (after calling the superclass' # method), but Tk doesn't seem to offer any similar thing. if not self.gcs_initialized: self.init_gcs() self.issue_state() def DestroyMethod(self): # make sure that gc is deleted. gc may have a shared memory ximage # which is not freed if the gc is not destroyed leaving unused shared # memory segments in the system even after the process has finished. self.gc = None PyWidget.DestroyMethod(self) def init_gcs(self): self.gc.init_gc(self.tkwin, graphics_exposures=1) self.gc.draw_visible = self.show_visible self.gc.draw_printable = self.show_printable self.gc.allow_outline = 0 self.gcs_initialized = 1 self.default_view() self.set_gc_transforms() def default_view(self): self.FitPageToWindow() def set_gc_transforms(self): self.gc.SetViewportTransform(self.scale, self.doc_to_win, self.win_to_doc) # # Channels # def issue_state(self): self.queue_message(STATE) def issue_view(self): self.queue_message(VIEW) def issue_document(self): self.doc_changed = 1 def queue_message(self, Publisher): if self.transaction: QueueingPublisher.queue_message(self, Publisher) else: self.issue(Publisher) def init_transactions(self): self.sb_update_pending = 0 self.doc_changed = 0 self.transaction = 0 def begin_transaction(self): self.transaction = self.transaction + 1 def end_transaction(self): self.transaction = self.transaction - 1 if self.transaction == 0: if self.doc_changed: self.issue(DOCUMENT, self.document) self.sb_update_pending = 0 self.doc_changed = 0 self.flush_message_queue() elif self.transaction < 0: raise SketchInternalError('transaction count < 0') # # receivers # def redraw_doc(self, all, rects=None): if all: self.clear_window() else: map(self.clear_area_doc, rects) def layout_changed(self): self.SetPageSize(self.document.Layout().Size()) self.set_gc_transforms() self.update_scrollbars() self.update_rulers() if self.show_page_outline: self.clear_window() def layer_changed(self, *args): if args: redraw = EmptyRect if args[0] == LAYER_STATE: layer, visible_changed, printable_changed, outlined_changed \ = args[1] rect = layer.bounding_rect if rect is not EmptyRect: if self.show_printable and printable_changed: redraw = rect if self.show_visible: if visible_changed: redraw = rect if outlined_changed and layer.Visible(): redraw = rect elif args[0] == LAYER_ORDER: layer = args[1] if (self.show_printable and layer.Printable() or self.show_visible and layer.Visible()): redraw = layer.bounding_rect if len(args) > 2: other = args[2] if (self.show_printable and other.Printable() or self.show_visible and other.Visible()): redraw = IntersectRects(redraw, other.bounding_rect) else: redraw = EmptyRect elif args[0] == LAYER_COLOR: layer = args[1] rect = layer.bounding_rect if self.show_visible and rect is not EmptyRect \ and layer.Visible(): redraw = rect self.clear_area_doc(redraw) # # Widget Methods (Redraw, ... ) # def get_matrix(self): return self.doc_to_win.coeff() time_redraw = 0 def RedrawMethod(self, region=None): # draw the document if self.move_window_count >= 2: self.clear_window(update=0) self.move_window_count = 0 region = self.do_clear(region) tkwin = self.tkwin if region: x, y, w, h = region.ClipBox() if x < 0: w = w - x; x = 0 if y < 0: h = h - y; y = 0 if w > tkwin.width: w = tkwin.width if h > tkwin.height: h = tkwin.height else: x = y = 0 w = tkwin.width h = tkwin.height p1 = self.WinToDoc(x - 1, y - 1) p2 = self.WinToDoc(x + w + 1, y + h + 1) rect = Rect(p1, p2) self.renderer.draw(self.document, rect) return region def ResizedMethod(self, width, height): Viewport.ResizedMethod(self, width, height) self.gc.WindowResized(width, height) if self.widget_size: center = self.WinToDoc(width / 2, height / 2,) dx = ((width - self.widget_size[0]) / 2) / self.scale dy = ((height - self.widget_size[1]) / 2) / self.scale self.SetCenter((center[0] - dx, center[1] + dy)) self.RedrawMethod() self.widget_size = (width, height) # # Viewport- and related methods # # extend some Viewport methods to issue VIEW whenever # the displayed area changes # def ForceRedraw(self): # Force a redraw of the whole window self.clear_window() if __debug__: #self.time_redraw = 1 pass # def SetScrollbars(self, hbar, vbar): # Viewport.SetScrollbars(self, hbar, vbar) # hbar.configure(jump = 1) # vbar.configure(jump = 1) def set_origin(self, xorg, yorg, move_contents=1): self.begin_transaction() try: Viewport.set_origin(self, xorg, yorg, move_contents=move_contents) self.set_gc_transforms() self.issue_view() finally: self.end_transaction() def move_window_contents(self, offx, offy): # implement the method needed by Viewport.set_origin w = self.tkwin width = w.width height = w.height if config.preferences.cairo_enabled : self.clear_window() else: if abs(offx) < width and abs(offy) < height: w.CopyArea(w, self.gc.gc, offx, offy, width, height, 0, 0) self.move_window_count = self.move_window_count + 1 else: self.clear_window() def SetScale(self, scale, do_center=1): # Set current scale self.begin_transaction() try: Viewport.SetScale(self, scale, do_center=do_center) self.set_gc_transforms() finally: self.end_transaction() def zoom_fit_rect(self, rect, save_viewport=0): if save_viewport: self.save_viewport() Viewport.zoom_fit_rect(self, rect) # # other view related methods # def FitToWindow(self, selected_only=0, save_viewport=1): self.begin_transaction() try: if selected_only: rect = self.document.SelectionBoundingRect() else: rect = self.document.BoundingRect() if rect: self.zoom_fit_rect(rect, save_viewport=save_viewport) finally: self.end_transaction() def FitPageToWindow(self, save_viewport=1): self.begin_transaction() try: w, h = self.document.PageSize() self.zoom_fit_rect(Rect(0, 0, w, h), save_viewport=save_viewport) finally: self.end_transaction() # # Outline Mode # # Although not directly related to the viewport methods (the outline # mode doesn't change the displayed area) the outline mode changes the # way the drawing is displayed and thus issues VIEW. def SetOutlineMode(self, on=1): self.begin_transaction() try: if on: if self.gc.IsOutlineActive(): return else: self.gc.StartOutlineMode() self.hitgc.StartOutlineMode() else: if self.gc.IsOutlineActive(): self.gc.EndOutlineMode() self.hitgc.EndOutlineMode() else: return self.issue_view() self.clear_window() finally: self.end_transaction() def ToggleOutlineMode(self): self.SetOutlineMode(not self.IsOutlineMode()) def IsOutlineMode(self): return self.gc and self.gc.IsOutlineActive() # # Show page outline on/off # def SetPageOutlineMode(self, on=1): self.begin_transaction() try: self.show_page_outline = on self.issue_view() self.clear_window() finally: self.end_transaction() def TogglePageOutlineMode(self): self.SetPageOutlineMode(not self.IsPageOutlineMode()) def IsPageOutlineMode(self): return self.show_page_outline # # # def unsubscribe_doc(self): if self.document is not None: self.document.Unsubscribe(REDRAW, self.redraw_doc) self.document.Unsubscribe(LAYOUT, self.layout_changed) self.document.Unsubscribe(LAYER, self.layer_changed) def subscribe_doc(self): self.document.Subscribe(REDRAW, self.redraw_doc) self.document.Subscribe(LAYOUT, self.layout_changed) self.document.Subscribe(LAYER, self.layer_changed) def SetDocument(self, doc): self.begin_transaction() try: self.unsubscribe_doc() self.document = doc self.subscribe_doc() self.clear_window() self.SetPageSize(self.document.Layout().Size()) self.FitPageToWindow(save_viewport=0) self.issue_document() self.issue_state() self.issue_view() finally: self.end_transaction()