def _create_properties(self):
        """Populate a frame with a list of all editable properties"""

        # To mantain container options:
        self._container_options = {}

        # Layout Options editors
        self._rcbag = {}  # bag for row/column prop editors
        # main options frame
        self._fprop = fprop = ttk.Labelframe(self._sframe.innerframe,
                                             text=_('Options:'),
                                             padding=4)
        fprop.grid(row=0, sticky='nswe')

        # Layout selector
        label = ttk.Label(fprop, text=_('Manager:'))
        label.grid(row=0, column=0, sticky=tk.EW, pady=2)
        self.layout_selector = combo = LayoutManagerPropertyEditor(fprop)
        combo.parameters(state='readonly', values=self.managers)
        combo.grid(row=0, column=1, sticky=tk.EW, pady=2)
        combo.bind('<<PropertyChanged>>', self._layout_manager_changed)
        self._allowed_managers = self.managers.keys()
        # Separator
        w = ttk.Separator(fprop, orient='horizontal')
        w.grid(row=1, column=0, columnspan=2, sticky='ew', pady=4)

        # Other Layout properties
        label_tpl = "{0}:"
        row = 2
        col = 0

        self._groups = (('00', properties.MANAGER_PROPERTIES,
                         properties.LAYOUT_OPTIONS), )

        for gcode, plist, propdescr in self._groups:
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._fprop, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                label.tooltip = create_tooltip(label, '?')
                widget = self._create_editor(self._fprop, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)

        # container layout editor
        self._cleditor = ContainerLayoutEditor(self._sframe.innerframe)
        self._cleditor.grid(row=1, sticky='nswe', pady='5 0')
 def _ask_manager_change(self, old_manager, new_manager):
     title = _('Change Manager')
     msg = _('Change manager from {0} to {1}?')
     msg = msg.format(old_manager, new_manager)
     detail = _('All container widgets will be updated.')
     user_accepts_change = messagebox.askokcancel(
         title,
         msg,
         detail=detail,
         parent=self.layout_selector.winfo_toplevel())
     if user_accepts_change:
         topack = '<<LayoutEditorContainerManagerToPack>>'
         togrid = '<<LayoutEditorContainerManagerToGrid>>'
         event_name = togrid if new_manager == 'grid' else topack
         self._sframe.event_generate(event_name)
Example #3
0
    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""
        self._frame = f = ttk.Labelframe(self._sframe.innerframe,
                                         text=_('Widget properties'))
        f.configure(padding=4)
        f.grid(sticky='nswe')

        label_tpl = "{0}:"
        row = 0
        col = 0

        groups = (
            ('00', _('Required'), properties.WIDGET_REQUIRED_OPTIONS,
             properties.REQUIRED_OPTIONS),
            ('01', _('Standard'), properties.WIDGET_STANDARD_OPTIONS,
             properties.TK_WIDGET_OPTIONS),
            ('02', _('Specific'), properties.WIDGET_SPECIFIC_OPTIONS,
             properties.TK_WIDGET_OPTIONS),
            ('03', _('Custom'), properties.WIDGET_CUSTOM_OPTIONS,
             properties.CUSTOM_OPTIONS),
        )

        for gcode, gname, plist, propdescr in groups:
            padding = '0 0 0 5' if row == 0 else '0 5 0 5'
            label = ttk.Label(self._frame,
                              text=gname,
                              font='TkDefaultFont 10 bold',
                              padding=padding,
                              foreground='#000059')
            label.grid(row=row, column=0, sticky='we', columnspan=2)
            row += 1
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._frame, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                label.tooltip = create_tooltip(label, '?')
                widget = self._create_editor(self._frame, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)
                logger.debug('Created property: %s-%s', gname, name)
                # add validator for widget id
                if gcode == '00' and name == 'id':
                    widget.set_unique_cb(self._id_validator)
Example #4
0
    def _create_ui(self):
        self._lbl_callback = _('Callback:')
        self._plabel = w = ttk.Label(self, text=self._lbl_callback,
                                     font='TkSmallCaptionFont')
        w.grid(row=0, column=0, sticky='nswe')

        self._cbname = w = EntryPropertyEditor(self)
        w.grid(row=0, column=1, sticky='nswe')
        w.bind('<<PropertyChanged>>', self._on_variable_changed)
        # type label:
        w = ttk.Label(self, text='Type:', font='TkSmallCaptionFont')
        w.grid(row=1, column=0, sticky='nsew')
        # type combo
        cmdtypes = (
            (CB_TYPES.SIMPLE, _('Simple')),
            (CB_TYPES.WITH_WID, _('Send widget ID')),
        )
        self._cmdtype = w = ChoiceByKeyPropertyEditor(self)
        w.parameters(values=cmdtypes)
        w.bind('<<PropertyChanged>>', self._on_variable_changed)
        w.grid(row=1, column=1, sticky='nswe')
        self.columnconfigure(1, weight=1)
Example #5
0
    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""
        self._frame = f = ttk.Labelframe(self._sframe.innerframe,
                                         text=_('Widget properties'))
        f.grid(sticky='nswe')

        label_tpl = "{0}:"
        row = 0
        col = 0

        groups = (
            ('00', _('Required'), properties.WIDGET_REQUIRED_OPTIONS,
             properties.REQUIRED_OPTIONS),
            ('01', _('Standard'), properties.WIDGET_STANDARD_OPTIONS,
             properties.TK_WIDGET_OPTIONS),
            ('02', _('Specific'), properties.WIDGET_SPECIFIC_OPTIONS,
             properties.TK_WIDGET_OPTIONS),
            ('03', _('Custom'), properties.WIDGET_CUSTOM_OPTIONS,
             properties.CUSTOM_OPTIONS),
        )

        for gcode, gname, plist, propdescr in groups:
            padding = '0 0 0 5' if row == 0 else '0 5 0 5'
            label = ttk.Label(self._frame, text=gname,
                              font='TkDefaultFont 10 bold', padding=padding,
                              foreground='#000059')
            label.grid(row=row, column=0, sticky='we', columnspan=2)
            row += 1
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._frame, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                widget = self._create_editor(self._frame, name, kwdata)
                widget.grid(row=row, column=col+1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode+name] = (label, widget)
                logger.debug('Created property: {0}-{1}'.format(gname,name))
Example #6
0
    def _create_ui(self):
        self._cbname = w = EntryPropertyEditor(self)
        w.grid(row=0, column=0, sticky='nswe', columnspan=2)
        w.bind('<<PropertyChanged>>', self._on_variable_changed)

        self._arg_var = var = tk.StringVar(self, '')
        self._argd = w = EntryPropertyEditor(self)
        w.parameters(state='readonly', textvariable=var)
        w.grid(row=1, column=0, sticky='nswe')

        self._mb = w = ttk.Menubutton(self, text='Args')
        w.grid(row=1, column=1, sticky='nswe')

        olist = (
            ('%d', _('Type of action.')),
            ('%i', _('Index of character string to be inserted/deleted.')),
            ('%P', _("The new/current value of the entry.")),
            ('%s', _('The current value of entry prior to editing.')),
            ('%S', _('The text string being inserted/deleted.')),
            ('%v', _('The current value of the -validate option.')),
            ('%V', _('The validation condition that triggered the callback.')),
            ('%W', _('The name of the entry widget.')),
        )
        options = OrderedDict(olist)
        self._vars = {k: tk.BooleanVar(self) for k in options.keys()}

        self._menu = m = tk.Menu(self._mb, tearoff=False)
        m.add_command(label=_('Select all'), command=self._on_select_all)
        m.add_command(label=_('Clear'), command=self._on_clear)
        m.add_separator()
        for key, txt in options.items():
            txt = '{0} {1}'.format(key, txt)
            m.add_checkbutton(label=txt,
                              variable=self._vars[key],
                              command=self._on_update_args)
        self._mb['menu'] = m
        self.columnconfigure(0, weight=1)
Example #7
0
    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""
        self._rcbag = {}  # bag for row/column prop editors
        self._fgrid = f = ttk.Labelframe(self._sframe.innerframe,
                                         text=_('Grid options:'),
                                         padding=5)
        f.grid(sticky='nswe')
        #  hack to resize correctly when properties are hidden
        label = ttk.Label(f)
        label.grid()

        label_tpl = "{0}:"
        row = 0
        col = 0

        groups = (('00', properties.GRID_PROPERTIES,
                   properties.LAYOUT_OPTIONS), )

        for gcode, plist, propdescr in groups:
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._fgrid, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                widget = self._create_editor(self._fgrid, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)

        # Grid row/col properties
        #labels
        gcode = '01'
        self._fgrc = fgrc = ttk.LabelFrame(self._sframe.innerframe,
                                           text=_('Grid row/column options:'),
                                           padding=5)
        fgrc.grid(row=1, column=0, sticky=tk.NSEW, pady='10 0')

        #hack to resize correctly when properties are hidden
        label = ttk.Label(fgrc)
        label.grid()

        row = col = 0
        icol = 1
        headers = []
        for pname in properties.GRID_RC_PROPERTIES:
            label = ttk.Label(fgrc, text=pname)
            label.grid(row=row, column=icol)
            headers.append(label)
            icol += 1
        self._internal = {'grc_headers': headers}

        #
        name_format = '{}_{}_{}'  # {row/column}_{number}_{name}
        MAX_RC = 50
        #rowconfig
        row += 1
        trow_label = _('Row {0}:')
        tcol_label = _('Column {0}:')
        for index in range(0, MAX_RC):
            labeltext = trow_label.format(index)
            label = ttk.Label(fgrc, text=labeltext)
            label.grid(row=row, column=0)

            labeltext = tcol_label.format(index)
            labelc = ttk.Label(fgrc, text=labeltext)
            labelc.grid(row=row + MAX_RC, column=0, sticky=tk.E, pady=2)

            icol = 1
            for pname in properties.GRID_RC_PROPERTIES:
                kwdata = properties.LAYOUT_OPTIONS[pname]

                alias = name_format.format('row', index, pname)
                widget = self._create_editor(fgrc, alias, kwdata)
                widget.grid(row=row, column=icol, pady=2)
                self._rcbag[alias] = (label, widget)

                alias = name_format.format('column', index, pname)
                widget = self._create_editor(fgrc, alias, kwdata)
                widget.grid(row=row + MAX_RC, column=icol, pady=2)
                self._rcbag[alias] = (labelc, widget)

                icol += 1
            row += 1
Example #8
0
    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""
        self._rcbag = {}  # bag for row/column prop editors
        self._fgrid = f = ttk.Labelframe(self._sframe.innerframe, text=_("Grid options:"), padding=5)
        f.grid(sticky="nswe")
        #  hack to resize correctly when properties are hidden
        label = ttk.Label(f)
        label.grid()

        label_tpl = "{0}:"
        row = 0
        col = 0

        groups = (("00", properties.GRID_PROPERTIES, properties.LAYOUT_OPTIONS),)

        for gcode, plist, propdescr in groups:
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._fgrid, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                widget = self._create_editor(self._fgrid, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)

        # Grid row/col properties
        # labels
        gcode = "01"
        self._fgrc = fgrc = ttk.LabelFrame(self._sframe.innerframe, text=_("Grid row/column options:"), padding=5)
        fgrc.grid(row=1, column=0, sticky=tk.NSEW, pady="10 0")

        # hack to resize correctly when properties are hidden
        label = ttk.Label(fgrc)
        label.grid()

        row = col = 0
        icol = 1
        headers = []
        for pname in properties.GRID_RC_PROPERTIES:
            label = ttk.Label(fgrc, text=pname)
            label.grid(row=row, column=icol)
            headers.append(label)
            icol += 1
        self._internal = {"grc_headers": headers}

        #
        name_format = "{}_{}_{}"  # {row/column}_{number}_{name}
        MAX_RC = 50
        # rowconfig
        row += 1
        trow_label = _("Row {0}:")
        tcol_label = _("Column {0}:")
        for index in range(0, MAX_RC):
            labeltext = trow_label.format(index)
            label = ttk.Label(fgrc, text=labeltext)
            label.grid(row=row, column=0)

            labeltext = tcol_label.format(index)
            labelc = ttk.Label(fgrc, text=labeltext)
            labelc.grid(row=row + MAX_RC, column=0, sticky=tk.E, pady=2)

            icol = 1
            for pname in properties.GRID_RC_PROPERTIES:
                kwdata = properties.LAYOUT_OPTIONS[pname]

                alias = name_format.format("row", index, pname)
                widget = self._create_editor(fgrc, alias, kwdata)
                widget.grid(row=row, column=icol, pady=2)
                self._rcbag[alias] = (label, widget)

                alias = name_format.format("column", index, pname)
                widget = self._create_editor(fgrc, alias, kwdata)
                widget.grid(row=row + MAX_RC, column=icol, pady=2)
                self._rcbag[alias] = (labelc, widget)

                icol += 1
            row += 1
class LayoutEditor(PropertiesEditor):
    managers_keys = ('grid', 'pack', 'place')
    managers_labels = (_('Grid'), _('Pack'), _('Place'))
    managers = dict(zip(managers_keys, managers_labels))

    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""

        # To mantain container options:
        self._container_options = {}

        # Layout Options editors
        self._rcbag = {}  # bag for row/column prop editors
        # main options frame
        self._fprop = fprop = ttk.Labelframe(self._sframe.innerframe,
                                             text=_('Options:'),
                                             padding=4)
        fprop.grid(row=0, sticky='nswe')

        # Layout selector
        label = ttk.Label(fprop, text=_('Manager:'))
        label.grid(row=0, column=0, sticky=tk.EW, pady=2)
        self.layout_selector = combo = LayoutManagerPropertyEditor(fprop)
        combo.parameters(state='readonly', values=self.managers)
        combo.grid(row=0, column=1, sticky=tk.EW, pady=2)
        combo.bind('<<PropertyChanged>>', self._layout_manager_changed)
        self._allowed_managers = self.managers.keys()
        # Separator
        w = ttk.Separator(fprop, orient='horizontal')
        w.grid(row=1, column=0, columnspan=2, sticky='ew', pady=4)

        # Other Layout properties
        label_tpl = "{0}:"
        row = 2
        col = 0

        self._groups = (('00', properties.MANAGER_PROPERTIES,
                         properties.LAYOUT_OPTIONS), )

        for gcode, plist, propdescr in self._groups:
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._fprop, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                label.tooltip = create_tooltip(label, '?')
                widget = self._create_editor(self._fprop, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)

        # container layout editor
        self._cleditor = ContainerLayoutEditor(self._sframe.innerframe)
        self._cleditor.grid(row=1, sticky='nswe', pady='5 0')

    def edit(self, wdescr, manager_options, container_options=None):
        self._current = wdescr

        # need to save the container info when updating the view.
        # this function is called again in _layout_manager_changed
        if container_options is not None:
            self._container_options = container_options

        wclass = wdescr.classname
        #class_descr = CLASS_MAP[wclass].builder
        max_children = CLASS_MAP[wclass].builder.maxchildren
        max_children = 0 if max_children is None else max_children
        is_container = CLASS_MAP[wclass].builder.container
        layout_required = CLASS_MAP[wclass].builder.layout_required
        allow_container_layout = CLASS_MAP[wclass].builder.container_layout
        show_layout = layout_required

        # manager selector
        manager = wdescr.manager
        manager_prop = properties.GRID_PROPERTIES
        if manager == 'pack':
            manager_prop = properties.PACK_PROPERTIES
        elif manager == 'place':
            manager_prop = properties.PLACE_PROPERTIES

        if show_layout:
            self._fprop.grid()
            self._allowed_managers = manager_options
            self.layout_selector.edit(manager)

            # layout properties
            for gcode, proplist, gproperties in self._groups:
                for name in proplist:
                    propdescr = gproperties[name]
                    label, widget = self._propbag[gcode + name]
                    if show_layout and name in manager_prop:
                        self.update_editor(label, widget, wdescr, name,
                                           propdescr)
                        label.grid()
                        widget.grid()
                    else:
                        label.grid_remove()
                        widget.grid_remove()
        else:
            self._fprop.grid_remove()

        # determine if show container layout options
        has_children = self._container_options.get('has_children', False)
        children_grid_dim = self._container_options.get('grid_dim', None)

        if is_container and allow_container_layout and has_children:
            self._cleditor.grid()
            cmanager = wdescr.container_manager
            self._cleditor.edit(wdescr, cmanager, children_grid_dim)
        else:
            self._cleditor.grid_remove()

        self._sframe.reposition()

    def _layout_manager_changed(self, event=None):
        if self._current is None:
            # I'm not editing anything
            return

        old_manager = self._current.manager
        new_manager = self.layout_selector.value
        needs_container_change = (new_manager not in self._allowed_managers)

        if needs_container_change:
            self.layout_selector.edit(old_manager)

            def cb(f=old_manager, t=new_manager):
                return self._ask_manager_change(f, t)

            self._sframe.after_idle(cb)
        else:
            self._current.manager = new_manager
            self.edit(self._current, self._allowed_managers)

    def _ask_manager_change(self, old_manager, new_manager):
        title = _('Change Manager')
        msg = _('Change manager from {0} to {1}?')
        msg = msg.format(old_manager, new_manager)
        detail = _('All container widgets will be updated.')
        user_accepts_change = messagebox.askokcancel(
            title,
            msg,
            detail=detail,
            parent=self.layout_selector.winfo_toplevel())
        if user_accepts_change:
            topack = '<<LayoutEditorContainerManagerToPack>>'
            togrid = '<<LayoutEditorContainerManagerToGrid>>'
            event_name = togrid if new_manager == 'grid' else topack
            self._sframe.event_generate(event_name)

    def _on_property_changed(self, name, editor):
        value = editor.value
        # Save new value and update the preview
        self._current.layout_property(name, value)

    def update_editor(self, label, editor, wdescr, pname, propdescr):
        pdescr = propdescr.copy()
        manager = wdescr.manager

        if manager in pdescr:
            pdescr = dict(pdescr, **pdescr[manager])

        label.tooltip.text = pdescr.get('help', None)
        params = pdescr.get('params', {})
        editor.parameters(**params)
        default = pdescr.get('default', '')

        value = wdescr.layout_property(pname)
        if not value and default:
            value = default
        editor.edit(value)

    def hide_all(self):
        super(LayoutEditor, self).hide_all()
        self._fprop.grid_remove()
        self._cleditor.grid_remove()
# encoding: utf-8

# translator marker
from pygubudesigner.i18n import translator as _

tooltip_help = {
    'class':
    _('Object class name.'),
    'id':
    _('Object unique identifier.'),
    'accelerator':
    _('Specifies a string to display at the right side of the menu entry.'),
    'activerelief':
    _('Specifies the relief to use when displaying the element that is active, if any.'
      ),
    'activestyle':
    _('Specifies the style in which to draw the active element.'),
    'activebackground':
    _('Specifies background color to use when drawing active elements.'),
    'activeborderwidth':
    _('Specifies a non-negative value indicating the width of the 3-D border drawn around active elements.'
      ),
    'activeforeground':
    _('Specifies foreground color to use when drawing active elements.'),
    'after':
    None,
    'anchor':
    _('Specifies how the information in the widget is positioned relative to the inner margins.'
      ),
    'aspect':
    _('Specifies a non-negative integer value indicating desired aspect ratio for the text. The aspect ratio is specified as 100*width/height. 100 means the text should be as wide as it is tall, 200 means the text should be twice as wide as it is tall, 50 means the text should be twice as tall as it is wide, and so on.'
Example #11
0
    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""

        # Layout selector
        self._fselector = fm = ttk.Frame(self._sframe.innerframe)
        label = ttk.Label(fm, text='Manager:')
        label.pack(side='left')
        self.layout_selector = combo = LayoutManagerPropertyEditor(fm)
        combo.parameters(state='readonly', values=self.managers)
        combo.pack(side='left', expand=True)
        combo.bind('<<PropertyChanged>>', self._layout_manager_changed)
        self._allowed_managers = self.managers.keys()
        fm.grid(row=0, sticky='w')

        # Layout Options editors
        self._rcbag = {}  # bag for row/column prop editors
        # main options frame
        self._fprop = f = ttk.Labelframe(self._sframe.innerframe,
                                         text=_('Options:'),
                                         padding=4)
        f.grid(row=1, sticky='nswe')
        #  hack to resize correctly when properties are hidden
        label = ttk.Frame(f)
        label.grid()

        label_tpl = "{0}:"
        row = 0
        col = 0

        groups = (('00', properties.MANAGER_PROPERTIES,
                   properties.LAYOUT_OPTIONS), )

        for gcode, plist, propdescr in groups:
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._fprop, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                widget = self._create_editor(self._fprop, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)

        # Grid row properties
        self._fgr_label = _("Grid row '{0}' options:")
        self._fgr = fgr = ttk.LabelFrame(self._sframe.innerframe,
                                         text=self._fgr_label,
                                         padding=5)
        fgr.grid(row=2, column=0, sticky=tk.NSEW, pady='10 0')
        name_format = 'row_{0}'  # row_{name}
        row = 0
        label_tpl = "{0}:"
        for pname in properties.GRID_RC_PROPERTIES:
            kwdata = properties.LAYOUT_OPTIONS[pname]
            alias = name_format.format(pname)
            labeltext = label_tpl.format(pname)
            label = ttk.Label(fgr, text=labeltext, anchor=tk.W)
            label.grid(row=row, column=0, sticky=tk.EW, pady=2)

            widget = self._create_editor(fgr, alias, kwdata)
            widget.grid(row=row, column=1, sticky=tk.EW, pady=2)
            self._rcbag[alias] = (label, widget)
            row = row + 1
        fgr.columnconfigure(1, weight=1)

        # Grid column properties
        self._fgc_label = _("Grid column '{0}' options:")
        self._fgc = fgc = ttk.LabelFrame(self._sframe.innerframe,
                                         text=self._fgc_label,
                                         padding=5)
        fgc.grid(row=3, column=0, sticky=tk.NSEW, pady='10 0')
        name_format = 'col_{0}'  # row_{name}
        row = 0
        label_tpl = "{0}:"
        for pname in properties.GRID_RC_PROPERTIES:
            kwdata = properties.LAYOUT_OPTIONS[pname]
            alias = name_format.format(pname)
            labeltext = label_tpl.format(pname)
            label = ttk.Label(fgc, text=labeltext, anchor=tk.W)
            label.grid(row=row, column=0, sticky=tk.EW, pady=2)

            widget = self._create_editor(fgc, alias, kwdata)
            widget.grid(row=row, column=1, sticky=tk.EW, pady=2)
            self._rcbag[alias] = (label, widget)
            row = row + 1
        fgc.columnconfigure(1, weight=1)
Example #12
0
class LayoutEditor(PropertiesEditor):
    managers_keys = ('grid', 'pack', 'place')
    managers_labels = (_('Grid'), _('Pack'), _('Place'))
    managers = dict(zip(managers_keys, managers_labels))

    def _create_properties(self):
        """Populate a frame with a list of all editable properties"""

        # Layout selector
        self._fselector = fm = ttk.Frame(self._sframe.innerframe)
        label = ttk.Label(fm, text='Manager:')
        label.pack(side='left')
        self.layout_selector = combo = LayoutManagerPropertyEditor(fm)
        combo.parameters(state='readonly', values=self.managers)
        combo.pack(side='left', expand=True)
        combo.bind('<<PropertyChanged>>', self._layout_manager_changed)
        self._allowed_managers = self.managers.keys()
        fm.grid(row=0, sticky='w')

        # Layout Options editors
        self._rcbag = {}  # bag for row/column prop editors
        # main options frame
        self._fprop = f = ttk.Labelframe(self._sframe.innerframe,
                                         text=_('Options:'),
                                         padding=4)
        f.grid(row=1, sticky='nswe')
        #  hack to resize correctly when properties are hidden
        label = ttk.Frame(f)
        label.grid()

        label_tpl = "{0}:"
        row = 0
        col = 0

        groups = (('00', properties.MANAGER_PROPERTIES,
                   properties.LAYOUT_OPTIONS), )

        for gcode, plist, propdescr in groups:
            for name in plist:
                kwdata = propdescr[name]
                labeltext = label_tpl.format(name)
                label = ttk.Label(self._fprop, text=labeltext, anchor=tk.W)
                label.grid(row=row, column=col, sticky=tk.EW, pady=2)
                widget = self._create_editor(self._fprop, name, kwdata)
                widget.grid(row=row, column=col + 1, sticky=tk.EW, pady=2)
                row += 1
                self._propbag[gcode + name] = (label, widget)

        # Grid row properties
        self._fgr_label = _("Grid row '{0}' options:")
        self._fgr = fgr = ttk.LabelFrame(self._sframe.innerframe,
                                         text=self._fgr_label,
                                         padding=5)
        fgr.grid(row=2, column=0, sticky=tk.NSEW, pady='10 0')
        name_format = 'row_{0}'  # row_{name}
        row = 0
        label_tpl = "{0}:"
        for pname in properties.GRID_RC_PROPERTIES:
            kwdata = properties.LAYOUT_OPTIONS[pname]
            alias = name_format.format(pname)
            labeltext = label_tpl.format(pname)
            label = ttk.Label(fgr, text=labeltext, anchor=tk.W)
            label.grid(row=row, column=0, sticky=tk.EW, pady=2)

            widget = self._create_editor(fgr, alias, kwdata)
            widget.grid(row=row, column=1, sticky=tk.EW, pady=2)
            self._rcbag[alias] = (label, widget)
            row = row + 1
        fgr.columnconfigure(1, weight=1)

        # Grid column properties
        self._fgc_label = _("Grid column '{0}' options:")
        self._fgc = fgc = ttk.LabelFrame(self._sframe.innerframe,
                                         text=self._fgc_label,
                                         padding=5)
        fgc.grid(row=3, column=0, sticky=tk.NSEW, pady='10 0')
        name_format = 'col_{0}'  # row_{name}
        row = 0
        label_tpl = "{0}:"
        for pname in properties.GRID_RC_PROPERTIES:
            kwdata = properties.LAYOUT_OPTIONS[pname]
            alias = name_format.format(pname)
            labeltext = label_tpl.format(pname)
            label = ttk.Label(fgc, text=labeltext, anchor=tk.W)
            label.grid(row=row, column=0, sticky=tk.EW, pady=2)

            widget = self._create_editor(fgc, alias, kwdata)
            widget.grid(row=row, column=1, sticky=tk.EW, pady=2)
            self._rcbag[alias] = (label, widget)
            row = row + 1
        fgc.columnconfigure(1, weight=1)

    def edit(self, wdescr, manager_options):
        self._current = wdescr

        wclass = wdescr.classname
        #class_descr = CLASS_MAP[wclass].builder
        max_children = CLASS_MAP[wclass].builder.maxchildren
        max_children = 0 if max_children is None else max_children
        is_container = CLASS_MAP[wclass].builder.container
        layout_required = CLASS_MAP[wclass].builder.layout_required
        show_layout = layout_required

        self._fprop.grid()
        self._fselector.grid()
        # manager selector
        manager = wdescr.manager
        manager_prop = properties.GRID_PROPERTIES
        if manager == 'pack':
            manager_prop = properties.PACK_PROPERTIES
        elif manager == 'place':
            manager_prop = properties.PLACE_PROPERTIES

        if show_layout:
            self._allowed_managers = manager_options
            self.layout_selector.edit(manager)
            self.layout_selector.pack()
        else:
            self.layout_selector.pack_forget()

        #layout properties
        groups = (('00', properties.MANAGER_PROPERTIES,
                   properties.LAYOUT_OPTIONS), )

        for gcode, proplist, gproperties in groups:
            for name in proplist:
                propdescr = gproperties[name]
                label, widget = self._propbag[gcode + name]
                if show_layout and name in manager_prop:
                    self.update_editor(widget, wdescr, name, propdescr)
                    label.grid()
                    widget.grid()
                else:
                    label.grid_remove()
                    widget.grid_remove()

        # determine if show grid r/c properties
        show_grid_rc = (manager == 'grid' and layout_required)

        if show_grid_rc:
            rownum = wdescr.layout_property('row')
            colnum = wdescr.layout_property('column')
            label = self._fgr_label.format(rownum)
            self._fgr.config(text=label)
            label = self._fgc_label.format(colnum)
            self._fgc.config(text=label)

            target = self._current
            for key in self._rcbag:
                rowcol, name = self.identify_gridrc_property(key)
                propdescr = properties.LAYOUT_OPTIONS[name]
                number = colnum if rowcol == 'col' else rownum
                label, widget = self._rcbag[key]
                self.update_rc_editor(rowcol, number, widget, target, name,
                                      propdescr)
            self._fgr.grid()
            self._fgc.grid()
        else:
            self._fgr.grid_remove()
            self._fgc.grid_remove()

        self._sframe.reposition()

    def _layout_manager_changed(self, event=None):
        if self._current is None:
            # I'm not editing anything
            return

        old_manager = self._current.manager
        new_manager = self.layout_selector.value
        needs_container_change = (new_manager not in self._allowed_managers)

        if needs_container_change:
            self.layout_selector.edit(old_manager)
            cb = lambda f=old_manager, t=new_manager: self._ask_manager_change(
                f, t)
            self._fselector.after_idle(cb)
        else:
            self._current.manager = new_manager
            self.edit(self._current, self._allowed_managers)

    def _ask_manager_change(self, old_manager, new_manager):
        title = _('Change Manager')
        msg = _('Change manager from {0} to {1}?')
        msg = msg.format(old_manager, new_manager)
        detail = _('All container widgets will be updated.')
        user_accepts_change = messagebox.askokcancel(
            title,
            msg,
            detail=detail,
            parent=self.layout_selector.winfo_toplevel())
        if user_accepts_change:
            topack = '<<LayoutEditorContainerManagerToPack>>'
            togrid = '<<LayoutEditorContainerManagerToGrid>>'
            event_name = togrid if new_manager == 'grid' else topack
            self._fselector.event_generate(event_name)

    def _on_property_changed(self, name, editor):
        value = editor.value
        if name in properties.MANAGER_PROPERTIES:
            self._current.layout_property(name, value)
        else:
            # asume that is a grid row/col property
            rowcol, pname = self.identify_gridrc_property(name)
            number = self._current.layout_property('row')
            if rowcol == 'col':
                number = self._current.layout_property('column')
            target = self._current
            target.gridrc_property(rowcol, number, pname, value)
            editor.event_generate('<<LayoutEditorGridRCChanged>>')

    def identify_gridrc_property(self, alias):
        return alias.split('_')

    def update_editor(self, editor, wdescr, pname, propdescr):
        pdescr = propdescr.copy()
        manager = wdescr.manager

        if manager in pdescr:
            pdescr = dict(pdescr, **pdescr[manager])

        params = pdescr.get('params', {})
        editor.parameters(**params)
        default = pdescr.get('default', '')

        value = wdescr.layout_property(pname)
        if not value and default:
            value = default
        editor.edit(value)

    def update_rc_editor(self, type_, index, editor, wdescr, pname, propdescr):
        pdescr = propdescr.copy()
        classname = wdescr.classname

        if classname in pdescr:
            pdescr = dict(pdescr, **pdescr[classname])

        params = pdescr.get('params', {})
        editor.parameters(**params)
        default = pdescr.get('default', '')

        value = ''
        value = wdescr.gridrc_property(type_, str(index), pname)
        if not value and default:
            value = default
        editor.edit(value)

    def hide_all(self):
        super(LayoutEditor, self).hide_all()
        self._fselector.grid_remove()
        self._fprop.grid_remove()
        self._fgr.grid_remove()
        self._fgc.grid_remove()