class PatternSample(PyWidget): def __init__(self, master=None, **kw): apply(PyWidget.__init__, (self, master), kw) self.gc_initialized = 0 self.gc = GraphicsDevice() self.pattern = EmptyPattern self.properties = PropertyStack() self.properties.AddStyle(EmptyLineStyle) self.properties.SetProperty(fill_pattern = self.pattern) self.gc.SetProperties(self.properties) self.fill_rect = None def MapMethod(self): self.fill_rect = Rect(0, 0, self.tkwin.width, self.tkwin.height) if not self.gc_initialized: self.init_gc() self.gc_initialized = 1 def init_gc(self): self.gc.init_gc(self.tkwin) self.compute_trafo() def compute_trafo(self): height = self.tkwin.height doc_to_win = Trafo(1, 0, 0, -1, 0, height) win_to_doc = doc_to_win.inverse() self.gc.SetViewportTransform(1.0, doc_to_win, win_to_doc) self.fill_rect = Rect(0, 0, self.tkwin.width, self.tkwin.height) self.gc.SetProperties(self.properties, self.fill_rect) def SetPattern(self, pattern): if pattern != self.pattern: self.pattern = pattern self.UpdateWhenIdle() self.properties.SetProperty(fill_pattern = pattern) self.gc.SetProperties(self.properties, self.fill_rect) def RedrawMethod(self, region = None): win = self.tkwin self.gc.StartDblBuffer() self.gc.SetFillColor(StandardColors.white) self.gc.FillRectangle(0, 0, win.width, win.height) if self.properties.HasFill(): self.gc.Rectangle(Trafo(win.width, 0, 0, win.height, 0, 0)) else: self.gc.SetLineColor(StandardColors.black) self.gc.DrawLineXY(0, win.height, win.width, 0) self.gc.EndDblBuffer() def ResizedMethod(self, width, height): self.gc.WindowResized(width, height) self.UpdateWhenIdle() self.compute_trafo()
class PaletteWidget(PyWidget, Publisher): def __init__(self, master=None, palette=None, cell_size=16, **kw): if not kw.has_key('height'): kw['height'] = 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.palette = None if palette is None: palette = RGBPalette() self.SetPalette(palette) self.dragging = 0 self.bind('<ButtonPress-1>', self.press_1) self.bind('<Motion>', self.move_1) self.bind('<ButtonRelease-1>', self.release_1) self.bind('<ButtonRelease-3>', self.apply_color_2) def DestroyMethod(self): self.palette.Unsubscribe(CHANGED, self.palette_changed) Publisher.Destroy(self) def compute_num_cells(self): self.num_cells = self.tkwin.width / self.cell_size + 1 def MapMethod(self): self.compute_num_cells() self.issue(VIEW) 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 + x / self.cell_size if i < len(self.palette): return apply(CreateRGBColor, self.palette.GetRGB(i)) def release_1(self, event): try: if self.dragging: self.drop_color(event) else: self.apply_color_1(event) finally: self.dragging = 0 def drop_color(self, event): self['cursor'] = self.drag_old_cursor w = self.winfo_containing(event.x_root, event.y_root) while w and w != self: if __debug__: pdebug('DND', 'trying to drop on', w) try: accepts = w.accept_drop except AttributeError: accepts = () if DROP_COLOR in accepts: x = event.x_root - w.winfo_rootx() y = event.y_root - w.winfo_rooty() w.DropAt(x, y, DROP_COLOR, self.drag_start) break if w != w.winfo_toplevel(): parent = self.tk.call('winfo', 'parent', w._w) w = self.nametowidget(parent) else: break 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): if event.state & X.Button1Mask: if not self.dragging: self.dragging = 1 self.drag_old_cursor = self['cursor'] self['cursor'] = CurDragColor w = self.winfo_containing(event.x_root, event.y_root) def Palette(self): return self.palette def SetPalette(self, palette): if self.palette is not None: self.palette.Unsubscribe(CHANGED, self.palette_changed) self.palette = palette self.palette.Subscribe(CHANGED, self.palette_changed) self.palette_changed() def palette_changed(self): self.compute_num_cells() self.normalize_start() self.issue(VIEW) self.UpdateWhenIdle() def RedrawMethod(self, region=None): win = self.tkwin width = win.width height = win.height self.gc.StartDblBuffer() self.gc.SetFillColor(StandardColors.white) self.gc.FillRectangle(0, 0, width, height) x = 0 FillRectangle = self.gc.FillRectangle SetFillColor = self.gc.SetFillColor create_color = CreateRGBColor rgbs = self.palette.Colors() rgbs = rgbs[self.start_idx:self.start_idx + self.num_cells] for rgb in rgbs: SetFillColor(apply(create_color, rgb)) FillRectangle(x, 0, x + height, height) x = x + height 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.palette) 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.palette) - self.start_idx > self.num_cells def ScrollXPages(self, count): length = self.tkwin.width / 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() self.issue(VIEW) 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() self.issue(VIEW)