gimp r26336 - in branches/soc-2008-python: . plug-ins/pygimp plug-ins/pygimp/plug-ins



Author: larsc
Date: Tue Jul 29 19:33:35 2008
New Revision: 26336
URL: http://svn.gnome.org/viewvc/gimp?rev=26336&view=rev

Log:
2008-07-29  Lars-Peter Clausen  <lars metafoo de>

	* plug-ins/pygimp/gimpfu.py: Refactored the interactive mode code. Moved all
	widget code to a new subclass of gimp.Dialog.
	Added support to specifiy a custom layout for plugins.
	* plug-ins/pygimp/plug-ins/sphere.py: Added testcode for the new layout
	parameter of register.



Modified:
   branches/soc-2008-python/ChangeLog
   branches/soc-2008-python/plug-ins/pygimp/gimpfu.py
   branches/soc-2008-python/plug-ins/pygimp/plug-ins/sphere.py

Modified: branches/soc-2008-python/plug-ins/pygimp/gimpfu.py
==============================================================================
--- branches/soc-2008-python/plug-ins/pygimp/gimpfu.py	(original)
+++ branches/soc-2008-python/plug-ins/pygimp/gimpfu.py	Tue Jul 29 19:33:35 2008
@@ -69,7 +69,7 @@
 consists of the translation domain and the directory where the translations
 are installed.
 '''
-
+import gtk
 import string as _string
 import gimp
 from gimp.enums import *
@@ -97,7 +97,6 @@
 #PF_STRINGARRAY = int(PDB_STRINGARRAY)
 PF_COLOR       = int(PDB_COLOR)
 PF_COLOUR      = PF_COLOR
-PF_REGION      = int(PDB_REGION)
 PF_DISPLAY     = int(PDB_DISPLAY)
 PF_IMAGE       = int(PDB_IMAGE)
 PF_LAYER       = int(PDB_LAYER)
@@ -127,6 +126,12 @@
 PF_DIRNAME     = 1012
 PF_OPTION      = 1013
 
+LAY_EXPANDER = 0
+LAY_GROUP = 1
+LAY_TABLE = 2
+LAY_FIELD = 3
+LAY_PREVIEW = 4
+
 _type_mapping = {
     PF_INT8        : PDB_INT8,
     PF_INT16       : PDB_INT16,
@@ -139,7 +144,6 @@
     #PF_FLOATARRAY  : PDB_FLOATARRAY,
     #PF_STRINGARRAY : PDB_STRINGARRAY,
     PF_COLOR       : PDB_COLOR,
-    PF_REGION      : PDB_REGION,
     PF_DISPLAY     : PDB_DISPLAY,
     PF_IMAGE       : PDB_IMAGE,
     PF_LAYER       : PDB_LAYER,
@@ -176,7 +180,6 @@
     #PF_FLOATARRAY  : list,
     #PF_STRINGARRAY : list,
     PF_COLOR       : gimp.color.RGB,
-    PF_REGION      : int,
     PF_DISPLAY     : gimp.Display,
     PF_IMAGE       : gimp.Image,
     PF_LAYER       : gimp.Layer,
@@ -201,11 +204,455 @@
     PF_OPTION      : int,
 }
 
+class EntryValueError(Exception):
+    pass
+
+
+class ScriptFuDialog(gimp.ui.Dialog):
+    
+    def __init__(self, proc_name, params, defaults, domain, blurb, layout):
+        gimp.ui.Dialog.__init__(self, proc_name, 'python-fu', None, 0, None,
+                                proc_name, (gtk.STOCK_CANCEL,
+                                gtk.RESPONSE_CANCEL, gtk.STOCK_OK,
+                                gtk.RESPONSE_OK))
+
+
+        self.proc_name = proc_name
+        self.params = params
+        self.field_widgets = []
+        self.params_by_name = {}
+        
+        for i in range(len(params)):
+            self.params_by_name[params[i][1]] = (params[i][0], params[i][2],
+                                             defaults[i]) + tuple(params[i][4:])
+
+ 
+
+        self.tooltips = gtk.Tooltips()
+
+        self.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL))
+        self.set_transient()
+        vbox = gtk.VBox(False, 12)
+        vbox.set_border_width(12)
+        self.vbox.pack_start(vbox)
+        vbox.show()
+
+        if blurb:
+            if domain:
+                try:
+                    (domain, locale_dir) = domain
+                    trans = gettext.translation(domain, locale_dir, fallback=True)
+                except ValueError:
+                    trans = gettext.translation(domain, fallback=True)
+                blurb = trans.ugettext(blurb)
+            box = gimp.ui.HintBox(blurb)
+            vbox.pack_start(box, expand=False)
+            box.show()
+                
+        if layout:
+            table = self.process_layout(layout)
+        else:
+            table = gtk.Table(len(params), 2, False)
+            table.set_row_spacings(6)
+            table.set_col_spacings(6)
+
+            row = 0
+
+            for param in params:
+                label, widget = self.create_field(param[1])
+                table.attach(label, 0, 1, row, row+1, xoptions=gtk.FILL)
+                table.attach(widget, 1, 2, row, row+1, yoptions=0)
+                row += 1
+        vbox.pack_start(table, expand=False)
+        table.show()
+
+        progress_vbox = gtk.VBox(False, 6)
+        vbox.pack_end(progress_vbox, expand=False)
+        progress_vbox.show()
+
+        progress = gimp.ui.ProgressBar()
+        progress_vbox.pack_start(progress)
+        progress.show()
+
+    #    progress_label = gtk.Label()
+    #    progress_label.set_alignment(0.0, 0.5)
+    #    progress_label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
+
+    #    attrs = pango.AttrList()
+    #    attrs.insert(pango.AttrStyle(pango.STYLE_ITALIC, 0, -1))
+    #    progress_label.set_attributes(attrs)
+
+    #    progress_vbox.pack_start(progress_label)
+    #    progress_label.show()
+
+
+        self.tooltips.enable()
+        self.connect("response", self.response)
+      
+    def response(self, dialog, id):
+        if id == gtk.RESPONSE_OK:
+            self.set_response_sensitive(gtk.RESPONSE_OK, False)
+            self.set_response_sensitive(gtk.RESPONSE_CANCEL, False)
+
+            params = []
+
+            try:
+                for wid in self.field_widgets:
+                    params.append(wid.get_value())
+            except EntryValueError:
+                self.warning_dialog(dialog, _("Invalid input for '%s'") % wid.desc)
+            else:
+                try:
+                    self.result = self.run_script(params)
+                except Exception:
+                    self.set_response_sensitive(gtk.RESPONSE_CANCEL, True)
+                    self.error_dialog()
+                    raise
+
+        gtk.main_quit()
+
+
+    def warning_dialog(self, primary, secondary=None):
+        dlg = gtk.MessageDialog(self, gtk.DIALOG_DESTROY_WITH_PARENT,
+                                        gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE,
+                                        primary)
+        if secondary:
+            dlg.format_secondary_text(secondary)
+        dlg.run()
+        dlg.destroy()
+
+    def error_dialog(self):
+        import sys, traceback
+
+        exc_str = exc_only_str = _('Missing exception information')
+
+        try:
+            etype, value, tb = sys.exc_info()        
+            exc_str = ''.join(traceback.format_exception(etype, value, tb))
+            exc_only_str = ''.join(traceback.format_exception_only(etype, value))
+        finally:
+            etype = value = tb = None
+
+        title = _("An error occured running %s") % self.proc_name
+        dlg = gtk.MessageDialog(self, gtk.DIALOG_DESTROY_WITH_PARENT,
+                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
+                                        title)
+        dlg.format_secondary_text(exc_only_str)
+
+        alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
+        alignment.set_padding(0, 0, 12, 12)
+        dlg.vbox.pack_start(alignment)
+        alignment.show()
+
+        expander = gtk.Expander(_("_More Information"));
+        expander.set_use_underline(True)
+        expander.set_spacing(6)
+        alignment.add(expander)
+        expander.show()
+
+        scrolled = gtk.ScrolledWindow()
+        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        scrolled.set_size_request(-1, 200)
+        expander.add(scrolled)
+        scrolled.show()
+
+        
+        label = gtk.Label(exc_str)
+        label.set_alignment(0.0, 0.0)
+        label.set_padding(6, 6)
+        label.set_selectable(True)
+        scrolled.add_with_viewport(label)
+        label.show()
+
+        def response(widget, id):
+            widget.destroy()
+
+        dlg.connect("response", response)
+        dlg.set_resizable(True)
+        dlg.show()
+
+    def create_field(self, name):
+        # define a mapping of param types to edit objects ...
+        class StringEntry(gtk.Entry):
+            def __init__(self, default=''):
+                gtk.Entry.__init__(self)
+                self.set_text(str(default))
+
+            def get_value(self):
+                return self.get_text()
+
+        class TextEntry(gtk.ScrolledWindow):
+            def __init__ (self, default=''):
+                gtk.ScrolledWindow.__init__(self)
+                self.set_shadow_type(gtk.SHADOW_IN)
+                
+                self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+                self.set_size_request(100, -1)
+
+                self.view = gtk.TextView()
+                self.add(self.view)
+                self.view.show()
+
+                self.buffer = self.view.get_buffer()
+
+                self.set_value(str(default))
+                
+            def set_value(self, text):
+                self.buffer.set_text(text)
+
+            def get_value(self):
+                return self.buffer.get_text(self.buffer.get_start_iter(),
+                                            self.buffer.get_end_iter())
+
+        class IntEntry(StringEntry):
+            def get_value(self):
+                try:
+                    return int(self.get_text())
+                except ValueError, e:
+                    raise EntryValueError, e.args
+
+        class FloatEntry(StringEntry):
+                def get_value(self):
+                    try:
+                        return float(self.get_text())
+                    except ValueError, e:
+                        raise EntryValueError, e.args
+
+        #class ArrayEntry(StringEntry):
+        #    def get_value(self):
+        #        return eval(self.get_text(), {}, {})
+
+        class SliderEntry(gtk.HScale):
+            # bounds is (upper, lower, step)
+            def __init__(self, default=0.0, bounds=(0.0, 100.0, 5.0)):
+                self.adj = gtk.Adjustment(default, bounds[0],
+                                          bounds[1], bounds[2],
+                                          bounds[2], 0.0)
+                gtk.HScale.__init__(self, self.adj)
+
+            def get_value(self):
+                return self.adj.value
+
+        class SpinnerEntry(gtk.SpinButton):
+            # bounds is (upper, lower, step)
+            def __init__(self, default=0.0, bounds=(0.0, 100.0, 5.0)):
+                self.adj = gtk.Adjustment(default, bounds[0],
+                                            bounds[1], bounds[2],
+                                            bounds[2], 0.0)
+                gtk.SpinButton.__init__(self, self.adj, 1, 0)
+
+            def get_value(self):
+                try:
+                    return int(self.get_text())
+                except ValueError, e:
+                    raise EntryValueError, e.args
+
+        class ToggleEntry(gtk.ToggleButton):
+            def __init__(self, default=0):
+                gtk.ToggleButton.__init__(self)
+
+                self.label = gtk.Label(_("No"))
+                self.add(self.label)
+                self.label.show()
+
+                self.connect("toggled", self.changed)
+
+                self.set_active(default)
+
+            def changed(self, tog):
+                if tog.get_active():
+                    self.label.set_text(_("Yes"))
+                else:
+                    self.label.set_text(_("No"))
+
+            def get_value(self):
+                return self.get_active()
+
+        class RadioEntry(gtk.VBox):
+            def __init__(self, default=0, items=((_("Yes"), 1), (_("No"), 0))):
+                gtk.VBox.__init__(self, homogeneous=False, spacing=2)
+
+                button = None
+
+                for (label, value) in items:
+                    button = gtk.RadioButton(button, label)
+                    self.pack_start(button)
+                    button.show()
+
+                    button.connect("toggled", self.changed, value)
+
+                    if value == default:
+                        button.set_active(True)
+                        self.active_value = value
+
+            def changed(self, radio, value):
+                if radio.get_active():
+                    self.active_value = value
+
+            def get_value(self):
+                return self.active_value
+
+        class ComboEntry(gtk.ComboBox):
+            def __init__(self, default=0, items=()):
+                store = gtk.ListStore(str)    
+                for item in items:
+                    store.append([item])
+
+                gtk.ComboBox.__init__(self, model=store)
+
+                cell = gtk.CellRendererText()
+                self.pack_start(cell)
+                self.set_attributes(cell, text=0)
+
+                self.set_active(default)
+
+            def get_value(self):
+                return self.get_active()
+
+        def FileSelector(default=''):
+           if default and default.endswith('/'):
+               selector = DirnameSelector
+               if default == '/': default = ''
+           else:
+               selector = FilenameSelector
+           return selector(default)
+
+        class FilenameSelector(gtk.FileChooserButton):
+            def __init__(self, default='', save_mode=False):
+                gtk.FileChooserButton.__init__(self,
+                                               _("Python-Fu File Selection"))
+                self.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+                if default:
+                    self.set_filename(default)
+
+            def get_value(self):
+                return self.get_filename()
+
+        class DirnameSelector(gtk.FileChooserButton):
+            def __init__(self, default=''):
+                gtk.FileChooserButton.__init__(self,
+                                               _("Python-Fu Folder Selection"))
+                self.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
+                if default:
+                    self.set_filename(default)
+
+            def get_value(self):
+                return self.get_filename()
+
+        _edit_mapping = {
+            PF_INT8        : IntEntry,
+            PF_INT16       : IntEntry,
+            PF_INT32       : IntEntry,
+            PF_FLOAT       : FloatEntry,
+            PF_STRING      : StringEntry,
+            #PF_INT8ARRAY   : ArrayEntry,
+            #PF_INT16ARRAY  : ArrayEntry,
+            #PF_INT32ARRAY  : ArrayEntry,
+            #PF_FLOATARRAY  : ArrayEntry,
+            #PF_STRINGARRAY : ArrayEntry,
+            PF_COLOR       : gimp.ui.ColorSelector,
+            PF_IMAGE       : gimp.ui.ImageSelector,
+            PF_LAYER       : gimp.ui.LayerSelector,
+            PF_CHANNEL     : gimp.ui.ChannelSelector,
+            PF_DRAWABLE    : gimp.ui.DrawableSelector,
+            PF_VECTORS     : gimp.ui.VectorsSelector,
+
+            PF_TOGGLE      : ToggleEntry,
+            PF_SLIDER      : SliderEntry,
+            PF_SPINNER     : SpinnerEntry,
+            PF_RADIO       : RadioEntry,
+            PF_OPTION      : ComboEntry,
+
+            PF_FONT        : gimp.ui.FontSelector,
+            PF_FILE        : FileSelector,
+            PF_FILENAME    : FilenameSelector,
+            PF_DIRNAME     : DirnameSelector,
+            PF_BRUSH       : gimp.ui.BrushSelector,
+            PF_PATTERN     : gimp.ui.PatternSelector,
+            PF_GRADIENT    : gimp.ui.GradientSelector,
+            PF_PALETTE     : gimp.ui.PaletteSelector,
+            PF_TEXT        : TextEntry
+        }
+        
+        param = self.params_by_name[name]
+        label = gtk.Label(param[1])
+        label.set_use_underline(True)
+        label.set_alignment(0.0, 0.5)
+        label.show()
+
+        widget = _edit_mapping[param[0]](*param[2:])
+
+        label.set_mnemonic_widget(widget)
+
+        if param[0] != PF_TEXT:
+            self.tooltips.set_tip(widget, param[1], None)         
+        else:
+            #Attach tip to TextView, not to ScrolledWindow
+            self.tooltips.set_tip(widget.view, param[1], None)         
+        widget.show()
+
+        widget.desc = param[1]
+        self.field_widgets.append(widget)
+
+        return (label, widget)
+
+    def create_expander(self, label, children):
+        expander = gtk.Expander(label)
+        expander.add(self.process_layout(children))
+        expander.show()
+        return expander 
+
+    def create_group(self, label, children):
+        group = gtk.Frame(label)
+        table = self.process_layout(children)
+        table.set_border_width(6)
+        group.add(table)
+        group.show()
+        return group 
+
+    def create_table(self, children):
+        return self.process_layout(children)
+
+    def create_preview(self, type = None):
+        return gimp.ui.ZoomPreview()
+
+    def process_layout(self, layout):
+
+        table = gtk.Table(len(layout), 2, False)
+        table.set_row_spacings(6)
+        table.set_col_spacings(6)
+        table.show()
+
+        mappings = {LAY_EXPANDER: self.create_expander,
+                    LAY_GROUP: self.create_group,
+                    LAY_TABLE: self.create_table,
+                    LAY_PREVIEW: self.create_preview,
+                    LAY_FIELD: self.create_field}
+       
+        row = 0
+        for item in layout:
+            func = mappings[item[0]]
+            result = func(*item[1:])
+            if isinstance(result, tuple):
+                table.attach(result[0], 0, 1, row, row+1, xoptions=gtk.FILL)
+                table.attach(result[1], 1, 2, row, row+1, yoptions=0)
+            else:
+                table.attach(result, 0, 2, row, row+1, xoptions=gtk.FILL)
+            row += 1
+
+        return table
+
+
+
+
+
+
 _registered_plugins_ = {}
 
 def register(proc_name, blurb, help, author, copyright, date, label,
              imagetypes, params, results, function,
-             menu=None, domain=None, on_query=None, on_run=None):
+             menu=None, domain=None, on_query=None, on_run=None,
+             layout=None):
     '''This is called to register a new plug-in.'''
 
     # First perform some sanity checks on the data
@@ -281,14 +728,14 @@
                                        date, label, imagetypes,
                                        plugin_type, params, results,
                                        function, menu, domain,
-                                       on_query, on_run)
+                                       on_query, on_run, layout)
 
 def _query():
     for plugin in _registered_plugins_.keys():
         (blurb, help, author, copyright, date,
          label, imagetypes, plugin_type,
          params, results, function, menu, domain,
-         on_query, on_run) = _registered_plugins_[plugin]
+         on_query, on_run, layout) = _registered_plugins_[plugin]
 
         def make_params(params):
             return [(_type_mapping[x[0]],
@@ -319,10 +766,7 @@
             on_query()
 
 def _get_defaults(proc_name):
-    (blurb, help, author, copyright, date,
-     label, imagetypes, plugin_type,
-     params, results, function, menu, domain,
-     on_query, on_run) = _registered_plugins_[proc_name]
+    params = _registered_plugins_[proc_name][8]
 
     key = "python-fu-save--" + proc_name
 
@@ -333,7 +777,6 @@
         return [x[3] for x in params]
 
 def _set_defaults(proc_name, defaults):
-
     key = "python-fu-save--" + proc_name
     gimp.shelf.shelf[key] = defaults
 
@@ -341,12 +784,15 @@
     (blurb, help, author, copyright, date,
      label, imagetypes, plugin_type,
      params, results, function, menu, domain,
-     on_query, on_run) = _registered_plugins_[proc_name]
+     on_query, on_run, layout) = _registered_plugins_[proc_name]
+
+    if on_run:
+        on_run()
 
     def run_script(run_params):
         params = start_params + tuple(run_params)
         _set_defaults(proc_name, params)
-        return apply(function, params)
+        return function(*params)
 
     params = params[len(start_params):]
 
@@ -354,394 +800,13 @@
     if len(params) == 0:
          return run_script([])
 
-    import pygtk
-    pygtk.require('2.0')
-
-    import gtk
-#    import pango
-
     defaults = _get_defaults(proc_name)
     defaults = defaults[len(start_params):]
 
-    class EntryValueError(Exception):
-        pass
-
-    def warning_dialog(parent, primary, secondary=None):
-        dlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT,
-                                        gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE,
-                                        primary)
-        if secondary:
-            dlg.format_secondary_text(secondary)
-        dlg.run()
-        dlg.destroy()
-
-    def error_dialog(parent, proc_name):
-        import sys, traceback
-
-        exc_str = exc_only_str = _('Missing exception information')
-
-        try:
-            etype, value, tb = sys.exc_info()        
-            exc_str = ''.join(traceback.format_exception(etype, value, tb))
-            exc_only_str = ''.join(traceback.format_exception_only(etype, value))
-        finally:
-            etype = value = tb = None
-
-        title = _("An error occured running %s") % proc_name
-        dlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT,
-                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
-                                        title)
-        dlg.format_secondary_text(exc_only_str)
-
-        alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
-        alignment.set_padding(0, 0, 12, 12)
-        dlg.vbox.pack_start(alignment)
-        alignment.show()
-
-        expander = gtk.Expander(_("_More Information"));
-        expander.set_use_underline(True)
-        expander.set_spacing(6)
-        alignment.add(expander)
-        expander.show()
-
-        scrolled = gtk.ScrolledWindow()
-        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        scrolled.set_size_request(-1, 200)
-        expander.add(scrolled)
-        scrolled.show()
-
-        
-        label = gtk.Label(exc_str)
-        label.set_alignment(0.0, 0.0)
-        label.set_padding(6, 6)
-        label.set_selectable(True)
-        scrolled.add_with_viewport(label)
-        label.show()
-
-        def response(widget, id):
-            widget.destroy()
-
-        dlg.connect("response", response)
-        dlg.set_resizable(True)
-        dlg.show()
-
-    # define a mapping of param types to edit objects ...
-    class StringEntry(gtk.Entry):
-        def __init__(self, default=''):
-            gtk.Entry.__init__(self)
-            self.set_text(str(default))
-
-        def get_value(self):
-            return self.get_text()
-
-    class TextEntry(gtk.ScrolledWindow):
-        def __init__ (self, default=''):
-            gtk.ScrolledWindow.__init__(self)
-            self.set_shadow_type(gtk.SHADOW_IN)
-            
-            self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-            self.set_size_request(100, -1)
-
-            self.view = gtk.TextView()
-            self.add(self.view)
-            self.view.show()
-
-            self.buffer = self.view.get_buffer()
-
-            self.set_value(str(default))
-            
-        def set_value(self, text):
-            self.buffer.set_text(text)
-
-        def get_value(self):
-            return self.buffer.get_text(self.buffer.get_start_iter(),
-                                        self.buffer.get_end_iter())
-
-    class IntEntry(StringEntry):
-        def get_value(self):
-            try:
-                return int(self.get_text())
-            except ValueError, e:
-                raise EntryValueError, e.args
-
-    class FloatEntry(StringEntry):
-            def get_value(self):
-                try:
-                    return float(self.get_text())
-                except ValueError, e:
-                    raise EntryValueError, e.args
-
-#    class ArrayEntry(StringEntry):
-#            def get_value(self):
-#                return eval(self.get_text(), {}, {})
-
-    class SliderEntry(gtk.HScale):
-        # bounds is (upper, lower, step)
-        def __init__(self, default=0, bounds=(0, 100, 5)):
-            self.adj = gtk.Adjustment(default, bounds[0],
-                                      bounds[1], bounds[2],
-                                      bounds[2], 0)
-            gtk.HScale.__init__(self, self.adj)
-
-        def get_value(self):
-            return self.adj.value
-
-    class SpinnerEntry(gtk.SpinButton):
-        # bounds is (upper, lower, step)
-        def __init__(self, default=0, bounds=(0, 100, 5)):
-            self.adj = gtk.Adjustment(default, bounds[0],
-                                        bounds[1], bounds[2],
-                                        bounds[2], 0)
-            gtk.SpinButton.__init__(self, self.adj, 1, 0)
-
-        def get_value(self):
-            try:
-                return int(self.get_text())
-            except ValueError, e:
-                raise EntryValueError, e.args
-
-    class ToggleEntry(gtk.ToggleButton):
-        def __init__(self, default=0):
-            gtk.ToggleButton.__init__(self)
-
-            self.label = gtk.Label(_("No"))
-            self.add(self.label)
-            self.label.show()
-
-            self.connect("toggled", self.changed)
-
-            self.set_active(default)
-
-        def changed(self, tog):
-            if tog.get_active():
-                self.label.set_text(_("Yes"))
-            else:
-                self.label.set_text(_("No"))
-
-        def get_value(self):
-            return self.get_active()
-
-    class RadioEntry(gtk.VBox):
-        def __init__(self, default=0, items=((_("Yes"), 1), (_("No"), 0))):
-            gtk.VBox.__init__(self, homogeneous=False, spacing=2)
-
-            button = None
-
-            for (label, value) in items:
-                button = gtk.RadioButton(button, label)
-                self.pack_start(button)
-                button.show()
-
-                button.connect("toggled", self.changed, value)
-
-                if value == default:
-                    button.set_active(True)
-                    self.active_value = value
-
-        def changed(self, radio, value):
-            if radio.get_active():
-                self.active_value = value
-
-        def get_value(self):
-            return self.active_value
-
-    class ComboEntry(gtk.ComboBox):
-        def __init__(self, default=0, items=()):
-            store = gtk.ListStore(str)    
-            for item in items:
-                store.append([item])
-
-            gtk.ComboBox.__init__(self, model=store)
-
-            cell = gtk.CellRendererText()
-            self.pack_start(cell)
-            self.set_attributes(cell, text=0)
-
-            self.set_active(default)
-
-        def get_value(self):
-            return self.get_active()
-
-    def FileSelector(default=''):
-       if default and default.endswith('/'):
-           selector = DirnameSelector
-           if default == '/': default = ''
-       else:
-           selector = FilenameSelector
-       return selector(default)
-
-    class FilenameSelector(gtk.FileChooserButton):
-        def __init__(self, default='', save_mode=False):
-            gtk.FileChooserButton.__init__(self,
-                                           _("Python-Fu File Selection"))
-            self.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
-            if default:
-                self.set_filename(default)
-
-        def get_value(self):
-            return self.get_filename()
-
-    class DirnameSelector(gtk.FileChooserButton):
-        def __init__(self, default=''):
-            gtk.FileChooserButton.__init__(self,
-                                           _("Python-Fu Folder Selection"))
-            self.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
-            if default:
-                self.set_filename(default)
-
-        def get_value(self):
-            return self.get_filename()
-
-    _edit_mapping = {
-            PF_INT8        : IntEntry,
-            PF_INT16       : IntEntry,
-            PF_INT32       : IntEntry,
-            PF_FLOAT       : FloatEntry,
-            PF_STRING      : StringEntry,
-            #PF_INT8ARRAY   : ArrayEntry,
-            #PF_INT16ARRAY  : ArrayEntry,
-            #PF_INT32ARRAY  : ArrayEntry,
-            #PF_FLOATARRAY  : ArrayEntry,
-            #PF_STRINGARRAY : ArrayEntry,
-            PF_COLOR       : gimp.ui.ColorSelector,
-            PF_REGION      : IntEntry,  # should handle differently ...
-            PF_IMAGE       : gimp.ui.ImageSelector,
-            PF_LAYER       : gimp.ui.LayerSelector,
-            PF_CHANNEL     : gimp.ui.ChannelSelector,
-            PF_DRAWABLE    : gimp.ui.DrawableSelector,
-            PF_VECTORS     : gimp.ui.VectorsSelector,
-
-            PF_TOGGLE      : ToggleEntry,
-            PF_SLIDER      : SliderEntry,
-            PF_SPINNER     : SpinnerEntry,
-            PF_RADIO       : RadioEntry,
-            PF_OPTION      : ComboEntry,
-
-            PF_FONT        : gimp.ui.FontSelector,
-            PF_FILE        : FileSelector,
-            PF_FILENAME    : FilenameSelector,
-            PF_DIRNAME     : DirnameSelector,
-            PF_BRUSH       : gimp.ui.BrushSelector,
-            PF_PATTERN     : gimp.ui.PatternSelector,
-            PF_GRADIENT    : gimp.ui.GradientSelector,
-            PF_PALETTE     : gimp.ui.PaletteSelector,
-            PF_TEXT        : TextEntry
-    }
-
-    if on_run:
-        on_run()
-
-    tooltips = gtk.Tooltips()
-
-    dialog = gimp.ui.Dialog(proc_name, 'python-fu', None, 0, None, proc_name,
-                           (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
-                            gtk.STOCK_OK, gtk.RESPONSE_OK))
-
-    dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL))
-
-    dialog.set_transient()
-
-    vbox = gtk.VBox(False, 12)
-    vbox.set_border_width(12)
-    dialog.vbox.pack_start(vbox)
-    vbox.show()
-
-    if blurb:
-        if domain:
-            try:
-                (domain, locale_dir) = domain
-                trans = gettext.translation(domain, locale_dir, fallback=True)
-            except ValueError:
-                trans = gettext.translation(domain, fallback=True)
-            blurb = trans.ugettext(blurb)
-        box = gimp.ui.HintBox(blurb)
-        vbox.pack_start(box, expand=False)
-        box.show()
-
-    table = gtk.Table(len(params), 2, False)
-    table.set_row_spacings(6)
-    table.set_col_spacings(6)
-    vbox.pack_start(table, expand=False)
-    table.show()
-
-    def response(dlg, id):
-        if id == gtk.RESPONSE_OK:
-            dlg.set_response_sensitive(gtk.RESPONSE_OK, False)
-            dlg.set_response_sensitive(gtk.RESPONSE_CANCEL, False)
-
-            params = []
-
-            try:
-                for wid in edit_wids:
-                    params.append(wid.get_value())
-            except EntryValueError:
-                warning_dialog(dialog, _("Invalid input for '%s'") % wid.desc)
-            else:
-                try:
-                    dialog.res = run_script(params)
-                except Exception:
-                    dlg.set_response_sensitive(gtk.RESPONSE_CANCEL, True)
-                    error_dialog(dialog, proc_name)
-                    raise
-
-        gtk.main_quit()
-
-    dialog.connect("response", response)
-
-    edit_wids = []
-    for i in range(len(params)):
-        pf_type = params[i][0]
-        name = params[i][1]
-        desc = params[i][2]
-        def_val = defaults[i]
-
-        label = gtk.Label(desc)
-        label.set_use_underline(True)
-        label.set_alignment(0.0, 0.5)
-        table.attach(label, 1, 2, i, i+1, xoptions=gtk.FILL)
-        label.show()
-
-        if pf_type in (PF_SPINNER, PF_SLIDER, PF_RADIO, PF_OPTION):
-            wid = _edit_mapping[pf_type](def_val, params[i][4])
-        else:
-            wid = _edit_mapping[pf_type](def_val)
-
-        label.set_mnemonic_widget(wid)
-
-        table.attach(wid, 2,3, i,i+1, yoptions=0)
-
-        if pf_type != PF_TEXT:
-            tooltips.set_tip(wid, desc, None)         
-        else:
-            #Attach tip to TextView, not to ScrolledWindow
-            tooltips.set_tip(wid.view, desc, None)         
-        wid.show()
-
-        wid.desc = desc
-        edit_wids.append(wid)
-
-    progress_vbox = gtk.VBox(False, 6)
-    vbox.pack_end(progress_vbox, expand=False)
-    progress_vbox.show()
-
-    progress = gimp.ui.ProgressBar()
-    progress_vbox.pack_start(progress)
-    progress.show()
-
-#    progress_label = gtk.Label()
-#    progress_label.set_alignment(0.0, 0.5)
-#    progress_label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
-
-#    attrs = pango.AttrList()
-#    attrs.insert(pango.AttrStyle(pango.STYLE_ITALIC, 0, -1))
-#    progress_label.set_attributes(attrs)
-
-#    progress_vbox.pack_start(progress_label)
-#    progress_label.show()
-
-    tooltips.enable()
+    dialog = ScriptFuDialog(proc_name, params, defaults, domain, blurb, layout)
+    # FIXME: This is really ugly!
+    dialog.run_script = run_script
     dialog.show()
-
     gtk.main()
 
     if hasattr(dialog, 'res'):
@@ -757,7 +822,7 @@
     func = _registered_plugins_[proc_name][10]
 
     if run_mode == RUN_NONINTERACTIVE:
-        return apply(func, params[1:])
+        return func(params[1:])
 
     script_params = _registered_plugins_[proc_name][8] 
 
@@ -787,7 +852,7 @@
         except CancelError:
             return
     else:
-        res = apply(func, params[1:])
+        res = func(*params[1:])
 
     gimp.displays_flush()
 

Modified: branches/soc-2008-python/plug-ins/pygimp/plug-ins/sphere.py
==============================================================================
--- branches/soc-2008-python/plug-ins/pygimp/plug-ins/sphere.py	(original)
+++ branches/soc-2008-python/plug-ins/pygimp/plug-ins/sphere.py	Tue Jul 29 19:33:35 2008
@@ -101,12 +101,20 @@
         (PF_INT, "radius", "Radius for sphere", 100),
         (PF_SLIDER, "light", "Light angle", 45, (0,360,1)),
         (PF_TOGGLE, "shadow", "Shadow?", 1),
-        (PF_RADIO, "foo", "Test", "foo", (("Foo", "foo"), ("Bar", "bar"))),
+        (PF_RADIO, "foo", "Test 123", "foo", (("Foo", "foo"), ("Bar", "bar"))),
         (PF_COLOR, "bg-color", "Background", (1.0, 1.0, 1.0)),
         (PF_COLOR, "sphere-color", "Sphere", "orange")
     ],
     [],
     sphere,
-    menu="<Image>/Filters/Languages/Python-Fu/Test")
+    menu="<Image>/Filters/Languages/Python-Fu/Test",
+    layout=((LAY_FIELD, "radius"),
+            (LAY_FIELD, "light"),
+            (LAY_EXPANDER, "Test expander", ((LAY_FIELD, "shadow"),
+                                             (LAY_FIELD, "foo"))),
+            (LAY_GROUP, "Test group", ((LAY_FIELD, "bg-color"), 
+                                       (LAY_FIELD, "sphere-color")))
+           )
+    )
 
 main()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]