sketchdlg.py :  » GUI » Sketch » skencil-0.6.17 » Sketch » UI » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » Sketch 
Sketch » skencil 0.6.17 » Sketch » UI » sketchdlg.py
# Sketch - A Python-based interactive drawing program
# Copyright (C) 1997, 1998, 1999, 2003 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

#
# Base Classes for Panels
#
# A Panel is an additional toplevel window that allows the user to
# manipulate properties of the document or the current selection. Panels
# are usually also additional Views of the document.
#
#
# Classes:
#
#
# SketchPanel
#
# Base class for all panels. Implements some standard behaviour and
# features, auch as managing the current document, passing document
# messages on to its widgets, saving preferences when the window is
# closed and functions to create some standard buttons.
#
# SketchPanel is used as an immediate base class for panels that affect
# the document as a whole or are independent from properties of the
# currently selected objects (LayerPanel, GridPanel and LayoutPanel for
# instance).
#
#
# PropertyPanel(SketchPanel)
#
# A panel derived from PropertyPanel is a panel that shows properties of
# the current selected objects and allows the user to change them.
#
# Baseclass for dialogs that display and change properties of the
# current selection (FillPanel and StylePanel for instance).
#
#
# CommandPanel(SketchPanel)
#
# A base class for panels that basically offer some commands that are
# either not accesible fom the menu or are more convenient on a seperate
# Panel (CurvePanel and AlignPanel for instance)
#

from types import StringType

from Sketch.warn import pdebug,warn_tb,INTERNAL
from Sketch import _,Publisher
from Sketch.const import SELECTION,DOCUMENT,EDITED,CLOSED
from Sketch import config
import Sketch

from Tkinter import Toplevel,IntVar,Frame,Checkbutton,Label
from Tkinter import TOP,LEFT,RIGHT,BOTTOM,X,BOTH,TkVersion

from tkext import UpdatedButton
import tkext
import skpixmaps
pixmaps = skpixmaps.PixmapTk



class SketchPanel(Publisher):

    # SketchPanel.receivers is a list of tuples of the form
    #    (CHANNEL, FUNCTION[, ARG, ...])
    # SketchPanel automatically installs FUNCTION as a receiver for
    # CHANNEL. FUNCTION will be calles with ARG,.. as arguments. derived
    # classes should copy this list and append their own additional
    # receivers.

    receivers = [(SELECTION, 'issue', SELECTION)]

    title = 'Skencil'    # The window title
    class_name = 'SKPanel'  # the class_name for resources

    x_correction = 0
    y_correction = 0

    def __init__(self, master, main_window, doc, **kw):
  self.master = master
  self.main_window = main_window
  self.document = None

  kw['class'] = self.class_name
  top = apply(Toplevel, (master,), kw)
  top.title(self.title)
  self.pref_pos_name = 'dlg_pos_' + self.__class__.__name__
  if config.preferences.panel_use_coordinates:
      posx, posy = config.get_preference(self.pref_pos_name, (0.1, 0.1))
      # avoid confusing behaviour of panels if the position is negative
      # or > 1:
      posx = max(min(posx, 1), 0)
      posy = max(min(posy, 1), 0)

      posx = master.winfo_rootx() + int(posx * master.winfo_width())
      posy = master.winfo_rooty() + int(posy * master.winfo_height())
      top.geometry('%+d%+d' % (posx, posy))

  top.transient(master)
  top.group(master)
  top.iconname(self.title)
  top.iconbitmap(pixmaps.Icon)
  top.iconmask(pixmaps.Icon_mask)
  top.protocol('WM_DELETE_WINDOW',
         tkext.MakeMethodCommand(self.close_dlg))
  # the following is a workaround for a Tkinter bug. Tkinter 1.63
  # doesn't like bindings for the Destroy event.
  top.tk.call('bind', top._w, '<Destroy>',
        tkext.MakeMethodCommand(self.destroyed) + ('%W',))

  self.top = top
  self.build_dlg()
  self.SetDocument(doc)

  self.main_window.Subscribe(DOCUMENT, self.doc_changed)

  if config.preferences.panel_use_coordinates \
     and config.preferences.panel_correct_wm:
      if not top.winfo_ismapped():
    top.wait_visibility()
      self.x_correction = posx - top.winfo_rootx()
      self.y_correction = posy - top.winfo_rooty()

    if __debug__:
  def __del__(self):
      pdebug('__del__', '__del__', self)

    def deiconify_and_raise(self):
  self.top.deiconify()
  self.top.tkraise()

    def withdraw(self):
  self.top.withdraw()

    def doc_changed(self, doc):
  self.SetDocument(doc)

    def doc_has_selection(self):
  return self.document.HasSelection()

    def destroyed(self, widget, *args):
  if widget == self.top._w:
      self.save_prefs()

    def subscribe_receivers(self):
  for info in self.receivers:
      apply(self.document.Subscribe,
      (info[0], getattr(self, info[1])) + info[2:])

    def unsubscribe_receivers(self):
  for info in self.receivers:
      apply(self.document.Unsubscribe,
      (info[0], getattr(self, info[1])) + info[2:])

    def SetDocument(self, doc):
  if self.document:
      self.unsubscribe_receivers()
  self.document = doc
  self.init_from_doc()
  self.subscribe_receivers()

    def save_prefs(self):
  # Save preferences. Called when dialog is closed.
  master = self.master
  top = self.top
  width = float(master.winfo_width())
  height = float(master.winfo_height())
  posx = (top.winfo_rootx() + self.x_correction - master.winfo_rootx())\
         / width
  posy = (top.winfo_rooty() + self.y_correction - master.winfo_rooty())\
         / height
  setattr(config.preferences, self.pref_pos_name, (posx, posy))

    def close_dlg(self):
  self.issue(CLOSED, self)
  if self.document:
      self.unsubscribe_receivers()
  self.document = None
  try:
      self.main_window.Unsubscribe(DOCUMENT, self.doc_changed)
  except:
      warn_tb(INTERNAL)
  self.main_window = None
  Publisher.Destroy(self)
  self.save_prefs()
  self.top.destroy()
  self.master = None
  import pax
  pax.unregister_object(self)

    def create_std_buttons(self, master):
  frame = Frame(master)

  button = UpdatedButton(frame, text = _("Apply"),
             command = self.do_apply,
             sensitivecb = self.can_apply)
  button.pack(side = LEFT, expand = 1, fill = X)
  button = UpdatedButton(frame, text = _("Close"),
             command = self.close_dlg)
  button.pack(side = RIGHT, expand = 1, fill = X)

  return frame

    def build_dlg(self):
  # Build the dialog window. Must be provided by the subclasses.
  pass

    def init_from_doc(self):
  # Called whenever the document changes and from __init__
  pass

    def Update(self):
  # Called when the selection changes.
  pass

    def do_apply(self):
  # called by the `Apply' standard button to apply the settings
  pass

    def can_apply(self):
  return 1


class PropertyPanel(SketchPanel):

    receivers = SketchPanel.receivers[:]

    def __init__(self, master, main_window, doc, *args, **kw):
  self.var_auto_update = IntVar(master)
  self.var_auto_update.set(1)
  apply(SketchPanel.__init__, (self, master, main_window, doc) +args, kw)

    receivers.append((SELECTION, 'selection_changed'))
    receivers.append((EDITED, 'selection_changed'))
    def selection_changed(self, *args):
  if self.var_auto_update.get():
      self.Update()

    def create_std_buttons(self, master, update_from = 1):
  button_frame = Frame(master)

  button = Checkbutton(button_frame, text = _("Auto Update"),
           variable = self.var_auto_update)
  button.pack(side = TOP, expand = 1, fill = X)

  if update_from:
      button = UpdatedButton(button_frame, text = _("Update From..."),
           command = self.update_from_object)
      button.pack(side = TOP, expand = 1, fill = X)

  button = UpdatedButton(button_frame, text = _("Apply"),
             command = self.do_apply,
             sensitivecb = self.can_apply)
  button.pack(side = LEFT, expand = 1, fill = X)
  self.Subscribe(SELECTION, button.Update)
  button = UpdatedButton(button_frame, text = _("Close"),
             command = self.close_dlg)
  button.pack(side = RIGHT, expand = 1, fill = X)

  return button_frame

    def update_from_object(self):
  self.main_window.canvas.PickObject(self.update_from_object_cb)

    def update_from_object_cb(self, obj):
  pass

    can_apply = SketchPanel.doc_has_selection

    def SetDocument(self, doc):
  SketchPanel.SetDocument(self, doc)
  self.selection_changed()


class StylePropertyPanel(PropertyPanel):

    def can_apply(self):
        return PropertyPanel.can_apply(self) \
               or config.preferences.set_default_properties

    def set_properties(self, title, category, kw):
        import styledlg
        styledlg.set_properties(self.master, self.document, title, category,
                                kw)


class CommandPanel(SketchPanel):

    pass


#
#  Modal dialogs...
#

class SKModal:

    title = ''

    class_name = 'SKModal'

    old_focus = None
    focus_widget = None

    def __init__(self, master, **kw):
  self.master = master

  kw['class'] = self.class_name
  top = apply(Toplevel, (master,), kw)
  top.title(self.title)
  top.transient(master)
  top.group(master)
  top.iconname(self.title)
  top.iconbitmap(pixmaps.Icon)
  top.iconmask(pixmaps.Icon_mask)
  top.protocol('WM_DELETE_WINDOW', self.close_dlg)

  self.top = top
  self.build_dlg()
  mcx = master.winfo_rootx() + master.winfo_width()/ 2
  mcy = master.winfo_rooty() + master.winfo_height() / 2
  top.withdraw()
  top.update()
  width = top.winfo_reqwidth()
  height = top.winfo_reqheight()
  posx = max(min(top.winfo_screenwidth() - width, mcx - width / 2), 0)
  posy = max(min(top.winfo_screenheight() - height, mcy - height / 2), 0)
  top.geometry('%+d%+d' % (posx, posy))
  top.deiconify()

  self.result = None

    if __debug__:
  def __del__(self):
      pdebug('__del__', '__del__', self)

    def build_dlg(self):
  pass

    def ok(self, *args):
  self.close_dlg()

    def cancel(self):
  self.close_dlg(None)

    def close_dlg(self, result = None):
  self.result = result
  if self.old_focus is not None:
      self.old_focus.focus_set()
      self.old_focus = None
  self.top.destroy()

    def RunDialog(self, grab = 1):
  try:
      self.old_focus = self.top.focus_get()
  except KeyError:
      # focus_get fails when the focus widget is a torn-off menu,
      # since there#s no corresponding Tkinter object.
      self.old_focus = None
  grab_widget = None
  if grab:
      if not self.top.winfo_ismapped():
    self.top.wait_visibility()
      grab_widget = self.top.grab_current()
      if grab_widget is not None:
    grab_status = grab_widget.grab_status()
      self.top.grab_set()
  if self.focus_widget is not None:
      self.focus_widget.focus_set()
  else:
      self.top.focus_set()
  self.result = None
  self.master.wait_window(self.top)
  if grab_widget is not None:
      if grab_status == 'global':
    grab_widget.grab_set_global()
      else:
    grab_widget.grab_set()
  return self.result


class MessageDialog(SKModal):

    class_name = 'SKMessageDialog'

    def __init__(self, master, title, message, buttons = _("OK"), default = 0,
     bitmap = 'warning', dlgname = '__dialog__'):
  self.title = title
  self.message = message
  if type(buttons) != type(()):
      buttons = (buttons,)
  self.buttons = buttons
  self.default = default
  self.bitmap = bitmap
  SKModal.__init__(self, master, name = dlgname)

    def build_dlg(self):
  top = self.top
  frame = Frame(top, name = 'top')
  frame.pack(side = TOP, fill = BOTH, expand = 1)
        bitmap = pixmaps.load_image(self.bitmap)
        if type(bitmap) == StringType:
            label = Label(frame, bitmap = bitmap, name = 'bitmap')
        else:
            label = Label(frame, image = bitmap, name = 'bitmap')
  label.pack(side = LEFT, padx = 5, pady = 5)
  label = Label(frame, text = self.message, name = 'msg')
  label.pack(side = RIGHT, fill = BOTH, expand = 1, padx = 5, pady = 5)

  frame = Frame(top, name = 'bot')
  frame.pack(side = BOTTOM, fill = X, expand = 1)
  command = self.ok
  for i in range(len(self.buttons)):
      button = UpdatedButton(frame, text = self.buttons[i],
           command = command, args = i)
      button.grid(column = i, row = 0, sticky = 'ew', padx = 10)
            if i == self.default:
                if TkVersion >= 8.0:
                    button['default'] = 'active'
                self.focus_widget = button
            else:
                if TkVersion >= 8.0:
                    button['default'] = 'normal'

  if self.default is not None:
      top.bind('<Return>', self.invoke_default)

    def ok(self, pos):
  self.close_dlg(pos)

    def invoke_default(self, *rest):
  self.ok(self.default)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.