Skip to content

Commit

Permalink
Merge pull request #22029 from ccordoba12/improve-plots-ux
Browse files Browse the repository at this point in the history
PR: Improve UX of the Plots plugin
  • Loading branch information
ccordoba12 committed May 15, 2024
2 parents b4d28aa + d351599 commit bee5542
Show file tree
Hide file tree
Showing 7 changed files with 475 additions and 95 deletions.
8 changes: 4 additions & 4 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@
{
'mute_inline_plotting': True,
'show_plot_outline': False,
'auto_fit_plotting': True
}),
('editor',
{
Expand Down Expand Up @@ -545,11 +544,12 @@
'plots/previous figure': 'Ctrl+PgUp',
'plots/next figure': 'Ctrl+PgDown',
'plots/save': 'Ctrl+S',
'plots/save all': 'Ctrl+Alt+S',
'plots/save all': 'Alt+Shift+S',
'plots/close': 'Ctrl+W',
'plots/close all': 'Ctrl+Shift+W',
'plots/close all': 'Alt+Shift+W',
'plots/zoom in': "Ctrl++",
'plots/zoom out': "Ctrl+-",
'plots/auto fit': "Ctrl+0",
# -- Files --
'explorer/copy file': 'Ctrl+C',
'explorer/paste file': 'Ctrl+V',
Expand Down Expand Up @@ -670,4 +670,4 @@
# or if you want to *rename* options, then you need to do a MAJOR update in
# version, e.g. from 3.0.0 to 4.0.0
# 3. You don't need to touch this value if you're just adding a new option
CONF_VERSION = '82.2.0'
CONF_VERSION = '83.0.0'
7 changes: 7 additions & 0 deletions spyder/plugins/plots/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
# (see spyder/__init__.py for details)

"""Plots plugin tests."""
142 changes: 142 additions & 0 deletions spyder/plugins/plots/tests/test_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
# (see spyder/__init__.py for details)

"""
Tests for the Plots plugin.
"""

from unittest.mock import Mock

import pytest

from spyder.config.manager import CONF
from spyder.plugins.plots.plugin import Plots
from spyder.plugins.plots.widgets.main_widget import PlotsWidgetActions
from spyder.plugins.plots.widgets.tests.test_plots_widgets import (
add_figures_to_browser,
)
from spyder.utils.stylesheet import APP_STYLESHEET


@pytest.fixture
def plots_plugin(qapp, qtbot):
plots = Plots(None, configuration=CONF)
plots.get_widget().setMinimumSize(700, 500)
plots.get_widget().add_shellwidget(Mock())
qtbot.addWidget(plots.get_widget())
qapp.setStyleSheet(str(APP_STYLESHEET))
plots.get_widget().show()
return plots


def test_fit_action(plots_plugin, tmpdir, qtbot):
"""Test that the fit action works as expected."""
main_widget = plots_plugin.get_widget()

# Action should not be checked when no plots are available
assert not main_widget.fit_action.isChecked()

# Add some plots
figbrowser = main_widget.current_widget()
figviewer = figbrowser.figviewer
add_figures_to_browser(figbrowser, 2, tmpdir)

# Action should be checked now and zoom factor less than 100%
assert main_widget.fit_action.isChecked()
assert main_widget.zoom_disp.value() < 100

# Plot should be zoomed in at full size when unchecking action
main_widget.fit_action.setChecked(False)
assert main_widget.zoom_disp.value() == 100
qtbot.wait(200)
assert figviewer.horizontalScrollBar().isVisible()

# Action should be checked for next plot
main_widget.next_plot()
assert main_widget.fit_action.isChecked()

# Action should be unchecked when going back to the previous plot
main_widget.previous_plot()
assert not main_widget.fit_action.isChecked()

# Plot should be fitted when checking the action again
main_widget.fit_action.setChecked(True)
assert main_widget.zoom_disp.value() < 100
qtbot.wait(200)
assert not figviewer.horizontalScrollBar().isVisible()


def test_zoom_actions(plots_plugin, qtbot, tmpdir):
"""Test that the behavior of the zoom actions work as expected."""
main_widget = plots_plugin.get_widget()
zoom_in_action = main_widget.get_action(PlotsWidgetActions.ZoomIn)
zoom_out_action = main_widget.get_action(PlotsWidgetActions.ZoomOut)

# Zoom in/out actions should be disabled when no plots are available
assert not zoom_in_action.isEnabled()
assert not zoom_out_action.isEnabled()

# Add some plots
figbrowser = main_widget.current_widget()
figviewer = figbrowser.figviewer
add_figures_to_browser(figbrowser, 3, tmpdir)

# Zoom in/out actions should be enabled now
assert zoom_in_action.isEnabled()
assert zoom_out_action.isEnabled()

# Zoom in first plot twice
for __ in range(2):
main_widget.zoom_in()
qtbot.wait(100)

# Save zoom and scrollbar values to test them later
qtbot.wait(200)
zoom_1 = main_widget.zoom_disp.value()
vscrollbar = figviewer.verticalScrollBar()
hscrollbar = figviewer.horizontalScrollBar()
vscrollbar_value_1 = vscrollbar.value()
hscrollbar_value_1 = hscrollbar.value()

# Fit action should be unchecked now
assert not main_widget.fit_action.isChecked()

# Next plot should be still fitted
main_widget.next_plot()
assert main_widget.fit_action.isChecked()
assert main_widget.zoom_disp.value() < 100
assert not hscrollbar.isVisible()
assert not vscrollbar.isVisible()

# Zoom out twice this plot
for __ in range(2):
main_widget.zoom_out()
qtbot.wait(100)

# Fit action should be unchecked now
assert not main_widget.fit_action.isChecked()

# Save zoom level for later
zoom_2 = main_widget.zoom_disp.value()

# Next plot should be still fitted
main_widget.next_plot()
assert main_widget.fit_action.isChecked()

# Return to the first plot
for __ in range(2):
main_widget.previous_plot()
qtbot.wait(100)

# Check zoom level and scrollbars are restored
qtbot.wait(200)
assert main_widget.zoom_disp.value() == zoom_1
assert vscrollbar.value() == vscrollbar_value_1
assert hscrollbar.value() == hscrollbar_value_1

# Move to next plot and check zoom level is restored
main_widget.next_plot()
assert main_widget.zoom_disp.value() == zoom_2

0 comments on commit bee5542

Please sign in to comment.