def popup_context_menu(self, event): if self.context_menu is None: items = [] set_unit = self.SetUnit for unit in unit_names: items.append(MenuCommand(unit, set_unit, unit)) self.context_menu = UpdatedMenu(self, items, tearoff=0) self.context_menu.Popup(event.x_root, event.y_root)
def popup_context_menu(self, event): self.set_event_context(event) if self.context_menu is None: self.context_menu = UpdatedMenu( self.frame, [], tearoff=0, auto_rebuild=self.build_context_menu) self.context_menu.Popup(event.x_root, event.y_root)
class TEntryExt(TEntry): def __init__(self, master=None, cnf={}, **kw): TEntry.__init__(self, master, kw) self.bind('<ButtonPress-3>', self.popup_context_menu) #--------ContextMenu----------------------------------------------------------- def popup_context_menu(self, event): if self["state"] == NORMAL: self.context_menu = UpdatedMenu( self, [], tearoff=0, auto_rebuild=self.build_context_menu) self.context_menu.Popup(event.x_root, event.y_root) def build_context_menu(self): entries = [] if self.can_cut(): entries += [(_("Cut"), self.cut, (), None, None, 'menu_edit_cut')] if self.can_copy(): entries += [(_("Copy"), self.copy, (), None, None, 'menu_edit_copy')] if self.can_paste(): entries += [(_("Paste"), self.paste, (), None, None, 'menu_edit_paste')] entries += [(_("Clear All"), self.clear_all, (), None, None, 'menu_edit_clear'), (None, 'small_separator'), (_("Select All"), self.select_all, (), None, None)] return map(MakeCommand, entries) def can_cut(self): return self.select_present() def can_copy(self): return self.select_present() def can_paste(self): if self.clipboar_get(): return 1 return 0 def select_all(self): self.select_range(0, END) def clear_all(self): self.delete(0, END) def clipboar_get(self): try: return self.tk.call('::tk::GetSelection', '.', 'CLIPBOARD') except: return None def cut(self): self.tk.call('::ttk::entry::Cut', self._w) def copy(self): self.tk.call('::ttk::entry::Copy', self._w) def paste(self): self.tk.call('::ttk::entry::Paste', self._w)
def PopupContextMenu(self, event): self.context_idx = self.x_to_idx(event.x) self.context_pos = (event.x - self.orig_x) / float(self.ximage.width) if self.context_menu is None: items = [ MenuCommand(_("Set Handle Color"), self.set_handle_color, sensitivecb=self.can_set_handle_color), MenuCommand(_("Delete Handle"), self.delete_handle, sensitivecb=self.can_delete_handle), MenuCommand(_("Insert Handle"), self.insert_handle, sensitivecb=self.can_insert_handle) ] self.context_menu = UpdatedMenu(self, items) self.context_menu.Popup(event.x_root, event.y_root)
class PositionLabel(UpdatedLabel): context_menu = None def __init__(self, *args, **kw): apply(UpdatedLabel.__init__, (self, ) + args, kw) self.bind('<ButtonPress-3>', self.popup_context_menu) self.set_unit(config.preferences.default_unit) config.preferences.Subscribe(CHANGED, self.preference_changed) def Update(self, *rest): if self.sensitivecb: self.SetSensitive(self.sensitivecb()) if self.updatecb and self.update_field: x, y = self.updatecb() x = x / self.factor y = y / self.factor self[self.update_field] = self.format % (x, y) def popup_context_menu(self, event): if self.context_menu is None: items = [] set_unit = self.SetUnit for unit in unit_names: items.append(MenuCommand(unit, set_unit, unit)) self.context_menu = UpdatedMenu(self, items, tearoff=0) self.context_menu.Popup(event.x_root, event.y_root) def set_unit(self, unit): self.factor = unit_dict[unit] self.format = formats[unit] self.Update() def SetUnit(self, unit): self.unit = unit if config.preferences.poslabel_sets_default_unit: config.preferences.default_unit = unit else: self.set_unit(unit) def preference_changed(self, pref, value): if pref == 'default_unit': self.set_unit(value)
def popup_context_menu(self, event): if self["state"] == NORMAL: self.context_menu = UpdatedMenu( self, [], tearoff=0, auto_rebuild=self.build_context_menu) self.context_menu.Popup(event.x_root, event.y_root)
def popup_context_menu(self, event): self.set_event_context(event) if self.context_menu is None: self.context_menu = UpdatedMenu(self.frame, [], tearoff = 0, auto_rebuild = self.build_context_menu) self.context_menu.Popup(event.x_root, event.y_root)
class LayerPanel(SketchPanel): title = _("Layers") receivers = SketchPanel.receivers[:] def __init__(self, master, main_window, doc): self.info_list = [] SketchPanel.__init__(self, master, main_window, doc, name = 'layerdlg') def build_dlg(self): top = self.top frame = Frame(top) frame.pack(side = BOTTOM, fill = X) button = UpdatedButton(frame, bitmap = pixmaps.LayerNew, name = 'new', command = self.new_layer) button.pack(side = LEFT, fill = BOTH, expand = 1) button = UpdatedButton(frame, bitmap = pixmaps.LayerUp, name = 'up', command = self.layer_up) button.pack(side = LEFT, fill = BOTH, expand = 1) button = UpdatedButton(frame, bitmap = pixmaps.LayerDown, name = 'down', command = self.layer_down) button.pack(side = LEFT, fill = BOTH, expand = 1) button = UpdatedButton(frame, text = _("Close"), name = 'close', command = self.close_dlg) button.pack(side = LEFT, fill = BOTH, expand = 1) list_frame = Frame(top) list_frame.pack(side = LEFT, expand = 1, fill = BOTH) sb_vert = Scrollbar(list_frame, takefocus = 0) sb_vert.pack(side = RIGHT, fill = Y) self.canvas = canvas = Canvas(list_frame) canvas.pack(expand = 1, fill = BOTH) self.frame = frame = Frame(canvas, name = 'list') canvas.create_window(0, 0, window = frame, anchor = NW) sb_vert['command'] = (canvas, 'yview') canvas['yscrollcommand'] = (sb_vert, 'set') self.active_var = IntVar(top) def init_from_doc(self): self.Update(LAYER_ORDER) receivers.append((LAYER, 'Update')) def Update(self, detail = '', *args): if detail != LAYER_ACTIVE: if detail == LAYER_ORDER: self.create_widget_list() else: self.update_widgets() self.update_active() def create_widget_list(self): frame = self.frame set_active_layer = self.set_active_layer set_layer_state = self.set_layer_state set_color = self.set_color context_menu = self.popup_context_menu rows = self.info_list layers = self.document.NumLayers() if layers > len(rows): for idx in range(len(rows), layers): row = LayerInfo(frame, idx, (), self.active_var, self.rename_layer, set_active_layer, set_layer_state, set_color, context_menu) row.PlaceWidgets(idx) rows.append(row) elif layers < len(rows): for row in rows[layers:]: row.Destroy() del rows[layers:] self.update_widgets() frame.update() self.canvas['scrollregion'] = (0, 0, frame.winfo_reqwidth(), frame.winfo_reqheight()) self.canvas['width'] = frame.winfo_reqwidth() def update_widgets(self): layers = self.document.layers[:] layers.reverse() for idx in range(len(layers)): self.info_list[idx].SetInfo(idx, layers[idx]) def update_active(self): idx = self.document.ActiveLayerIdx() if idx is None: idx = -1 self.active_var.set(self.document.NumLayers() - 1 - idx) def set_active_layer(self): idx = self.document.NumLayers() - self.active_var.get() - 1 self.document.SetActiveLayer(idx) def set_layer_state(self, idx): idx = int(idx) row = self.info_list[idx] idx = self.document.NumLayers() - idx - 1 state = row.State() apply(self.document.SetLayerState, (idx,) + state) def set_color(self, idx): idx = int(idx) row = self.info_list[idx] idx = self.document.NumLayers() - idx - 1 self.document.SetLayerColor(idx, row.Color()) def set_event_context(self, event): for idx in range(len(self.info_list)): if self.info_list[idx].button == event.widget: break else: return self.context_idx = self.document.NumLayers() - 1 - idx self.context_layer = self.document.Layers()[self.context_idx] context_menu = None def popup_context_menu(self, event): self.set_event_context(event) if self.context_menu is None: self.context_menu = UpdatedMenu(self.frame, [], tearoff = 0, auto_rebuild = self.build_context_menu) self.context_menu.Popup(event.x_root, event.y_root) def build_context_menu(self): entries = [ (_("Rename"), self.rename_layer), None, (_("Lower Layer"), self.layer_down, 0), (_("Raise Layer"), self.layer_up, 0), (_("Delete"), self.delete_layer, (), self.can_delete_layer), None, (_("Move Selection Here"), self.move_selection_here, (), self.can_move_selection), (_("Select All Children"), self.select_layer, SelectAdd, self.is_not_locked), (_("Deselect All Children"), self.select_layer, SelectSubtract, self.is_not_locked) ] if self.context_layer.is_GuideLayer: entries.append(None) entries.append(self.main_window.commands.CreateGuideDialog) if self.context_layer.is_GridLayer: entries.append(None) entries.append(self.main_window.commands.CreateGridDialog) return map(MakeCommand, entries) def close_dlg(self): SketchPanel.close_dlg(self) if self.context_menu is not None: self.context_menu.destroy() def rename_layer(self, event = None): if event is not None: self.set_event_context(event) name = GetName(self.top, self.context_layer.Name()) if name != None: self.document.SetLayerName(self.context_idx, name) def delete_layer(self): self.document.DeleteLayer(self.context_idx) def can_delete_layer(self): return self.document.CanDeleteLayer(self.context_idx) def new_layer(self): self.document.NewLayer() def layer_up(self, active_layer = 1): if active_layer: active_idx = self.active_var.get() if active_idx < 0: return idx = self.document.NumLayers() - 1 - active_idx else: idx = self.context_idx self.document.MoveLayerUp(idx) def layer_down(self, active_layer = 1): if active_layer: active_idx = self.active_var.get() if active_idx < 0: return idx = self.document.NumLayers() - 1 - active_idx else: idx = self.context_idx self.document.MoveLayerDown(idx) def move_selection_here(self): self.document.MoveSelectionToLayer(self.context_idx) def can_move_selection(self): return not self.context_layer.Locked() and self.document.HasSelection() def is_not_locked(self): return not self.context_layer.Locked() def select_layer(self, mode): self.document.SelectLayer(self.context_idx, mode)
class LayerPanel(SketchPanel): title = _("Layers") receivers = SketchPanel.receivers[:] def __init__(self, master, main_window, doc): self.info_list = [] SketchPanel.__init__(self, master, main_window, doc, name='layerdlg') def build_dlg(self): top = self.top frame = Frame(top) frame.pack(side=BOTTOM, fill=X) button = UpdatedButton(frame, bitmap=pixmaps.LayerNew, name='new', command=self.new_layer) button.pack(side=LEFT, fill=BOTH, expand=1) button = UpdatedButton(frame, bitmap=pixmaps.LayerUp, name='up', command=self.layer_up) button.pack(side=LEFT, fill=BOTH, expand=1) button = UpdatedButton(frame, bitmap=pixmaps.LayerDown, name='down', command=self.layer_down) button.pack(side=LEFT, fill=BOTH, expand=1) button = UpdatedButton(frame, text=_("Close"), name='close', command=self.close_dlg) button.pack(side=LEFT, fill=BOTH, expand=1) list_frame = Frame(top) list_frame.pack(side=LEFT, expand=1, fill=BOTH) sb_vert = Scrollbar(list_frame, takefocus=0) sb_vert.pack(side=RIGHT, fill=Y) self.canvas = canvas = Canvas(list_frame) canvas.pack(expand=1, fill=BOTH) self.frame = frame = Frame(canvas, name='list') canvas.create_window(0, 0, window=frame, anchor=NW) sb_vert['command'] = (canvas, 'yview') canvas['yscrollcommand'] = (sb_vert, 'set') self.active_var = IntVar(top) def init_from_doc(self): self.Update(LAYER_ORDER) receivers.append((LAYER, 'Update')) def Update(self, detail='', *args): if detail != LAYER_ACTIVE: if detail == LAYER_ORDER: self.create_widget_list() else: self.update_widgets() self.update_active() def create_widget_list(self): frame = self.frame set_active_layer = self.set_active_layer set_layer_state = self.set_layer_state set_color = self.set_color context_menu = self.popup_context_menu rows = self.info_list layers = self.document.NumLayers() if layers > len(rows): for idx in range(len(rows), layers): row = LayerInfo(frame, idx, (), self.active_var, self.rename_layer, set_active_layer, set_layer_state, set_color, context_menu) row.PlaceWidgets(idx) rows.append(row) elif layers < len(rows): for row in rows[layers:]: row.Destroy() del rows[layers:] self.update_widgets() frame.update() self.canvas['scrollregion'] = (0, 0, frame.winfo_reqwidth(), frame.winfo_reqheight()) self.canvas['width'] = frame.winfo_reqwidth() def update_widgets(self): layers = self.document.layers[:] layers.reverse() for idx in range(len(layers)): self.info_list[idx].SetInfo(idx, layers[idx]) def update_active(self): idx = self.document.ActiveLayerIdx() if idx is None: idx = -1 self.active_var.set(self.document.NumLayers() - 1 - idx) def set_active_layer(self): idx = self.document.NumLayers() - self.active_var.get() - 1 self.document.SetActiveLayer(idx) def set_layer_state(self, idx): idx = int(idx) row = self.info_list[idx] idx = self.document.NumLayers() - idx - 1 state = row.State() apply(self.document.SetLayerState, (idx, ) + state) def set_color(self, idx): idx = int(idx) row = self.info_list[idx] idx = self.document.NumLayers() - idx - 1 self.document.SetLayerColor(idx, row.Color()) def set_event_context(self, event): for idx in range(len(self.info_list)): if self.info_list[idx].button == event.widget: break else: return self.context_idx = self.document.NumLayers() - 1 - idx self.context_layer = self.document.Layers()[self.context_idx] context_menu = None def popup_context_menu(self, event): self.set_event_context(event) if self.context_menu is None: self.context_menu = UpdatedMenu( self.frame, [], tearoff=0, auto_rebuild=self.build_context_menu) self.context_menu.Popup(event.x_root, event.y_root) def build_context_menu(self): entries = [(_("Rename"), self.rename_layer), None, (_("Lower Layer"), self.layer_down, 0), (_("Raise Layer"), self.layer_up, 0), (_("Delete"), self.delete_layer, (), self.can_delete_layer), None, (_("Move Selection Here"), self.move_selection_here, (), self.can_move_selection), (_("Select All Children"), self.select_layer, SelectAdd, self.is_not_locked), (_("Deselect All Children"), self.select_layer, SelectSubtract, self.is_not_locked)] if self.context_layer.is_GuideLayer: entries.append(None) entries.append(self.main_window.commands.CreateGuideDialog) if self.context_layer.is_GridLayer: entries.append(None) entries.append(self.main_window.commands.CreateGridDialog) return map(MakeCommand, entries) def close_dlg(self): SketchPanel.close_dlg(self) if self.context_menu is not None: self.context_menu.destroy() def rename_layer(self, event=None): if event is not None: self.set_event_context(event) name = GetName(self.top, self.context_layer.Name()) if name != None: self.document.SetLayerName(self.context_idx, name) def delete_layer(self): self.document.DeleteLayer(self.context_idx) def can_delete_layer(self): return self.document.CanDeleteLayer(self.context_idx) def new_layer(self): self.document.NewLayer() def layer_up(self, active_layer=1): if active_layer: active_idx = self.active_var.get() if active_idx < 0: return idx = self.document.NumLayers() - 1 - active_idx else: idx = self.context_idx self.document.MoveLayerUp(idx) def layer_down(self, active_layer=1): if active_layer: active_idx = self.active_var.get() if active_idx < 0: return idx = self.document.NumLayers() - 1 - active_idx else: idx = self.context_idx self.document.MoveLayerDown(idx) def move_selection_here(self): self.document.MoveSelectionToLayer(self.context_idx) def can_move_selection(self): return not self.context_layer.Locked() and self.document.HasSelection() def is_not_locked(self): return not self.context_layer.Locked() def select_layer(self, mode): self.document.SelectLayer(self.context_idx, mode)
class GradientView(PyWidget, Publisher): accept_drop = (DROP_COLOR, ) def __init__(self, master, width, height, gradient, **kw): image = PIL.Image.new('RGB', (width, height)) self.orig_x = handle_height / 2 if not kw.has_key('width'): kw["width"] = width + handle_height if not kw.has_key('height'): kw["height"] = height + handle_height apply(PyWidget.__init__, (self, master), kw) self.set_gradient(gradient) self.update_pending = 0 self.dragging = 0 self.drag_idx = 0 self.drag_start = 0 self.drag_min = self.drag_max = 0.0 self.gc_initialized = 0 self.image = image self.ximage = None self.context_menu = None self.bind('<ButtonPress-3>', self.PopupContextMenu) self.bind('<ButtonPress>', self.ButtonPressEvent) self.bind('<Motion>', self.PointerMotionEvent) self.bind('<ButtonRelease>', self.ButtonReleaseEvent) def __del__(self): pdebug('__del__', '__del__', self) def MapMethod(self): if not self.gc_initialized: self.init_gc() self.tk.call(self._w, 'motionhints') self.gc_initialized = 1 def DestroyMethod(self): if self.context_menu is not None: self.context_menu.clean_up() self.context_menu = None PyWidget.DestroyMethod(self) def init_gc(self): self.gc = self.tkwin.GetGC() self.visual = color.skvisual w = self.tkwin width, height = self.image.size depth = self.visual.depth if depth > 16: bpl = 4 * width elif depth > 8: bpl = ((2 * width + 3) / 4) * 4 elif depth == 8: bpl = ((width + 3) / 4) * 4 else: raise SketchError('unsupported depth for images') self.ximage = w.CreateImage(depth, X.ZPixmap, 0, None, width, height, 32, bpl) self.set_image(self.image) def set_image(self, image): self.image = image if self.ximage: ximage = self.ximage _sketch.copy_image_to_ximage(self.visual, image.im, ximage, 0, 0, ximage.width, ximage.height) self.UpdateWhenIdle() def ResizedMethod(self, width, height): pass def set_gradient(self, gradient): gradient = gradient.Colors() self.gradient = [] for pos, color in gradient: self.gradient.append((pos, tuple(color))) def reverse(self): for i in range(len(self.gradient)): self.gradient[i] = (1 - self.gradient[i][0], self.gradient[i][1]) self.gradient.reverse() self.UpdateWhenIdle() def x_to_idx(self, x): width = self.ximage.width w2 = handle_height / 2 orig_x = self.orig_x for i in range(len(self.gradient)): if abs(x - orig_x - self.gradient[i][0] * width) < w2: return i return -1 def ButtonPressEvent(self, event): if not self.dragging: self.drag_idx = self.x_to_idx(event.x) if self.drag_idx < 0: return if self.drag_idx == 0: self.gradient.insert(0, self.gradient[0]) self.drag_idx = self.drag_idx + 1 if self.drag_idx == len(self.gradient) - 1: self.gradient.append(self.gradient[-1]) self.drag_start = event.x, self.gradient[self.drag_idx][0] if self.drag_idx > 0: self.drag_min = self.gradient[self.drag_idx - 1][0] else: self.drag_min = 0.0 if self.drag_idx < len(self.gradient) - 1: self.drag_max = self.gradient[self.drag_idx + 1][0] else: self.drag_max = 1.0 self.dragging = self.dragging + 1 def ButtonReleaseEvent(self, event): if self.dragging: self.dragging = self.dragging - 1 self.move_to(event.x) if self.drag_idx == 1 and \ self.gradient[0][0] == self.gradient[1][0]: del self.gradient[0] elif self.drag_idx == len(self.gradient) - 2 and \ self.gradient[-1][0] == self.gradient[-2][0]: del self.gradient[-1] def PointerMotionEvent(self, event): if self.dragging: x = self.tkwin.QueryPointer()[4] self.move_to(x) def move_to(self, x): start_x, start_pos = self.drag_start pos = x - start_x + start_pos * self.ximage.width pos = float(pos) / self.ximage.width if pos < self.drag_min: pos = self.drag_min if pos > self.drag_max: pos = self.drag_max color = self.gradient[self.drag_idx][-1] self.gradient[self.drag_idx] = (pos, color) self.UpdateWhenIdle() def PopupContextMenu(self, event): self.context_idx = self.x_to_idx(event.x) self.context_pos = (event.x - self.orig_x) / float(self.ximage.width) if self.context_menu is None: items = [ MenuCommand(_("Set Handle Color"), self.set_handle_color, sensitivecb=self.can_set_handle_color), MenuCommand(_("Delete Handle"), self.delete_handle, sensitivecb=self.can_delete_handle), MenuCommand(_("Insert Handle"), self.insert_handle, sensitivecb=self.can_insert_handle) ] self.context_menu = UpdatedMenu(self, items) self.context_menu.Popup(event.x_root, event.y_root) def delete_handle(self): if 0 < self.context_idx < len(self.gradient) - 1: del self.gradient[self.context_idx] self.UpdateWhenIdle() def can_delete_handle(self): return 0 < self.context_idx < len(self.gradient) - 1 def insert_handle(self): gradient = self.gradient pos = self.context_pos if 0.0 <= pos <= 1.0: for i in range(len(gradient) - 1): if gradient[i][0] < pos < gradient[i + 1][0]: p1, c1 = gradient[i] p2, c2 = gradient[i + 1] color = Blend(apply(CreateRGBColor, c2), apply(CreateRGBColor, c1), (pos - p1) / (p2 - p1)) gradient.insert(i + 1, (pos, tuple(color))) self.UpdateWhenIdle() break def can_insert_handle(self): return self.context_idx < 0 and 0.0 <= self.context_pos <= 1.0 def set_handle_color(self): if self.context_idx >= 0: pos, color = self.gradient[self.context_idx] color = GetColor(self, apply(CreateRGBColor, color)) if color is not None: self.gradient[self.context_idx] = (pos, tuple(color)) self.UpdateWhenIdle() def can_set_handle_color(self): return self.context_idx >= 0 def update_gradient(self): _sketch.fill_axial_gradient(self.image.im, self.gradient, 0, 0, self.image.size[0] - 1, 0) self.set_image(self.image) def UpdateWhenIdle(self): if not self.update_pending: self.update_pending = 1 PyWidget.UpdateWhenIdle(self) def RedrawMethod(self, region=None): if self.update_pending: self.update_gradient() self.update_pending = 0 pixmap = self.tkwin.CreatePixmap() width = self.ximage.width height = self.ximage.height startx = handle_height / 2 self.gc.SetDrawable(pixmap) self.tkborder.Fill3DRectangle(pixmap, 0, 0, self.tkwin.width, self.tkwin.height, 0, pax.TK_RELIEF_FLAT) self.gc.PutImage(self.ximage, 0, 0, startx, 0, width, height) border = self.tkborder win = self.tkwin w2 = handle_height / 2 bot = handle_height + height for pos in self.gradient: pos = pos[0] x = int(pos * width) + startx poly = [(x - w2, bot), (x, height), (x + w2, bot)] border.Draw3DPolygon(pixmap, poly, -2, pax.TK_RELIEF_SUNKEN) self.gc.SetDrawable(self.tkwin) pixmap.CopyArea(self.tkwin, self.gc, 0, 0, self.tkwin.width, self.tkwin.height, 0, 0) def DropAt(self, x, y, what, data): if what == DROP_COLOR: idx = self.x_to_idx(x) if idx >= 0: pos, color = self.gradient[idx] self.gradient[idx] = (pos, tuple(data)) self.UpdateWhenIdle() def GetGradient(self): result = [] for pos, color in self.gradient: result.append((pos, apply(CreateRGBColor, color))) return MultiGradient(result)