diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index b061f3b2fe8..78edf12263a 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -20,7 +20,7 @@ from idlelib.config import idleConf BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", "if", "try", "while", "with", "async"} UPDATEINTERVAL = 100 # millisec -FONTUPDATEINTERVAL = 1000 # millisec +CONFIGUPDATEINTERVAL = 1000 # millisec def get_spaces_firstword(codeline, c=re.compile(r"^(\s*)(\w*)")): @@ -45,9 +45,6 @@ def get_line_info(codeline): class CodeContext: "Display block context above the edit window." - bgcolor = "LightGray" - fgcolor = "Black" - def __init__(self, editwin): """Initialize settings for context block. @@ -69,22 +66,20 @@ class CodeContext: self.editwin = editwin self.text = editwin.text self.textfont = self.text["font"] + self.contextcolors = CodeContext.colors self.label = None self.topvisible = 1 self.info = [(0, -1, "", False)] # Start two update cycles, one for context lines, one for font changes. self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event) - self.t2 = self.text.after(FONTUPDATEINTERVAL, self.font_timer_event) + self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event) @classmethod def reload(cls): "Load class variables from config." cls.context_depth = idleConf.GetOption("extensions", "CodeContext", "maxlines", type="int", default=15) -## cls.bgcolor = idleConf.GetOption("extensions", "CodeContext", -## "bgcolor", type="str", default="LightGray") -## cls.fgcolor = idleConf.GetOption("extensions", "CodeContext", -## "fgcolor", type="str", default="Black") + cls.colors = idleConf.GetHighlight(idleConf.CurrentTheme(), 'context') def __del__(self): "Cancel scheduled events." @@ -118,7 +113,8 @@ class CodeContext: self.label = tkinter.Label( self.editwin.top, text="", anchor=W, justify=LEFT, font=self.textfont, - bg=self.bgcolor, fg=self.fgcolor, + bg=self.contextcolors['background'], + fg=self.contextcolors['foreground'], width=1, # Don't request more than we get. padx=padx, border=border, relief=SUNKEN) # Pack the label widget before and above the text_frame widget, @@ -202,13 +198,17 @@ class CodeContext: self.update_code_context() self.t1 = self.text.after(UPDATEINTERVAL, self.timer_event) - def font_timer_event(self): - "Event on editor text widget triggered every FONTUPDATEINTERVAL ms." + def config_timer_event(self): + "Event on editor text widget triggered every CONFIGUPDATEINTERVAL ms." newtextfont = self.text["font"] - if self.label and newtextfont != self.textfont: + if (self.label and (newtextfont != self.textfont or + CodeContext.colors != self.contextcolors)): self.textfont = newtextfont + self.contextcolors = CodeContext.colors self.label["font"] = self.textfont - self.t2 = self.text.after(FONTUPDATEINTERVAL, self.font_timer_event) + self.label['background'] = self.contextcolors['background'] + self.label['foreground'] = self.contextcolors['foreground'] + self.t2 = self.text.after(CONFIGUPDATEINTERVAL, self.config_timer_event) CodeContext.reload() diff --git a/Lib/idlelib/config-highlight.def b/Lib/idlelib/config-highlight.def index 4146e28c4ed..aaa2b57a7f6 100644 --- a/Lib/idlelib/config-highlight.def +++ b/Lib/idlelib/config-highlight.def @@ -31,6 +31,8 @@ stderr-foreground= red stderr-background= #ffffff console-foreground= #770000 console-background= #ffffff +context-foreground= #000000 +context-background= lightgray [IDLE New] normal-foreground= #000000 @@ -62,6 +64,8 @@ stderr-foreground= red stderr-background= #ffffff console-foreground= #770000 console-background= #ffffff +context-foreground= #000000 +context-background= lightgray [IDLE Dark] comment-foreground = #dd0000 @@ -91,3 +95,5 @@ stdout-background = #002240 hit-foreground = #002240 comment-background = #002240 break-foreground = #FFFFFF +context-foreground= #ffffff +context-background= #454545 diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py index c3e57bc692d..94b20832091 100644 --- a/Lib/idlelib/config.py +++ b/Lib/idlelib/config.py @@ -360,6 +360,8 @@ class IdleConf: 'stderr-background':'#ffffff', 'console-foreground':'#000000', 'console-background':'#ffffff', + 'context-foreground':'#000000', + 'context-background':'#ffffff', } for element in theme: if not cfgParser.has_option(themeName, element): diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 28ad4586394..7df69d5c4d6 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -799,19 +799,20 @@ class HighPage(Frame): """ self.theme_elements = { 'Normal Text': ('normal', '00'), - 'Python Keywords': ('keyword', '01'), - 'Python Definitions': ('definition', '02'), - 'Python Builtins': ('builtin', '03'), - 'Python Comments': ('comment', '04'), - 'Python Strings': ('string', '05'), - 'Selected Text': ('hilite', '06'), - 'Found Text': ('hit', '07'), - 'Cursor': ('cursor', '08'), - 'Editor Breakpoint': ('break', '09'), - 'Shell Normal Text': ('console', '10'), - 'Shell Error Text': ('error', '11'), - 'Shell Stdout Text': ('stdout', '12'), - 'Shell Stderr Text': ('stderr', '13'), + '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 Normal Text': ('console', '11'), + 'Shell Error Text': ('error', '12'), + 'Shell Stdout Text': ('stdout', '13'), + 'Shell Stderr Text': ('stderr', '14'), } self.builtin_name = tracers.add( StringVar(self), self.var_changed_builtin_name) @@ -842,6 +843,7 @@ class HighPage(Frame): ('\n', 'normal'), ('#you can click here', 'comment'), ('\n', 'normal'), ('#to choose items', 'comment'), ('\n', 'normal'), + ('code context section', 'context'), ('\n\n', 'normal'), ('def', 'keyword'), (' ', 'normal'), ('func', 'definition'), ('(param):\n ', 'normal'), ('"""string"""', 'string'), ('\n var0 = ', 'normal'), diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py index 4c775eee6b5..d446090b082 100644 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ b/Lib/idlelib/idle_test/test_codecontext.py @@ -110,6 +110,8 @@ class CodeContextTest(unittest.TestCase): def test_reload(self): codecontext.CodeContext.reload() + self.assertEqual(self.cc.colors, {'background': 'lightgray', + 'foreground': '#000000'}) self.assertEqual(self.cc.context_depth, 15) def test_toggle_code_context_event(self): @@ -125,8 +127,8 @@ class CodeContextTest(unittest.TestCase): eq(toggle(), 'break') self.assertIsNotNone(cc.label) eq(cc.label['font'], cc.textfont) - eq(cc.label['fg'], cc.fgcolor) - eq(cc.label['bg'], cc.bgcolor) + eq(cc.label['fg'], cc.colors['foreground']) + eq(cc.label['bg'], cc.colors['background']) eq(cc.label['text'], '') # Toggle off. @@ -275,11 +277,13 @@ class CodeContextTest(unittest.TestCase): self.cc.timer_event() mock_update.assert_called() - def test_font_timer_event(self): + def test_config_timer_event(self): eq = self.assertEqual cc = self.cc save_font = cc.text['font'] + save_colors = codecontext.CodeContext.colors test_font = 'FakeFont' + test_colors = {'background': '#222222', 'foreground': '#ffff00'} # Ensure code context is not active. if cc.label: @@ -287,24 +291,42 @@ class CodeContextTest(unittest.TestCase): # Nothing updates on inactive code context. cc.text['font'] = test_font - cc.font_timer_event() + codecontext.CodeContext.colors = test_colors + cc.config_timer_event() eq(cc.textfont, save_font) + eq(cc.contextcolors, save_colors) - # Activate code context, but no change to font. + # Activate code context, but no change to font or color. cc.toggle_code_context_event() cc.text['font'] = save_font - cc.font_timer_event() + codecontext.CodeContext.colors = save_colors + cc.config_timer_event() eq(cc.textfont, save_font) + eq(cc.contextcolors, save_colors) eq(cc.label['font'], save_font) + eq(cc.label['background'], save_colors['background']) + eq(cc.label['foreground'], save_colors['foreground']) # Active code context, change font. cc.text['font'] = test_font - cc.font_timer_event() + cc.config_timer_event() eq(cc.textfont, test_font) + eq(cc.contextcolors, save_colors) eq(cc.label['font'], test_font) + eq(cc.label['background'], save_colors['background']) + eq(cc.label['foreground'], save_colors['foreground']) + # Active code context, change color. cc.text['font'] = save_font - cc.font_timer_event() + codecontext.CodeContext.colors = test_colors + cc.config_timer_event() + eq(cc.textfont, save_font) + eq(cc.contextcolors, test_colors) + eq(cc.label['font'], save_font) + eq(cc.label['background'], test_colors['background']) + eq(cc.label['foreground'], test_colors['foreground']) + codecontext.CodeContext.colors = save_colors + cc.config_timer_event() class HelperFunctionText(unittest.TestCase): diff --git a/Misc/NEWS.d/next/IDLE/2018-05-29-07-14-37.bpo-33679.MgX_Ui.rst b/Misc/NEWS.d/next/IDLE/2018-05-29-07-14-37.bpo-33679.MgX_Ui.rst new file mode 100644 index 00000000000..43d78b023f6 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2018-05-29-07-14-37.bpo-33679.MgX_Ui.rst @@ -0,0 +1,12 @@ +IDLE: Re-enable color configuration for Code Context. +The difference from before is that the settings are now on the +Highlights tab instead of the Extensions tab and only change one theme +at a time instead of all themes. The default for light themes is black +on light gray, as before. The default for the IDLE Dark theme is white +on dark gray, which better fits the dark theme. + +When one starts IDLE from a console and loads a custom theme without +definitions for 'context', one will see a warning message on the console. +To stop the warning, go to Options => Configure IDLE => Highlights, +select the custom theme if not selected already, select 'Code Context', +and select foreground and background colors.