(self)
Return frame of widgets for Highlights tab.

        Enable users to provisionally change foreground and background
        colors applied to textual tags.  Color mappings are stored in
        complete listings called themes.  Built-in themes in
        idlelib/config-highlight.def are fixed as far as the dialog is
        concerned. Any theme can be used as the base for a new custom
        theme, stored in .idlerc/config-highlight.cfg.

        Function load_theme_cfg() initializes tk variables and theme
        lists and calls paint_theme_sample() and set_highlight_target()
        for the current theme.  Radiobuttons builtin_theme_on and
        custom_theme_on toggle var theme_source, which controls if the
        current set of colors are from a builtin or custom theme.
        DynOptionMenus builtinlist and customlist contain lists of the
        builtin and custom themes, respectively, and the current item
        from each list is stored in vars builtin_name and custom_name.

        Function paint_theme_sample() applies the colors from the theme
        to the tags in text widget highlight_sample and then invokes
        set_color_sample().  Function set_highlight_target() sets the state
        of the radiobuttons fg_on and bg_on based on the tag and it also
        invokes set_color_sample().

        Function set_color_sample() sets the background color for the frame
        holding the color selector.  This provides a larger visual of the
        color for the current tag and plane (foreground/background).

        Note: set_color_sample() is called from many places and is often
        called more than once when a change is made.  It is invoked when
        foreground or background is selected (radiobuttons), from
        paint_theme_sample() (theme is changed or load_cfg is called), and
        from set_highlight_target() (target tag is changed or load_cfg called).

        Button delete_custom invokes delete_custom() to delete
        a custom theme from idleConf.userCfg['highlight'] and changes.
        Button save_custom invokes save_as_new_theme() which calls
        get_new_theme_name() and create_new() to save a custom theme
        and its colors to idleConf.userCfg['highlight'].

        Radiobuttons fg_on and bg_on toggle var fg_bg_toggle to control
        if the current selected color for a tag is for the foreground or
        background.

        DynOptionMenu targetlist contains a readable description of the
        tags applied to Python source within IDLE.  Selecting one of the
        tags from this list populates highlight_target, which has a callback
        function set_highlight_target().

        Text widget highlight_sample displays a block of text (which is
        mock Python code) in which is embedded the defined tags and reflects
        the color attributes of the current theme and changes for those tags.
        Mouse button 1 allows for selection of a tag and updates
        highlight_target with that tag value.

        Note: The font in highlight_sample is set through the config in
        the fonts tab.

        In other words, a tag can be selected either from targetlist or
        by clicking on the sample text within highlight_sample.  The
        plane (foreground/background) is selected via the radiobutton.
        Together, these two (tag and plane) control what color is
        shown in set_color_sample() for the current theme.  Button set_color
        invokes get_color() which displays a ColorChooser to change the
        color for the selected tag/plane.  If a new color is picked,
        it will be saved to changes and the highlight_sample and
        frame background will be updated.

        Tk Variables:
            color: Color of selected target.
            builtin_name: Menu variable for built-in theme.
            custom_name: Menu variable for custom theme.
            fg_bg_toggle: Toggle for foreground/background color.
                Note: this has no callback.
            theme_source: Selector for built-in or custom theme.
            highlight_target: Menu variable for the highlight tag target.

        Instance Data Attributes:
            theme_elements: Dictionary of tags for text highlighting.
                The key is the display name and the value is a tuple of
                (tag name, display sort order).

        Methods [attachment]:
            load_theme_cfg: Load current highlight colors.
            get_color: Invoke colorchooser [button_set_color].
            set_color_sample_binding: Call set_color_sample [fg_bg_toggle].
            set_highlight_target: set fg_bg_toggle, set_color_sample().
            set_color_sample: Set frame background to target.
            on_new_color_set: Set new color and add option.
            paint_theme_sample: Recolor sample.
            get_new_theme_name: Get from popup.
            create_new: Combine theme with changes and save.
            save_as_new_theme: Save [button_save_custom].
            set_theme_type: Command for [theme_source].
            delete_custom: Activate default [button_delete_custom].
            save_new: Save to userCfg['theme'] (is function).

        Widgets of highlights page frame:  (*) widgets bound to self
            frame_custom: LabelFrame
                (*)highlight_sample: Text
                (*)frame_color_set: Frame
                    (*)button_set_color: Button
                    (*)targetlist: DynOptionMenu - highlight_target
                frame_fg_bg_toggle: Frame
                    (*)fg_on: Radiobutton - fg_bg_toggle
                    (*)bg_on: Radiobutton - fg_bg_toggle
                (*)button_save_custom: Button
            frame_theme: LabelFrame
                theme_type_title: Label
                (*)builtin_theme_on: Radiobutton - theme_source
                (*)custom_theme_on: Radiobutton - theme_source
                (*)builtinlist: DynOptionMenu - builtin_name
                (*)customlist: DynOptionMenu - custom_name
                (*)button_delete_custom: Button
                (*)theme_message: Label
Return frame of widgets for Highlights tab.
Return frame of widgets for Highlights tab .
def create_page_highlight(self):
        """Return frame of widgets for Highlights tab.

        Enable users to provisionally change foreground and background
        colors applied to textual tags.  Color mappings are stored in
        complete listings called themes.  Built-in themes in
        idlelib/config-highlight.def are fixed as far as the dialog is
        concerned. Any theme can be used as the base for a new custom
        theme, stored in .idlerc/config-highlight.cfg.

        Function load_theme_cfg() initializes tk variables and theme
        lists and calls paint_theme_sample() and set_highlight_target()
        for the current theme.  Radiobuttons builtin_theme_on and
        custom_theme_on toggle var theme_source, which controls if the
        current set of colors are from a builtin or custom theme.
        DynOptionMenus builtinlist and customlist contain lists of the
        builtin and custom themes, respectively, and the current item
        from each list is stored in vars builtin_name and custom_name.

        Function paint_theme_sample() applies the colors from the theme
        to the tags in text widget highlight_sample and then invokes
        set_color_sample().  Function set_highlight_target() sets the state
        of the radiobuttons fg_on and bg_on based on the tag and it also
        invokes set_color_sample().

        Function set_color_sample() sets the background color for the frame
        holding the color selector.  This provides a larger visual of the
        color for the current tag and plane (foreground/background).

        Note: set_color_sample() is called from many places and is often
        called more than once when a change is made.  It is invoked when
        foreground or background is selected (radiobuttons), from
        paint_theme_sample() (theme is changed or load_cfg is called), and
        from set_highlight_target() (target tag is changed or load_cfg called).

        Button delete_custom invokes delete_custom() to delete
        a custom theme from idleConf.userCfg['highlight'] and changes.
        Button save_custom invokes save_as_new_theme() which calls
        get_new_theme_name() and create_new() to save a custom theme
        and its colors to idleConf.userCfg['highlight'].

        Radiobuttons fg_on and bg_on toggle var fg_bg_toggle to control
        if the current selected color for a tag is for the foreground or
        background.

        DynOptionMenu targetlist contains a readable description of the
        tags applied to Python source within IDLE.  Selecting one of the
        tags from this list populates highlight_target, which has a callback
        function set_highlight_target().

        Text widget highlight_sample displays a block of text (which is
        mock Python code) in which is embedded the defined tags and reflects
        the color attributes of the current theme and changes for those tags.
        Mouse button 1 allows for selection of a tag and updates
        highlight_target with that tag value.

        Note: The font in highlight_sample is set through the config in
        the fonts tab.

        In other words, a tag can be selected either from targetlist or
        by clicking on the sample text within highlight_sample.  The
        plane (foreground/background) is selected via the radiobutton.
        Together, these two (tag and plane) control what color is
        shown in set_color_sample() for the current theme.  Button set_color
        invokes get_color() which displays a ColorChooser to change the
        color for the selected tag/plane.  If a new color is picked,
        it will be saved to changes and the highlight_sample and
        frame background will be updated.

        Tk Variables:
            color: Color of selected target.
            builtin_name: Menu variable for built-in theme.
            custom_name: Menu variable for custom theme.
            fg_bg_toggle: Toggle for foreground/background color.
                Note: this has no callback.
            theme_source: Selector for built-in or custom theme.
            highlight_target: Menu variable for the highlight tag target.

        Instance Data Attributes:
            theme_elements: Dictionary of tags for text highlighting.
                The key is the display name and the value is a tuple of
                (tag name, display sort order).

        Methods [attachment]:
            load_theme_cfg: Load current highlight colors.
            get_color: Invoke colorchooser [button_set_color].
            set_color_sample_binding: Call set_color_sample [fg_bg_toggle].
            set_highlight_target: set fg_bg_toggle, set_color_sample().
            set_color_sample: Set frame background to target.
            on_new_color_set: Set new color and add option.
            paint_theme_sample: Recolor sample.
            get_new_theme_name: Get from popup.
            create_new: Combine theme with changes and save.
            save_as_new_theme: Save [button_save_custom].
            set_theme_type: Command for [theme_source].
            delete_custom: Activate default [button_delete_custom].
            save_new: Save to userCfg['theme'] (is function).

        Widgets of highlights page frame:  (*) widgets bound to self
            frame_custom: LabelFrame
                (*)highlight_sample: Text
                (*)frame_color_set: Frame
                    (*)button_set_color: Button
                    (*)targetlist: DynOptionMenu - highlight_target
                frame_fg_bg_toggle: Frame
                    (*)fg_on: Radiobutton - fg_bg_toggle
                    (*)bg_on: Radiobutton - fg_bg_toggle
                (*)button_save_custom: Button
            frame_theme: LabelFrame
                theme_type_title: Label
                (*)builtin_theme_on: Radiobutton - theme_source
                (*)custom_theme_on: Radiobutton - theme_source
                (*)builtinlist: DynOptionMenu - builtin_name
                (*)customlist: DynOptionMenu - custom_name
                (*)button_delete_custom: Button
                (*)theme_message: Label
        """
        self.theme_elements = {
            'Normal Code or Text': ('normal', '00'),
            'Code Context': ('context', '01'),
            'Python Keywords': ('keyword', '02'),
            'Python Definitions': ('definition', '03'),
            'Python Builtins': ('builtin', '04'),
            'Python Comments': ('comment', '05'),
            'Python Strings': ('string', '06'),
            'Selected Text': ('hilite', '07'),
            'Found Text': ('hit', '08'),
            'Cursor': ('cursor', '09'),
            'Editor Breakpoint': ('break', '10'),
            'Shell Prompt': ('console', '11'),
            'Error Text': ('error', '12'),
            'Shell User Output': ('stdout', '13'),
            'Shell User Exception': ('stderr', '14'),
            'Line Number': ('linenumber', '16'),
            }
        self.builtin_name = tracers.add(
                StringVar(self), self.var_changed_builtin_name)
        self.custom_name = tracers.add(
                StringVar(self), self.var_changed_custom_name)
        self.fg_bg_toggle = BooleanVar(self)
        self.color = tracers.add(
                StringVar(self), self.var_changed_color)
        self.theme_source = tracers.add(
                BooleanVar(self), self.var_changed_theme_source)
        self.highlight_target = tracers.add(
                StringVar(self), self.var_changed_highlight_target)

        # Create widgets:
        # body frame and section frames.
        frame_custom = LabelFrame(self, borderwidth=2, relief=GROOVE,
                                  text=' Custom Highlighting ')
        frame_theme = LabelFrame(self, borderwidth=2, relief=GROOVE,
                                 text=' Highlighting Theme ')
        # frame_custom.
        sample_frame = ScrollableTextFrame(
                frame_custom, relief=SOLID, borderwidth=1)
        text = self.highlight_sample = sample_frame.text
        text.configure(
                font=('courier', 12, ''), cursor='hand2', width=1, height=1,
                takefocus=FALSE, highlightthickness=0, wrap=NONE)
        # Prevent perhaps invisible selection of word or slice.
        text.bind('<Double-Button-1>', lambda e: 'break')
        text.bind('<B1-Motion>', lambda e: 'break')
        string_tags=(
            ('# Click selects item.', 'comment'), ('\n', 'normal'),
            ('code context section', 'context'), ('\n', 'normal'),
            ('| cursor', 'cursor'), ('\n', 'normal'),
            ('def', 'keyword'), (' ', 'normal'),
            ('func', 'definition'), ('(param):\n  ', 'normal'),
            ('"Return None."', 'string'), ('\n  var0 = ', 'normal'),
            ("'string'", 'string'), ('\n  var1 = ', 'normal'),
            ("'selected'", 'hilite'), ('\n  var2 = ', 'normal'),
            ("'found'", 'hit'), ('\n  var3 = ', 'normal'),
            ('list', 'builtin'), ('(', 'normal'),
            ('None', 'keyword'), (')\n', 'normal'),
            ('  breakpoint("line")', 'break'), ('\n\n', 'normal'),
            ('>>>', 'console'), (' 3.14**2\n', 'normal'),
            ('9.8596', 'stdout'), ('\n', 'normal'),
            ('>>>', 'console'), (' pri ', 'normal'),
            ('n', 'error'), ('t(\n', 'normal'),
            ('SyntaxError', 'stderr'), ('\n', 'normal'))
        for string, tag in string_tags:
            text.insert(END, string, tag)
        n_lines = len(text.get('1.0', END).splitlines())
        for lineno in range(1, n_lines):
            text.insert(f'{lineno}.0',
                        f'{lineno:{len(str(n_lines))}d} ',
                        'linenumber')
        for element in self.theme_elements:
            def tem(event, elem=element):
                # event.widget.winfo_top_level().highlight_target.set(elem)
                self.highlight_target.set(elem)
            text.tag_bind(
                    self.theme_elements[element][0], '<ButtonPress-1>', tem)
        text['state'] = 'disabled'
        self.style.configure('frame_color_set.TFrame', borderwidth=1,
                             relief='solid')
        self.frame_color_set = Frame(frame_custom, style='frame_color_set.TFrame')
        frame_fg_bg_toggle = Frame(frame_custom)
        self.button_set_color = Button(
                self.frame_color_set, text='Choose Color for :',
                command=self.get_color)
        self.targetlist = DynOptionMenu(
                self.frame_color_set, self.highlight_target, None,
                highlightthickness=0) #, command=self.set_highlight_targetBinding
        self.fg_on = Radiobutton(
                frame_fg_bg_toggle, variable=self.fg_bg_toggle, value=1,
                text='Foreground', command=self.set_color_sample_binding)
        self.bg_on = Radiobutton(
                frame_fg_bg_toggle, variable=self.fg_bg_toggle, value=0,
                text='Background', command=self.set_color_sample_binding)
        self.fg_bg_toggle.set(1)
        self.button_save_custom = Button(
                frame_custom, text='Save as New Custom Theme',
                command=self.save_as_new_theme)
        # frame_theme.
        theme_type_title = Label(frame_theme, text='Select : ')
        self.builtin_theme_on = Radiobutton(
                frame_theme, variable=self.theme_source, value=1,
                command=self.set_theme_type, text='a Built-in Theme')
        self.custom_theme_on = Radiobutton(
                frame_theme, variable=self.theme_source, value=0,
                command=self.set_theme_type, text='a Custom Theme')
        self.builtinlist = DynOptionMenu(
                frame_theme, self.builtin_name, None, command=None)
        self.customlist = DynOptionMenu(
                frame_theme, self.custom_name, None, command=None)
        self.button_delete_custom = Button(
                frame_theme, text='Delete Custom Theme',
                command=self.delete_custom)
        self.theme_message = Label(frame_theme, borderwidth=2)
        # Pack widgets:
        # body.
        frame_custom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
        frame_theme.pack(side=TOP, padx=5, pady=5, fill=X)
        # frame_custom.
        self.frame_color_set.pack(side=TOP, padx=5, pady=5, fill=X)
        frame_fg_bg_toggle.pack(side=TOP, padx=5, pady=0)
        sample_frame.pack(
                side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH)
        self.button_set_color.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4)
        self.targetlist.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=3)
        self.fg_on.pack(side=LEFT, anchor=E)
        self.bg_on.pack(side=RIGHT, anchor=W)
        self.button_save_custom.pack(side=BOTTOM, fill=X, padx=5, pady=5)
        # frame_theme.
        theme_type_title.pack(side=TOP, anchor=W, padx=5, pady=5)
        self.builtin_theme_on.pack(side=TOP, anchor=W, padx=5)
        self.custom_theme_on.pack(side=TOP, anchor=W, padx=5, pady=2)
        self.builtinlist.pack(side=TOP, fill=X, padx=5, pady=5)
        self.customlist.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5)
        self.button_delete_custom.pack(side=TOP, fill=X, padx=5, pady=5)
        self.theme_message.pack(side=TOP, fill=X, pady=5)
def create_page_highlight ( self ) : self . theme_elements = { 'Normal Code or Text' : ( 'normal' , '00' ) , 'Code Context' : ( 'context' , '01' ) , 'Python Keywords' : ( 'keyword' , '02' ) , 'Python Definitions' : ( 'definition' , '03' ) , 'Python Builtins' : ( 'builtin' , '04' ) , 'Python Comments' : ( 'comment' , '05' ) , 'Python Strings' : ( 'string' , '06' ) , 'Selected Text' : ( 'hilite' , '07' ) , 'Found Text' : ( 'hit' , '08' ) , 'Cursor' : ( 'cursor' , '09' ) , 'Editor Breakpoint' : ( 'break' , '10' ) , 'Shell Prompt' : ( 'console' , '11' ) , 'Error Text' : ( 'error' , '12' ) , 'Shell User Output' : ( 'stdout' , '13' ) , 'Shell User Exception' : ( 'stderr' , '14' ) , 'Line Number' : ( 'linenumber' , '16' ) , } self . builtin_name = tracers . add ( StringVar ( self ) , self . var_changed_builtin_name ) self . custom_name = tracers . add ( StringVar ( self ) , self . var_changed_custom_name ) self . fg_bg_toggle = BooleanVar ( self ) self . color = tracers . add ( StringVar ( self ) , self . var_changed_color ) self . theme_source = tracers . add ( BooleanVar ( self ) , self . var_changed_theme_source ) self . highlight_target = tracers . add ( StringVar ( self ) , self . var_changed_highlight_target ) # Create widgets: # body frame and section frames. frame_custom = LabelFrame ( self , borderwidth = 2 , relief = GROOVE , text = ' Custom Highlighting ' ) frame_theme = LabelFrame ( self , borderwidth = 2 , relief = GROOVE , text = ' Highlighting Theme ' ) # frame_custom. sample_frame = ScrollableTextFrame ( frame_custom , relief = SOLID , borderwidth = 1 ) text = self . highlight_sample = sample_frame . text text . configure ( font = ( 'courier' , 12 , '' ) , cursor = 'hand2' , width = 1 , height = 1 , takefocus = FALSE , highlightthickness = 0 , wrap = NONE ) # Prevent perhaps invisible selection of word or slice. text . bind ( '<Double-Button-1>' , lambda e : 'break' ) text . bind ( '<B1-Motion>' , lambda e : 'break' ) string_tags = ( ( '# Click selects item.' , 'comment' ) , ( '\n' , 'normal' ) , ( 'code context section' , 'context' ) , ( '\n' , 'normal' ) , ( '| cursor' , 'cursor' ) , ( '\n' , 'normal' ) , ( 'def' , 'keyword' ) , ( ' ' , 'normal' ) , ( 'func' , 'definition' ) , ( '(param):\n  ' , 'normal' ) , ( '"Return None."' , 'string' ) , ( '\n  var0 = ' , 'normal' ) , ( "'string'" , 'string' ) , ( '\n  var1 = ' , 'normal' ) , ( "'selected'" , 'hilite' ) , ( '\n  var2 = ' , 'normal' ) , ( "'found'" , 'hit' ) , ( '\n  var3 = ' , 'normal' ) , ( 'list' , 'builtin' ) , ( '(' , 'normal' ) , ( 'None' , 'keyword' ) , ( ')\n' , 'normal' ) , ( '  breakpoint("line")' , 'break' ) , ( '\n\n' , 'normal' ) , ( '>>>' , 'console' ) , ( ' 3.14**2\n' , 'normal' ) , ( '9.8596' , 'stdout' ) , ( '\n' , 'normal' ) , ( '>>>' , 'console' ) , ( ' pri ' , 'normal' ) , ( 'n' , 'error' ) , ( 't(\n' , 'normal' ) , ( 'SyntaxError' , 'stderr' ) , ( '\n' , 'normal' ) ) for string , tag in string_tags : text . insert ( END , string , tag ) n_lines = len ( text . get ( '1.0' , END ) . splitlines ( ) ) for lineno in range ( 1 , n_lines ) : text . insert ( f'{lineno}.0' , f'{lineno:{len(str(n_lines))}d} ' , 'linenumber' ) for element in self . theme_elements : def tem ( event , elem = element ) : # event.widget.winfo_top_level().highlight_target.set(elem) self . highlight_target . set ( elem ) text . tag_bind ( self . theme_elements [ element ] [ 0 ] , '<ButtonPress-1>' , tem ) text [ 'state' ] = 'disabled' self . style . configure ( 'frame_color_set.TFrame' , borderwidth = 1 , relief = 'solid' ) self . frame_color_set = Frame ( frame_custom , style = 'frame_color_set.TFrame' ) frame_fg_bg_toggle = Frame ( frame_custom ) self . button_set_color = Button ( self . frame_color_set , text = 'Choose Color for :' , command = self . get_color ) self . targetlist = DynOptionMenu ( self . frame_color_set , self . highlight_target , None , highlightthickness = 0 ) #, command=self.set_highlight_targetBinding self . fg_on = Radiobutton ( frame_fg_bg_toggle , variable = self . fg_bg_toggle , value = 1 , text = 'Foreground' , command = self . set_color_sample_binding ) self . bg_on = Radiobutton ( frame_fg_bg_toggle , variable = self . fg_bg_toggle , value = 0 , text = 'Background' , command = self . set_color_sample_binding ) self . fg_bg_toggle . set ( 1 ) self . button_save_custom = Button ( frame_custom , text = 'Save as New Custom Theme' , command = self . save_as_new_theme ) # frame_theme. theme_type_title = Label ( frame_theme , text = 'Select : ' ) self . builtin_theme_on = Radiobutton ( frame_theme , variable = self . theme_source , value = 1 , command = self . set_theme_type , text = 'a Built-in Theme' ) self . custom_theme_on = Radiobutton ( frame_theme , variable = self . theme_source , value = 0 , command = self . set_theme_type , text = 'a Custom Theme' ) self . builtinlist = DynOptionMenu ( frame_theme , self . builtin_name , None , command = None ) self . customlist = DynOptionMenu ( frame_theme , self . custom_name , None , command = None ) self . button_delete_custom = Button ( frame_theme , text = 'Delete Custom Theme' , command = self . delete_custom ) self . theme_message = Label ( frame_theme , borderwidth = 2 ) # Pack widgets: # body. frame_custom . pack ( side = LEFT , padx = 5 , pady = 5 , expand = TRUE , fill = BOTH ) frame_theme . pack ( side = TOP , padx = 5 , pady = 5 , fill = X ) # frame_custom. self . frame_color_set . pack ( side = TOP , padx = 5 , pady = 5 , fill = X ) frame_fg_bg_toggle . pack ( side = TOP , padx = 5 , pady = 0 ) sample_frame . pack ( side = TOP , padx = 5 , pady = 5 , expand = TRUE , fill = BOTH ) self . button_set_color . pack ( side = TOP , expand = TRUE , fill = X , padx = 8 , pady = 4 ) self . targetlist . pack ( side = TOP , expand = TRUE , fill = X , padx = 8 , pady = 3 ) self . fg_on . pack ( side = LEFT , anchor = E ) self . bg_on . pack ( side = RIGHT , anchor = W ) self . button_save_custom . pack ( side = BOTTOM , fill = X , padx = 5 , pady = 5 ) # frame_theme. theme_type_title . pack ( side = TOP , anchor = W , padx = 5 , pady = 5 ) self . builtin_theme_on . pack ( side = TOP , anchor = W , padx = 5 ) self . custom_theme_on . pack ( side = TOP , anchor = W , padx = 5 , pady = 2 ) self . builtinlist . pack ( side = TOP , fill = X , padx = 5 , pady = 5 ) self . customlist . pack ( side = TOP , fill = X , anchor = W , padx = 5 , pady = 5 ) self . button_delete_custom . pack ( side = TOP , fill = X , padx = 5 , pady = 5 ) self . theme_message . pack ( side = TOP , fill = X , pady = 5 )