Source code for sofia_redux.visualization.setup

# Licensed under a 3-clause BSD style license - see LICENSE.rst

from logging import FileHandler

from sofia_redux.visualization import log
from sofia_redux.visualization.utils.logger \
    import StatusLogger, DialogLogger, StreamLogger

__all__ = ['Setup']


[docs] class Setup(object): """ Setup GUI controls and callbacks. """ def __init__(self, parent): """Initialize GUI setup.""" self.parent = parent self.view = parent.view
[docs] def setup_all(self): """Call all setup actions.""" self.setup_menu_bar() self.setup_controls() self.setup_line_controls() self.setup_model_controls() self.setup_order_controls() self.setup_mouse_events() self.setup_signals() self.setup_messages()
[docs] def setup_menu_bar(self): """Connect menu bar to callbacks.""" # menu bar is still TBD self.view.menubar.hide()
[docs] def setup_controls(self): """Connect control panel events to callbacks.""" # default: hide a couple control panels # self.view.order_panel.hide() self.view.axis_panel.hide() self.view.plot_panel.hide() self.view.analysis_panel.hide() # order panel has TBD functionality; hide it for now # self.view.order_panel_frame.hide() # connect signals # self.view.hightlight_pane_checkbox.toggled.connect( # self.view.toggle_pane_highlight) self.view.x_property_selector.activated.connect(self.view.set_field) self.view.y_property_selector.activated.connect(self.view.set_field) self.view.x_unit_selector.activated.connect(self.view.set_unit) self.view.y_unit_selector.activated.connect(self.view.set_unit) self.view.x_scale_linear_button.toggled.connect(self.view.set_scale) self.view.y_scale_linear_button.toggled.connect(self.view.set_scale) self.view.x_scale_log_button.toggled.connect(self.view.set_scale) self.view.y_scale_log_button.toggled.connect(self.view.set_scale) self.view.x_limit_min.editingFinished.connect(self.view.set_limits) self.view.x_limit_max.editingFinished.connect(self.view.set_limits) self.view.y_limit_min.editingFinished.connect(self.view.set_limits) self.view.y_limit_max.editingFinished.connect(self.view.set_limits) self.view.enable_overplot_checkbox.toggled.connect( self.view.toggle_overplot) self.view.axes_selector.currentIndexChanged.connect( self.view.update_controls) # zoom controls self.view.x_zoom_button.clicked.connect( lambda: self.view.start_selection('x_zoom')) self.view.y_zoom_button.clicked.connect( lambda: self.view.start_selection('y_zoom')) self.view.box_zoom_button.clicked.connect( lambda: self.view.start_selection('b_zoom')) self.view.reset_zoom_button.clicked.connect( self.view.reset_zoom) # panel collapsing self.view.collapse_controls_button.clicked.connect( self.view.toggle_controls) self.view.collapse_cursor_button.clicked.connect( self.view.toggle_cursor) self.view.collapse_file_choice_button.clicked.connect( self.view.toggle_file_panel) self.view.collapse_order_button.clicked.connect( self.view.toggle_order_panel) self.view.collapse_axis_button.clicked.connect( self.view.toggle_axis_panel) self.view.collapse_plot_button.clicked.connect( self.view.toggle_plot_panel) self.view.collapse_analysis_button.clicked.connect( self.view.toggle_analysis_panel) # cursor enabling self.view.cursor_checkbox.clicked.connect( self.view.enable_cursor_position) self.view.cursor_popout_button.clicked.connect( self.view.popout_cursor_position) # analysis self.view.open_fit_results_button.clicked.connect( self.view.open_fits_results) self.view.open_ref_data_button.clicked.connect( self.view.open_ref_data)
[docs] def setup_line_controls(self): """Connect control panel to plot callbacks.""" # pane controls self.view.add_pane_button.clicked.connect(self.view.add_pane) self.view.remove_pane_button.clicked.connect(self.view.remove_pane) # plot controls self.view.color_cycle_selector.currentTextChanged.connect( self.view.select_color_cycle) self.view.plot_type_selector.currentTextChanged.connect( self.view.select_plot_type) self.view.marker_checkbox.toggled.connect( self.view.toggle_markers) self.view.grid_checkbox.toggled.connect( self.view.toggle_grid) self.view.error_checkbox.toggled.connect( self.view.toggle_error) self.view.dark_mode_checkbox.toggled.connect( self.view.toggle_dark_mode)
[docs] def setup_model_controls(self): """Connect control panel to model callbacks.""" self.view.add_file_button.clicked.connect(self.parent.add_data) self.view.remove_file_button.clicked.connect(self.parent.remove_data)
[docs] def setup_order_controls(self): """Connect order controls to view callbacks.""" self.view.pane_selector.currentIndexChanged.connect( self.view.pane_order_selector_changed) self.view.all_panes_checkbox.stateChanged.connect( self.view.all_panes_checking) self.view.all_filenames_checkbox.stateChanged.connect( self.view.all_filenames_selection_changed) self.view.on_orders_selector.returnPressed.connect( self.view.on_orders_changed) self.view.all_enabled_orders_button.clicked.connect( self.view.enable_all_orders) self.view.off_orders_selector.returnPressed.connect( self.view.off_orders_changed) self.view.all_disabled_orders_button.clicked.connect( self.view.disable_all_orders) self.view.remove_file_from_pane_button.clicked.connect( self.view.remove_file_from_pane)
[docs] def setup_mouse_events(self): """Connect mouse events to callbacks.""" self.view.loaded_files_table.itemDoubleClicked.connect( self.parent.display_selected_model) self.view.figure_widget.canvas.mpl_connect( 'button_press_event', self.view.figure_clicked)
[docs] def setup_signals(self): """Connect signals to callbacks.""" self.view.signals.atrophy.connect(self.view.atrophy) self.view.signals.atrophy_controls.connect(self.view.atrophy_controls) self.view.signals.atrophy_bg_full.connect( self.view.atrophy_background_full) self.view.signals.atrophy_bg_partial.connect( self.view.atrophy_background_partial) # self.view.signals.refresh_order_list.connect( # self.view.refresh_order_list) self.view.signals.on_orders_changed.connect( self.view.on_orders_changed) self.view.signals.off_orders_changed.connect( self.view.off_orders_changed) self.view.signals.axis_limits_changed.connect( self.view.axis_limits_changed) self.view.signals.axis_scale_changed.connect( self.view.axis_scale_changed) self.view.signals.axis_unit_changed.connect( self.view.axis_unit_changed) self.view.signals.axis_field_changed.connect( self.view.axis_field_changed) self.view.filename_table.cellClicked.connect( self.view.filename_table_selection_changed) self.view.signals.current_pane_changed.connect( self.view.current_pane_changed) self.view.signals.model_selected.connect( self.parent.display_selected_model) self.view.signals.model_removed.connect( self.parent.remove_data) self.view.signals.end_zoom_mode.connect( self.view.clear_selection) self.view.signals.end_cursor_recording.connect( self.view.end_selection) self.view.signals.clear_fit.connect(self.view.clear_fit) self.view.signals.toggle_fit_visibility.connect( self.view.toggle_fit_visibility) self.view.signals.update_reference_lines.connect( self.view.update_reference_lines) self.view.signals.unload_reference_model.connect( self.view.unload_reference_model) self.view.signals.obtain_raw_model.connect( self.parent.get_model_backup)
[docs] def setup_messages(self): """Add filters to pass log messages to GUI handlers.""" # make sure terminal matches parent setting; # remove any old GUI or file handlers for hand in log.handlers: if isinstance(hand, StreamLogger): try: hand.setLevel(self.parent.log_level) except ValueError: # pragma: no cover pass elif (isinstance(hand, StatusLogger) or isinstance(hand, DialogLogger) or isinstance(hand, FileHandler)): log.removeHandler(hand) # INFO goes to status bar logger = StatusLogger(self.view.statusbar) logger.setLevel('INFO') log.addHandler(logger) # WARNING/ERROR goes to dialog box logger = DialogLogger(self.view) logger.setLevel('WARNING') log.addHandler(logger)