"""
This module defines the `PanoramaConfig` class, which handles the configuration of panorama views in an application
"""
[docs]
class PanoramaConfig:
"""
This class provides methods to handle user interactions related to configuring panorama views,
including changing modes between car and tube, setting initial values for UI elements,
updating properties based on user input, and managing signals between UI elements and the underlying model.
Methods:
__init__: Initializes a new instance of the PanoramaConfig class.
_connect_event: Connects UI signals to corresponding slots.
onclick_btn_panorama: Handles click event for the 'panorama' button.
change_mode_panorama: Changes the panorama mode between 'car' and 'tube'.
set_initial_value_to_ui_panorama: Sets initial values for UI elements in panorama view configuration.
change_properties_panorama: Changes properties of the panorama view configuration based on user input.
change_properties_crop_panorama: Changes the properties of the panorama crop based on user input.
block_signal_pano_tube: Blocks signals for UI elements related to the tube panorama view.
unblock_signal_pano_tube: Unblocks signals for UI elements related to the tube panorama view.
block_signal_pano_car: Blocks signals for UI elements related to the car panorama view.
unblock_signal_pano_car: Unblocks signals for UI elements related to the car panorama view.
showing_config_panorama_tube: Updates UI elements with panorama tube configuration values.
showing_config_panorama_car: Updates UI elements with panorama car configuration values.
change_properties_panorama_tube: Changes properties of the panorama tube view configuration.
change_properties_panorama_car: Changes properties of the panorama car view configuration.
check_box_active_mode_panorama: Checks and sets the active mode in the panorama view.
"""
[docs]
def __init__(self, controller):
self._controller = controller
self._model = controller.model
self._ui_object = controller.ui_object
# self._main_config = controller.model.main_config
self._connect_event()
[docs]
def _connect_event(self):
self._ui_object.btn_panorama_view.clicked.connect(self.onclick_btn_panorama)
self._ui_object.btn_panorama_view.setShortcut("Ctrl+P")
self._ui_object.checkbox_flip.toggled.connect(self.change_properties_panorama)
self._ui_object.spinbox_alpha_max_panorama_car.valueChanged.connect(self.change_properties_panorama)
self._ui_object.doubleSpinBox_pano_car_alpha.valueChanged.connect(self.change_properties_panorama)
self._ui_object.doubleSpinBox_pano_car_beta.valueChanged.connect(self.change_properties_panorama)
self._ui_object.doubleSpinBox_pano_car_crop_left.valueChanged.connect(self.change_properties_crop_panorama)
self._ui_object.doubleSpinBox_pano_car_crop_right.valueChanged.connect(self.change_properties_crop_panorama)
self._ui_object.doubleSpinBox_pano_car_crop_top.valueChanged.connect(self.change_properties_crop_panorama)
self._ui_object.doubleSpinBox_pano_car_crop_bottom.valueChanged.connect(self.change_properties_crop_panorama)
self._ui_object.doubleSpinBox_pano_tube_alpha_min.valueChanged.connect(self.change_properties_panorama)
self._ui_object.doubleSpinBox_pano_tube_alpha_max.valueChanged.connect(self.change_properties_panorama)
self._ui_object.doubleSpinBox_pano_tube_crop_top.valueChanged.connect(self.change_properties_crop_panorama)
self._ui_object.doubleSpinBox_pano_tube_crop_buttom.valueChanged.connect(self.change_properties_crop_panorama)
self._ui_object.radioButton_car.toggled.connect(self.change_mode_panorama)
self._ui_object.radioButton_tube.toggled.connect(self.change_mode_panorama)
[docs]
def onclick_btn_panorama(self):
"""
Handle click event for the 'panorama' button.
Change the app's recent view state to 'PanoramaView',
shows the widget mode view and frame pointer anypoint,
sets the current index of the widget mode view to 1,
and sets the state rubberband to False if an image has been loaded.
Return:
None
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: onclick_btn_panorama(), "
"Click push button Panorama image")
if self._controller.model.image_original is not None:
if self._controller.model.source_usable:
if self._model.set_moildev.moildev_main is not None:
self._controller.ctrl_stylesheet.change_stylesheet_selected_menu()
self._controller.model.mode_view = "PanoramaView"
self.change_mode_panorama()
self._ui_object.widget_mode_view.show()
self._ui_object.check_draw_poligon_pano.setChecked(False)
self._ui_object.widget_mode_view.setCurrentIndex(1)
self._ui_object.frame_pointer_in_recenter_frame.show()
else:
self._controller.model.mode_view = "FisheyeView"
message = ("Source not usable to apply Panorama transformation, \n"
"or cant access the parameter of the image on the database,"
"please select another source or or contact the developer if you are confused.")
self._controller.ctrl_message_box.display_message_box(message, "information")
else:
self._controller.model.mode_view = "FisheyeView"
message = ("Source not usable to apply Panorama transformation, \n"
"or cant access the parameter of the image on the database,"
"please select another source or or contact the developer if you are confused.")
self._controller.ctrl_message_box.display_message_box(message, "information")
else:
self._controller.model.mode_view = "FisheyeView"
message = "No media found, please select the file \nbefore you perform the operation!"
self._controller.ctrl_message_box.display_message_box(message, "information")
[docs]
def change_mode_panorama(self):
"""
Change the panorama mode to either 'car' or 'tube'.
This method sets the panorama mode to either 'car' or 'tube' based on the selected radio button.
If the 'car' radio button is selected, the car configuration frame is shown and the tube configuration frame
is hidden. The opposite is true if the 'tube' radio button is selected. The panorama configuration object is
then updated and the maps for the selected mode are created.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: change_mode_panorama(), "
"Click push button Change panorama to car or tube")
self._controller.model.view_zoom_area.state_rubberband = False
# self._controller.main_apps_model.model_apps_panorama.create_maps_fov()
if self._ui_object.radioButton_car.isChecked():
self._ui_object.frame_panorama_tube_config.hide()
self._ui_object.frame_panorama_car_config.show()
self.showing_config_panorama_car()
self._controller.model.view_panorama.panorama_mode = "car"
self._controller.model.view_panorama.create_maps_panorama_car()
else:
self._ui_object.frame_panorama_car_config.hide()
self._ui_object.frame_panorama_tube_config.show()
self.showing_config_panorama_tube()
self._controller.model.view_panorama.panorama_mode = "tube"
self._controller.model.view_panorama.create_maps_panorama_tube()
self.set_initial_value_to_ui_panorama()
self._controller.display_image_to_ui()
self._controller.model.save_main_config_update()
[docs]
def set_initial_value_to_ui_panorama(self):
"""
Set initial values to the user interface elements for the Panorama view configuration.
This method sets the initial values of spin boxes and double spin boxes in the user interface
based on the Panorama view configuration.
Return:
None
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: set_initial_value_to_ui_panorama(), "
"Set value config panorama to user interface")
self._ui_object.spinBox_icx.blockSignals(True)
self._ui_object.spinBox_icy.blockSignals(True)
self._ui_object.doubleSpinBox_alpha_rec.blockSignals(True)
self._ui_object.doubleSpinBox_beta_rec.blockSignals(True)
if self._ui_object.radioButton_car.isChecked():
x = self._model.main_config["Pano_car"]["coord"][0]
y = self._model.main_config["Pano_car"]["coord"][1]
alpha = self._model.main_config["Pano_car"]["alpha"]
beta = self._model.main_config["Pano_car"]["beta"]
else:
x = self._model.main_config["Image_original"]["center_coord"][0]
y = self._model.main_config["Image_original"]["center_coord"][1]
alpha = 0
beta = 0
self._ui_object.spinBox_icx.setValue(x)
self._ui_object.spinBox_icy.setValue(y)
self._ui_object.doubleSpinBox_alpha_rec.setValue(round(alpha, 2))
self._ui_object.doubleSpinBox_beta_rec.setValue(round(beta, 2))
self._ui_object.spinBox_icx.blockSignals(False)
self._ui_object.spinBox_icy.blockSignals(False)
self._ui_object.doubleSpinBox_alpha_rec.blockSignals(False)
self._ui_object.doubleSpinBox_beta_rec.blockSignals(False)
[docs]
def change_properties_panorama(self):
"""
Change the properties of the panorama configuration according to the selected options.
If there is a result image, this function updates the panorama configuration and maps based on the
selected radio button, which can be "Car" or "Tube". It then updates the file configuration. If
there is no result image, this function does nothing.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: change_properties_panorama(), "
"Change Properties (value config) panorama car or tube when change mode")
self._controller.model.view_zoom_area.state_rubberband = False
if self._ui_object.radioButton_car.isChecked():
self.change_properties_panorama_car()
self._controller.model.view_panorama.create_maps_panorama_car()
else:
self.change_properties_panorama_tube()
self._controller.model.view_panorama.create_maps_panorama_tube()
self._controller.display_image_to_ui()
[docs]
def change_properties_crop_panorama(self):
"""
Change the properties of the current panorama crop.
If there is a panorama image loaded, this function updates the properties of the crop using the settings
selected in the UI. If the "car" option is selected, the panorama is cropped to a horizontal field of view
of 360 degrees and a vertical field of view of 90 degrees. If the "tube" option is selected, the panorama is
cropped to a horizontal field of view of 180 degrees and a vertical field of view of 360 degrees.
After updating the properties of the crop, this function updates the app's configuration file and creates
a new image result.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: change_properties_crop_panorama(), "
"Change Properties crop panorama car or tube when change mode")
self._controller.model.view_zoom_area.state_rubberband = False
if self._ui_object.radioButton_car.isChecked():
self.change_properties_panorama_car()
else:
self.change_properties_panorama_tube()
self._controller.display_image_to_ui()
[docs]
def block_signal_pano_tube(self):
"""
Block signals for panoptic tube spin boxes and double spin boxes.
This method blocks signals for the following spin boxes and double spin boxes:
- self.ui_object.doubleSpinBox_pano_tube_alpha_min
- self.ui_object.doubleSpinBox_pano_tube_alpha_max
- self.ui_object.doubleSpinBox_pano_tube_crop_top
- self.ui_object.doubleSpinBox_pano_tube_crop_bottom
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: block_signal_pano_tube(), "
"Block signal configuration Properties panorama tube")
self._ui_object.doubleSpinBox_pano_tube_alpha_min.blockSignals(True)
self._ui_object.doubleSpinBox_pano_tube_alpha_max.blockSignals(True)
self._ui_object.doubleSpinBox_pano_tube_crop_top.blockSignals(True)
self._ui_object.doubleSpinBox_pano_tube_crop_buttom.blockSignals(True)
[docs]
def unblock_signal_pano_tube(self):
"""
Unblock the signals for the pano tube settings widgets.
This function calls the _unblock_signal method to unblock the signals for the pano tube settings widgets.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: unblock_signal_pano_tube(), "
"Unblock signal configuration Properties panorama tube")
self._ui_object.doubleSpinBox_pano_tube_alpha_min.blockSignals(False)
self._ui_object.doubleSpinBox_pano_tube_alpha_max.blockSignals(False)
self._ui_object.doubleSpinBox_pano_tube_crop_top.blockSignals(False)
self._ui_object.doubleSpinBox_pano_tube_crop_buttom.blockSignals(False)
[docs]
def block_signal_pano_car(self):
"""
Block the signals of certain UI elements related to the panoramic car view.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: block_signal_pano_car(), "
"Block signal configuration Properties panorama car")
self._ui_object.doubleSpinBox_pano_car_alpha.blockSignals(True)
self._ui_object.doubleSpinBox_pano_car_beta.blockSignals(True)
self._ui_object.doubleSpinBox_pano_car_crop_left.blockSignals(True)
self._ui_object.doubleSpinBox_pano_car_crop_right.blockSignals(True)
self._ui_object.doubleSpinBox_pano_car_crop_top.blockSignals(True)
self._ui_object.doubleSpinBox_pano_car_crop_bottom.blockSignals(True)
[docs]
def unblock_signal_pano_car(self):
"""
Unblock signals for a set of widgets related to the panoramic car view.
This function unblocks signals for the following widgets: doubleSpinBox_pano_car_alpha,
doubleSpinBox_pano_car_beta, doubleSpinBox_pano_car_crop_left, doubleSpinBox_pano_car_crop_right,
doubleSpinBox_pano_car_crop_top, doubleSpinBox_pano_car_crop_bottom. This allows changes to
these widgets to trigger the corresponding slots.
This function is called by the GUI when the user leaves a specific tab or dialog box in the panoramic
car view.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: unblock_signal_pano_car(), "
"Unblock signal configuration Properties panorama car")
self._ui_object.doubleSpinBox_pano_car_alpha.blockSignals(False)
self._ui_object.doubleSpinBox_pano_car_beta.blockSignals(False)
self._ui_object.doubleSpinBox_pano_car_crop_left.blockSignals(False)
self._ui_object.doubleSpinBox_pano_car_crop_right.blockSignals(False)
self._ui_object.doubleSpinBox_pano_car_crop_top.blockSignals(False)
self._ui_object.doubleSpinBox_pano_car_crop_bottom.blockSignals(False)
[docs]
def showing_config_panorama_tube(self):
"""
Read the panorama configuration from a YAML file, and populates the relevant UI elements with the values.
Open the cached configuration file using the private attribute `__cached_file` as the file path, and reads its
contents using PyYAML's `safe_load` method. The relevant UI elements are then set to the corresponding values
found in the configuration file.
Note:
This function blocks signals from the UI elements while updating them with the configuration values.
Raise:
IOError: If the configuration file cannot be read.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: showing_config_panorama_tube(), "
"Update configuration Properties panorama tube")
self.block_signal_pano_tube()
self._ui_object.doubleSpinBox_pano_tube_alpha_min.setValue(self._model.main_config["Pano_tube"]["alpha_min"])
self._ui_object.doubleSpinBox_pano_tube_alpha_max.setValue(self._model.main_config["Pano_tube"]["alpha_max"])
self._ui_object.doubleSpinBox_pano_tube_crop_top.setValue(self._model.main_config["Pano_tube"]["crop_top"])
self._ui_object.doubleSpinBox_pano_tube_crop_buttom.setValue(
self._model.main_config["Pano_tube"]["crop_bottom"])
self.unblock_signal_pano_tube()
[docs]
def showing_config_panorama_car(self):
"""
Load the panorama car configuration from a cached YAML file and updates the user interface with its values.
Read the cached file at `self.__cached_file` using the PyYAML library to parse the YAML content. The parsed
configuration values are assigned to the instance variable `self.__panorama_config`. Blocks signals from all the
widgets associated with the car panorama in the user interface to prevent any unintended updates during the UI
update process. Then, sets the values of the panorama car configuration widgets in the UI with the parsed values
from the configuration file. Finally, unblocks signals from all the widgets that were previously blocked.
Return:
None
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: showing_config_panorama_car(), "
"Update configuration Properties panorama car")
self.block_signal_pano_car()
self._ui_object.spinbox_alpha_max_panorama_car.setValue(self._model.main_config["Pano_car"]["alpha_max"])
self._ui_object.doubleSpinBox_pano_car_alpha.setValue(self._model.main_config["Pano_car"]["alpha"])
self._ui_object.doubleSpinBox_pano_car_beta.setValue(self._model.main_config["Pano_car"]["beta"])
self._ui_object.doubleSpinBox_pano_car_crop_left.setValue(self._model.main_config["Pano_car"]["crop_left"])
self._ui_object.doubleSpinBox_pano_car_crop_right.setValue(self._model.main_config["Pano_car"]["crop_right"])
self._ui_object.doubleSpinBox_pano_car_crop_top.setValue(self._model.main_config["Pano_car"]["crop_top"])
self._ui_object.doubleSpinBox_pano_car_crop_bottom.setValue(self._model.main_config["Pano_car"]["crop_bottom"])
self.unblock_signal_pano_car()
[docs]
def change_properties_panorama_tube(self):
"""
Change the properties of the panorama tube.
Read the new values for alpha_min, alpha_max, crop_top, and crop_bottom from the
corresponding UI elements, and updates the __panorama_config dictionary with the new
values if they meet certain criteria. Then writes the updated dictionary to a YAML file.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: change_properties_panorama_tube(), "
"Change configuration Properties panorama tube")
alpha_min = self._ui_object.doubleSpinBox_pano_tube_alpha_min.value()
alpha_max = self._ui_object.doubleSpinBox_pano_tube_alpha_max.value()
crop_top = round(self._ui_object.doubleSpinBox_pano_tube_crop_top.value(), 3)
crop_bottom = round(self._ui_object.doubleSpinBox_pano_tube_crop_buttom.value(), 3)
if alpha_min < alpha_max - 10:
self._model.main_config["Pano_tube"]["alpha_min"] = alpha_min
if alpha_max > alpha_min + 10:
self._model.main_config["Pano_tube"]["alpha_max"] = alpha_max
if crop_top < crop_bottom - 0.2:
self._model.main_config["Pano_tube"]["crop_top"] = crop_top
if crop_bottom > crop_top + 0.2:
self._model.main_config["Pano_tube"]["crop_bottom"] = crop_bottom
self._controller.model.save_main_config_update()
[docs]
def change_properties_panorama_car(self):
"""
Update the properties of the car panorama and saves them to a YAML file.
Update the alpha and beta properties of the car panorama from the GUI spinboxes.
Update the crop_left, crop_right, crop_top, and crop_bottom properties of the car panorama from the GUI double spinboxes.
Saves the updated panorama configuration to a YAML file specified in `self.__cached_file`.
"""
if self._model.debug_mode:
self._model.activity_logger.info("PanoramaConfig: change_properties_panorama_car(), "
"Change configuration Properties panorama car")
self._model.main_config["Pano_car"]["alpha_max"] = self._ui_object.spinbox_alpha_max_panorama_car.value()
self._model.main_config["Pano_car"]["alpha"] = self._ui_object.doubleSpinBox_pano_car_alpha.value()
self._model.main_config["Pano_car"]["beta"] = self._ui_object.doubleSpinBox_pano_car_beta.value()
self._model.main_config["Pano_car"]["flip"] = True if self._ui_object.checkbox_flip.isChecked() else False
crop_left = round(self._ui_object.doubleSpinBox_pano_car_crop_left.value(), 3)
crop_right = round(self._ui_object.doubleSpinBox_pano_car_crop_right.value(), 3)
crop_top = round(self._ui_object.doubleSpinBox_pano_car_crop_top.value(), 3)
crop_bottom = round(self._ui_object.doubleSpinBox_pano_car_crop_bottom.value(), 3)
if crop_left < crop_right: # - 0.25:
self._model.main_config["Pano_car"]["crop_left"] = crop_left
if crop_right > crop_left: # + 0.25:
self._model.main_config["Pano_car"]["crop_right"] = crop_right
if crop_top < crop_bottom: # - 0.25:
self._model.main_config["Pano_car"]["crop_top"] = crop_top
if crop_bottom > crop_top: # + 0.25:
self._model.main_config["Pano_car"]["crop_bottom"] = crop_bottom
self._controller.model.save_main_config_update()
[docs]
def check_box_active_mode_panorama(self):
"""
Check and set the active mode in the Panorama view.
This method checks the active mode in the Panorama view and sets the corresponding radio button
in the user interface.
Return:
None
"""
if self._controller.model.mode_view == "PanoramaView":
self._ui_object.radioButton_car.blockSignals(True)
self._ui_object.radioButton_tube.blockSignals(True)
if self._model.main_config["Active_view"] == "car":
self._ui_object.radioButton_car.setChecked(True)
self._ui_object.radioButton_tube.setChecked(False)
elif self._model.main_config["Active_view"] == "tube":
self._ui_object.radioButton_car.setChecked(False)
self._ui_object.radioButton_tube.setChecked(True)
self._ui_object.radioButton_car.blockSignals(False)
self._ui_object.radioButton_tube.blockSignals(False)