# Sketch - A Python-based interactive drawing program
# Copyright (C) 1997, 1998, 2000 by Bernhard Herzog
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# A dialog to rearrange the layers of the document and change some of
# their properties.
from Tkinter import Button,Scrollbar,Frame,IntVar,Canvas,Label
from Tkinter import RIGHT,BOTTOM,X,Y,BOTH,LEFT,W,NW,NORMAL,DISABLED
from Sketch.const import LAYER,LAYER_ACTIVE,LAYER_ORDER,\
SelectSubtract, SelectAdd
from Sketch import _
from tkext import UpdatedButton,MyEntry,UpdatedCheckbutton,\
ColorButton, UpdatedRadiobutton, MenuCommand, UpdatedMenu, MakeCommand
from sketchdlg import SketchPanel,SKModal
import skpixmaps
pixmaps = skpixmaps.PixmapTk
class MutableNumber:
def __init__(self, value = 0):
self.value = value
def SetValue(self, value):
self.value = value
def __int__(self):
return int(self.value)
def __str__(self):
return str(self.value)
def __repr__(self):
return `self.value`
class LayerInfo:
def __init__(self, frame, idx, info, active_var, rename, set_active_layer,
set_layer_state, set_color, context_menu):
self.index = MutableNumber()
self.active_var = active_var
self.create_widgets(frame, idx, set_active_layer, rename,
set_layer_state, set_color, context_menu)
if info:
self.SetInfo(info)
def create_widgets(self, frame, idx, set_active_layer, rename,
set_layer_state, set_color, context_menu):
self.index.SetValue(idx)
idx = (self.index,)
self.button = UpdatedRadiobutton(frame, anchor = W, value = idx,
width = 10,
variable = self.active_var,
command = set_active_layer)
self.button.bind('<ButtonPress-3>', context_menu)
self.button.bind('<ButtonPress-2>', rename)
self.button.bind('<Double-Button-1>', rename)
self.var_visible = IntVar(frame)
self.visible = UpdatedCheckbutton(frame, variable = self.var_visible,
indicatoron = 0, selectcolor = '',
command = set_layer_state,
args = idx)
self.var_printable = IntVar(frame)
self.printable = UpdatedCheckbutton(frame,
variable = self.var_printable,
indicatoron = 0, selectcolor = '',
command = set_layer_state,
args = idx)
self.var_locked = IntVar(frame)
self.locked = UpdatedCheckbutton(frame, variable = self.var_locked,
indicatoron = 0, selectcolor = '',
command = set_layer_state, args = idx)
self.var_outlined = IntVar(frame)
self.outlined = UpdatedCheckbutton(frame, variable = self.var_outlined,
indicatoron = 0, selectcolor = '',
command = set_layer_state,
args = idx)
self.color = ColorButton(frame, command = set_color, args = idx,
width = 2,
dialog_master =
frame.master.master.master.master)
def SetInfo(self, idx, info):
self.index.SetValue(idx)
p = pixmaps
#name, visible, printable, locked, outlined, color = info
self.button['text'] = info.Name()
visible = info.Visible()
self.var_visible.set(visible)
self.visible['bitmap'] = visible and p.MiniEyeOpen or p.MiniEyeClosed
printable = info.Printable()
self.var_printable.set(printable)
self.printable['bitmap']= printable and p.MiniPrintOn or p.MiniPrintOff
locked = info.Locked()
self.var_locked.set(locked)
self.locked['bitmap'] = locked and p.MiniLockClosed or p.MiniLockOpen
outlined = info.Outlined()
self.var_outlined.set(outlined)
bm = outlined and p.MiniOutlineOn or p.MiniOutlineOff
self.outlined['bitmap'] = bm
self.color.SetColor(info.OutlineColor())
if info.is_GridLayer:
self.locked['state'] = self.outlined['state'] \
= self.printable['state'] = DISABLED
else:
self.locked['state'] = NORMAL
if info.is_GuideLayer:
self.printable['state'] = self.outlined['state'] = DISABLED
else:
self.printable['state'] = self.outlined['state'] = NORMAL
def PlaceWidgets(self, idx):
self.button.grid(row = idx, column = 0, sticky = 'NEWS')
self.visible.grid(row = idx, column = 1, sticky = 'NEWS')
self.printable.grid(row = idx, column = 2, sticky = 'NEWS')
self.locked.grid(row = idx, column = 3, sticky = 'NEWS')
self.outlined.grid(row = idx, column = 4, sticky = 'NEWS')
self.color.grid(row = idx, column = 5, sticky = 'NEWS')
def State(self):
return (self.var_visible.get(),
self.var_printable.get(),
self.var_locked.get(),
self.var_outlined.get())
def Color(self):
return self.color.Color()
def Destroy(self):
self.button.destroy()
self.visible.destroy()
self.printable.destroy()
self.locked.destroy()
self.outlined.destroy()
self.color.destroy()
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 GetNameDlg(SKModal):
title = _("Name")
def __init__(self, master, name, **kw):
self.name = name
apply(SKModal.__init__, (self, master), kw)
def build_dlg(self):
top = self.top
frame = Frame(top)
frame.pack(side = BOTTOM, fill = BOTH, expand = 1)
button = Button(frame, text = _("OK"), command = self.ok)
button.pack(side = LEFT, expand = 1)
button = Button(frame, text = _("Cancel"), command = self.cancel)
button.pack(side = RIGHT, expand = 1)
self.label = Label(top, text = _("Name"))
self.label.pack(side = LEFT)
self.entry = MyEntry(top, command = self.ok)
self.entry.pack(side = RIGHT, expand = 1, fill = X)
self.entry.SetText(self.name)
def ok(self, *args):
self.close_dlg(self.entry.get())
def GetName(master, name):
dlg = GetNameDlg(master, name)
return dlg.RunDialog()
|