Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Initial support for Spyder's dark theme #8020

Merged
merged 12 commits into from
Oct 15, 2018
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ a Python version greater than 2.7 or 3.4 (Python <=3.3 is no longer supported).
* **Cloudpickle**: Serialize variables in the IPython kernel to send to Spyder.
* **spyder-kernels** 1.0+: Jupyter kernels for the Spyder console.
* **keyring**: Save Github credentials to report errors securely.
* **QDarkStyle**: A dark stylesheet for Qt applications, used for Spyder's dark theme.
* **pexpect**/**paramiko**: Connect to remote kernels through SSH.

### Optional dependencies
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ environment:
sympy cython keyring
PIP_DEPENDENCIES: >
pytest-qt pytest-mock pytest-timeout flaky codecov
python-language-server[all]
python-language-server[all] qdarkstyle
APPVEYOR_RDP_PASSWORD: "dcca4c4863E30d56c2e0dda6327370b3#"

matrix:
Expand Down
2 changes: 1 addition & 1 deletion continuous_integration/posix/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ else
pytest pytest-cov numpydoc scipy cython pillow jedi pycodestyle sympy \
keyring pexpect"
export PIP_DEPENDENCIES="coveralls pytest-qt pytest-mock pytest-timeout flaky \
python-language-server[all]"
python-language-server[all] qdarkstyle"
fi


Expand Down
1 change: 1 addition & 0 deletions requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ pyqt5
keyring
spyder-kernels>=1.0
python-language-server
qdarkstyle
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ def run(self):
'pyqt5<5.10;python_version>="3"',
# Pyls with all its dependencies
'python-language-server[all]',
'qdarkstyle',
# Required to get SSH connections to remote kernels
'pexpect;platform_system!="Windows"',
'paramiko;platform_system=="Windows"'
Expand Down
17 changes: 15 additions & 2 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,7 @@
from spyder.utils.misc import select_port, getcwd_or_home, get_python_executable
from spyder.widgets.fileswitcher import FileSwitcher
from spyder.plugins.lspmanager import LSPManager


from spyder.config.gui import is_dark_font_color

#==============================================================================
# Local gui imports
Expand All @@ -188,6 +187,10 @@
from spyder.otherplugins import get_spyderplugins_mods
from spyder.app import tour

#==============================================================================
# Third-party library imports
#==============================================================================
import qdarkstyle

#==============================================================================
# Get the cwd before initializing WorkingDirectory, which sets it to the one
Expand Down Expand Up @@ -553,6 +556,16 @@ def create_toolbar(self, title, object_name, iconsize=24):
def setup(self):
"""Setup main window"""
self.debug_print("*** Start of MainWindow setup ***")
self.debug_print(" ..theme configuration")
color_theme = CONF.get('color_schemes', 'color_theme')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color_theme -> ui_theme

color_scheme = CONF.get('color_schemes', 'selected')
if color_theme == 'dark':
self.setStyleSheet(qdarkstyle.load_stylesheet_from_environment())
elif color_theme == 'automatic':
if not is_dark_font_color(color_scheme):
self.setStyleSheet(
qdarkstyle.load_stylesheet_from_environment())

self.debug_print(" ..core actions")
self.close_dockwidget_action = create_action(self,
icon=ima.icon('DialogCloseButton'),
Expand Down
9 changes: 9 additions & 0 deletions spyder/config/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
from spyder.py3compat import to_text_string
from spyder.utils import syntaxhighlighters as sh

# Third-party imports
from qtconsole.styles import dark_color

# To save metadata about widget shortcuts (needed to build our
# preferences page)
Expand Down Expand Up @@ -164,5 +166,12 @@ def set_default_color_scheme(name, replace=True):
set_color_scheme(name, sh.get_color_scheme(name), replace=replace)


def is_dark_font_color(color_scheme):
"""Check if the font color used in the color scheme is dark."""
color_scheme = get_color_scheme(color_scheme)
font_color, fon_fw, fon_fs = color_scheme['normal']
return dark_color(font_color)


for _name in sh.COLOR_SCHEME_NAMES:
set_default_color_scheme(_name, replace=False)
1 change: 1 addition & 0 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@
}),
('color_schemes',
{
'color_theme': 'automatic',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this option name to ui_theme

'names': ['emacs', 'idle', 'monokai', 'pydev', 'scintilla',
'spyder', 'spyder/dark', 'zenburn', 'solarized/light',
'solarized/dark'],
Expand Down
70 changes: 58 additions & 12 deletions spyder/preferences/configdialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from spyder.widgets.colors import ColorLayout
from spyder.widgets.comboboxes import FileComboBox
from spyder.plugins.editor.widgets.codeeditor import CodeEditor
from spyder.config.gui import is_dark_font_color


HDPI_QT_PAGE = "https://doc.qt.io/qt-5/highdpi.html"
Expand Down Expand Up @@ -911,7 +912,6 @@ def setup_page(self):
icons_combo = self.create_combobox(_('Icon theme'), icon_choices,
'icon_theme', restart=True)


vertdock_box = newcb(_("Vertical title bars in panes"),
'vertical_dockwidget_titlebars')
verttabs_box = newcb(_("Vertical tabs in panes"),
Expand Down Expand Up @@ -1171,17 +1171,29 @@ def setup_page(self):
'selected')
self.schemes_combobox = schemes_combobox_widget.combobox

# Layouts
vlayout = QVBoxLayout()
color_themes = ['Automatic', 'Light', 'Dark']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color_themes -> ui_themes

color_theme_choices = list(zip(color_themes,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color_theme_choices -> ui_theme_choices

[color_theme.lower()
for color_theme in color_themes]))
color_theme_combo = self.create_combobox(_('User interface theme:'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color_theme_combo -> ui_theme_combo

color_theme_choices,
'color_theme',
restart=True)

# Layouts
manage_layout = QVBoxLayout()
manage_layout.addWidget(about_label)

combo_layout = QHBoxLayout()
combo_layout.addWidget(schemes_combobox_widget.label)
combo_layout.addWidget(schemes_combobox_widget.combobox)

color_theme_combo_layout = QHBoxLayout()
color_theme_combo_layout.addWidget(color_theme_combo.label)
color_theme_combo_layout.addWidget(color_theme_combo.combobox)

buttons_layout = QVBoxLayout()
buttons_layout.addLayout(color_theme_combo_layout)
buttons_layout.addLayout(combo_layout)
buttons_layout.addWidget(edit_button)
buttons_layout.addWidget(self.reset_button)
Expand All @@ -1200,6 +1212,7 @@ def setup_page(self):
manage_group = QGroupBox(_("Manage color schemes"))
manage_group.setLayout(manage_layout)

vlayout = QVBoxLayout()
vlayout.addWidget(manage_group)
self.setLayout(vlayout)

Expand All @@ -1223,15 +1236,46 @@ def setup_page(self):

def apply_settings(self, options):
self.set_option('selected', self.current_scheme)
self.main.editor.apply_plugin_settings(['color_scheme_name'])
if self.main.ipyconsole is not None:
self.main.ipyconsole.apply_plugin_settings(['color_scheme_name'])
if self.main.historylog is not None:
self.main.historylog.apply_plugin_settings(['color_scheme_name'])
if self.main.help is not None:
self.main.help.apply_plugin_settings(['color_scheme_name'])
self.update_combobox()
self.update_preview()
color_scheme = self.get_option('selected')
color_theme = self.get_option('color_theme')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

color_theme -> ui_theme

style_sheet = self.main.styleSheet()
if color_theme == 'automatic':
if ((not is_dark_font_color(color_scheme) and not style_sheet)
or (is_dark_font_color(color_scheme) and style_sheet)):
self.changed_options.add('color_theme')
elif 'color_theme' in self.changed_options:
self.changed_options.remove('color_theme')

if 'color_theme' not in self.changed_options:
self.main.editor.apply_plugin_settings(['color_scheme_name'])
if self.main.ipyconsole is not None:
self.main.ipyconsole.apply_plugin_settings(
['color_scheme_name'])
if self.main.historylog is not None:
self.main.historylog.apply_plugin_settings(
['color_scheme_name'])
if self.main.help is not None:
self.main.help.apply_plugin_settings(['color_scheme_name'])
self.update_combobox()
self.update_preview()
else:
if 'color_theme' in self.changed_options:
if (style_sheet and color_theme == 'dark' or
not style_sheet and color_theme == 'light'):
self.changed_options.remove('color_theme')

if 'color_theme' not in self.changed_options:
self.main.editor.apply_plugin_settings(['color_scheme_name'])
if self.main.ipyconsole is not None:
self.main.ipyconsole.apply_plugin_settings(
['color_scheme_name'])
if self.main.historylog is not None:
self.main.historylog.apply_plugin_settings(
['color_scheme_name'])
if self.main.help is not None:
self.main.help.apply_plugin_settings(['color_scheme_name'])
self.update_combobox()
self.update_preview()

# Helpers
# -------------------------------------------------------------------------
Expand Down Expand Up @@ -1532,6 +1576,8 @@ def add_color_scheme_stack(self, scheme_name, custom=False):

if not custom:
line_edit.textbox.setDisabled(True)
if not self.isVisible():
line_edit.setVisible(False)

cs_layout = QVBoxLayout()
cs_layout.addLayout(name_layout)
Expand Down
Loading