diff --git a/pulse.ico b/pulse.ico index 6350a991c..378c56e6b 100644 Binary files a/pulse.ico and b/pulse.ico differ diff --git a/pulse/interface/data/icons/logos/op_dark_theme.png b/pulse/interface/data/icons/logos/op_dark_theme.png index 758134956..4e3f288b2 100644 Binary files a/pulse/interface/data/icons/logos/op_dark_theme.png and b/pulse/interface/data/icons/logos/op_dark_theme.png differ diff --git a/pulse/interface/data/icons/logos/op_light_theme.png b/pulse/interface/data/icons/logos/op_light_theme.png index f5de57a2a..65c89f030 100644 Binary files a/pulse/interface/data/icons/logos/op_light_theme.png and b/pulse/interface/data/icons/logos/op_light_theme.png differ diff --git a/pulse/interface/data/icons/pulse/pulse_icon.png b/pulse/interface/data/icons/pulse/pulse_icon.png index 39c537d99..537d72fe3 100644 Binary files a/pulse/interface/data/icons/pulse/pulse_icon.png and b/pulse/interface/data/icons/pulse/pulse_icon.png differ diff --git a/pulse/interface/others/splash_screen.py b/pulse/interface/others/splash_screen.py index 1c53b9248..c436e409a 100644 --- a/pulse/interface/others/splash_screen.py +++ b/pulse/interface/others/splash_screen.py @@ -1,5 +1,7 @@ from PySide6.QtCore import Qt +from PySide6.QtGui import QPixmap +from pulse import ICON_DIR from pulse.interface.ui_generated.project.splash_ui import Splash_UI @@ -17,16 +19,19 @@ def _config_widget(self): self.progressBar.setStyleSheet( """ QProgressBar{background-color : rgba(255, 255, 255, 0); border-radius: 6px; border-style: ridge; border-width: 0px;} QProgressBar::chunk {background-color : rgb(45, 110, 190); border-radius: 6px; border-style: ridge; border-width: 0px;} """) - + def _config_logo_label(self): - logo_text = f"""
OpenPulse
""" + logo_path = ICON_DIR / "logos/op_dark_theme.png" + pixmap = QPixmap(str(logo_path)) + + dpr = self.devicePixelRatioF() + pixmap = pixmap.scaledToWidth(int(360 * dpr), Qt.SmoothTransformation) + pixmap.setDevicePixelRatio(dpr) - self.logo_label.setText(logo_text) + self.logo_label.setPixmap(pixmap) - def update_position(self, app): - desktop_geometry = app.primaryScreen().geometry() + def update_position(self, qt_app): + desktop_geometry = qt_app.primaryScreen().geometry() pos_x = int((desktop_geometry.width() - self.width())/2) pos_y = int((desktop_geometry.height() - self.height())/2) self.setGeometry(pos_x, pos_y, self.width(), self.height()) diff --git a/pulse/interface/viewer_3d/render_widgets/geometry_render_widget.py b/pulse/interface/viewer_3d/render_widgets/geometry_render_widget.py index e8f739993..9772ee472 100644 --- a/pulse/interface/viewer_3d/render_widgets/geometry_render_widget.py +++ b/pulse/interface/viewer_3d/render_widgets/geometry_render_widget.py @@ -46,6 +46,7 @@ def _create_connections(self): self.left_clicked.connect(self.click_callback) self.left_released.connect(self.selection_callback) app().main_window.theme_changed.connect(self.set_theme) + app().main_window.theme_changed.connect(self._apply_logo_theme) app().main_window.visualization_changed.connect(self.visualization_changed_callback) def update_plot(self, reset_camera=True): @@ -130,32 +131,75 @@ def update_open_pulse_logo_visibility(self): def create_logos(self): if not hasattr(self, "_light_logo"): self._light_logo = self.create_logo(ICON_DIR / "logos/op_light_theme.png") - self._light_logo.SetPosition(0.845, 0.89) - self._light_logo.SetPosition2(0.15, 0.15) + self._light_logo.SetShowBorderToOff() + self._light_logo.SetShowPolygonBackground(0) if not hasattr(self, "_dark_logo"): self._dark_logo = self.create_logo(ICON_DIR / "logos/op_dark_theme.png") - self._dark_logo.SetPosition(0.845, 0.89) - self._dark_logo.SetPosition2(0.15, 0.15) + self._dark_logo.SetShowBorderToOff() + self._dark_logo.SetShowPolygonBackground(0) + + if getattr(self, "_logo_observer_id", None) is None: + self._logo_last_size = None + self._logo_observer_id = self.renderer.AddObserver("StartEvent", self._logo_size_callback) self._apply_logo_theme() + self.update_logo_geometry() - def _apply_logo_theme(self): - if app().main_window.config.user_preferences.interface_theme == "light": - self._light_logo.VisibilityOn() - self._dark_logo.VisibilityOff() - self.open_pulse_logo = self._light_logo - else: - self._dark_logo.VisibilityOn() - self._light_logo.VisibilityOff() - self.open_pulse_logo = self._dark_logo + def _logo_size_callback(self, *args, **kwargs): + + size = tuple(self.renderer.GetSize()) + if size != self._logo_last_size: + self._logo_last_size = size + self.update_logo_geometry() + + def update_logo_geometry(self): + width_fraction = 0.15 + min_width = 90 + max_width = 240 + max_height_ratio = 0.12 + margin = 10 + + width, height = self.renderer.GetSize() + if width < 2 or height < 2: + return + + for logo in (self._light_logo, self._dark_logo): + image = logo.GetImage() + if image is None: + continue + + image_width, image_height, _ = image.GetDimensions() + if image_width < 1 or image_height < 1: + continue + + aspect = image_width / image_height + logo_width = max(width_fraction * width, min_width) + logo_width = min(logo_width, max_width, 0.4 * width, max_height_ratio * height * aspect) + logo_height = logo_width / aspect + + box_x = logo_width / width + box_y = logo_height / height + + logo.SetPosition(1 - box_x - margin / width, 1 - box_y - margin / height) + logo.SetPosition2(box_x, box_y) + logo.Modified() + + def _apply_logo_theme(self, *args, **kwargs): + light_theme = app().main_window.config.user_preferences.interface_theme == "light" + logo_visible = getattr(self, "_logo_visible", True) + + self.open_pulse_logo = self._light_logo if light_theme else self._dark_logo + self._light_logo.SetVisibility(light_theme and logo_visible) + self._dark_logo.SetVisibility(not light_theme and logo_visible) def enable_open_pulse_logo(self): - return - # self.open_pulse_logo.VisibilityOn() + self._logo_visible = True + self._apply_logo_theme() def disable_open_pulse_logo(self): - self.open_pulse_logo.VisibilityOff() + self._logo_visible = False + self._apply_logo_theme() def visualization_changed_callback(self): if not self._actor_exists(): @@ -311,4 +355,4 @@ def update_selection(self): def set_default_render_tool(self): tool = SelectionTool() self.set_interactor_style(tool) - tool.update_mouse_cursor_in_render_widgets(tool.current_cursor) + tool.update_mouse_cursor_in_render_widgets(tool.current_cursor) \ No newline at end of file diff --git a/pulse/interface/viewer_3d/render_widgets/mesh_render_widget.py b/pulse/interface/viewer_3d/render_widgets/mesh_render_widget.py index 065207f60..00fb74004 100644 --- a/pulse/interface/viewer_3d/render_widgets/mesh_render_widget.py +++ b/pulse/interface/viewer_3d/render_widgets/mesh_render_widget.py @@ -195,25 +195,74 @@ def update_theme(self): def create_logos(self): if not hasattr(self, "_light_logo"): self._light_logo = self.create_logo(ICON_DIR / "logos/op_light_theme.png") - self._light_logo.SetPosition(0.845, 0.89) - self._light_logo.SetPosition2(0.15, 0.15) + self._light_logo.SetShowBorderToOff() + self._light_logo.SetShowPolygonBackground(0) if not hasattr(self, "_dark_logo"): self._dark_logo = self.create_logo(ICON_DIR / "logos/op_dark_theme.png") - self._dark_logo.SetPosition(0.845, 0.89) - self._dark_logo.SetPosition2(0.15, 0.15) + self._dark_logo.SetShowBorderToOff() + self._dark_logo.SetShowPolygonBackground(0) + + if getattr(self, "_logo_observer_id", None) is None: + self._logo_last_size = None + self._logo_observer_id = self.renderer.AddObserver("StartEvent", self._logo_size_callback) self._apply_logo_theme() + self.update_logo_geometry() + + def _logo_size_callback(self, *args, **kwargs): + size = tuple(self.renderer.GetSize()) + if size != self._logo_last_size: + self._logo_last_size = size + self.update_logo_geometry() + + def update_logo_geometry(self): + width_fraction = 0.15 + min_width = 90 + max_width = 240 + max_height_ratio = 0.12 + margin = 10 + + width, height = self.renderer.GetSize() + if width < 2 or height < 2: + return - def _apply_logo_theme(self): - if app().main_window.config.user_preferences.interface_theme == "light": - self._light_logo.VisibilityOn() - self._dark_logo.VisibilityOff() - self.open_pulse_logo = self._light_logo - else: - self._dark_logo.VisibilityOn() - self._light_logo.VisibilityOff() - self.open_pulse_logo = self._dark_logo + for logo in (self._light_logo, self._dark_logo): + image = logo.GetImage() + if image is None: + continue + + image_width, image_height, _ = image.GetDimensions() + if image_width < 1 or image_height < 1: + continue + + aspect = image_width / image_height + logo_width = max(width_fraction * width, min_width) + logo_width = min(logo_width, max_width, 0.4 * width, max_height_ratio * height * aspect) + logo_height = logo_width / aspect + + box_x = logo_width / width + box_y = logo_height / height + + logo.SetPosition(1 - box_x - margin / width, 1 - box_y - margin / height) + logo.SetPosition2(box_x, box_y) + logo.Modified() + + def _apply_logo_theme(self, *args, **kwargs): + light_theme = app().main_window.config.user_preferences.interface_theme == "light" + logo_visible = getattr(self, "_logo_visible", True) + + self.open_pulse_logo = self._light_logo if light_theme else self._dark_logo + self._light_logo.SetVisibility(light_theme and logo_visible) + self._dark_logo.SetVisibility(not light_theme and logo_visible) + + def enable_open_pulse_logo(self): + self._logo_visible = True + self._apply_logo_theme() + + def disable_open_pulse_logo(self): + self._logo_visible = False + self._apply_logo_theme() def save_thumbnail(self): thumbnail = app().project.thumbnail @@ -267,12 +316,6 @@ def update_open_pulse_logo_visibility(self): else: self.disable_open_pulse_logo() - def enable_open_pulse_logo(self): - self.open_pulse_logo.VisibilityOn() - - def disable_open_pulse_logo(self): - self.open_pulse_logo.VisibilityOff() - def update_scale_bar_visibility(self): user_preferences = app().config.user_preferences @@ -435,4 +478,4 @@ def _apply_section_plane(self, position, rotation, inverted, show_plane=True): def set_default_render_tool(self): tool = SelectionTool() self.set_interactor_style(tool) - tool.update_mouse_cursor_in_render_widgets(tool.current_cursor) + tool.update_mouse_cursor_in_render_widgets(tool.current_cursor) \ No newline at end of file diff --git a/pulse/interface/viewer_3d/render_widgets/results_render_widget.py b/pulse/interface/viewer_3d/render_widgets/results_render_widget.py index 49ec8f5eb..a0a293e85 100644 --- a/pulse/interface/viewer_3d/render_widgets/results_render_widget.py +++ b/pulse/interface/viewer_3d/render_widgets/results_render_widget.py @@ -392,25 +392,74 @@ def update_theme(self): def create_logos(self): if not hasattr(self, "_light_logo"): self._light_logo = self.create_logo(ICON_DIR / "logos/op_light_theme.png") - self._light_logo.SetPosition(0.845, 0.89) - self._light_logo.SetPosition2(0.15, 0.15) + self._light_logo.SetShowBorderToOff() + self._light_logo.SetShowPolygonBackground(0) if not hasattr(self, "_dark_logo"): self._dark_logo = self.create_logo(ICON_DIR / "logos/op_dark_theme.png") - self._dark_logo.SetPosition(0.845, 0.89) - self._dark_logo.SetPosition2(0.15, 0.15) + self._dark_logo.SetShowBorderToOff() + self._dark_logo.SetShowPolygonBackground(0) + + if getattr(self, "_logo_observer_id", None) is None: + self._logo_last_size = None + self._logo_observer_id = self.renderer.AddObserver("StartEvent", self._logo_size_callback) self._apply_logo_theme() + self.update_logo_geometry() + + def _logo_size_callback(self, *args, **kwargs): + size = tuple(self.renderer.GetSize()) + if size != self._logo_last_size: + self._logo_last_size = size + self.update_logo_geometry() + + def update_logo_geometry(self): + width_fraction = 0.15 + min_width = 90 + max_width = 240 + max_height_ratio = 0.12 + margin = 10 + + width, height = self.renderer.GetSize() + if width < 2 or height < 2: + return - def _apply_logo_theme(self): - if app().main_window.config.user_preferences.interface_theme == "light": - self._light_logo.VisibilityOn() - self._dark_logo.VisibilityOff() - self.open_pulse_logo = self._light_logo - else: - self._dark_logo.VisibilityOn() - self._light_logo.VisibilityOff() - self.open_pulse_logo = self._dark_logo + for logo in (self._light_logo, self._dark_logo): + image = logo.GetImage() + if image is None: + continue + + image_width, image_height, _ = image.GetDimensions() + if image_width < 1 or image_height < 1: + continue + + aspect = image_width / image_height + logo_width = max(width_fraction * width, min_width) + logo_width = min(logo_width, max_width, 0.4 * width, max_height_ratio * height * aspect) + logo_height = logo_width / aspect + + box_x = logo_width / width + box_y = logo_height / height + + logo.SetPosition(1 - box_x - margin / width, 1 - box_y - margin / height) + logo.SetPosition2(box_x, box_y) + logo.Modified() + + def _apply_logo_theme(self, *args, **kwargs): + light_theme = app().main_window.config.user_preferences.interface_theme == "light" + logo_visible = getattr(self, "_logo_visible", True) + + self.open_pulse_logo = self._light_logo if light_theme else self._dark_logo + self._light_logo.SetVisibility(light_theme and logo_visible) + self._dark_logo.SetVisibility(not light_theme and logo_visible) + + def enable_open_pulse_logo(self): + self._logo_visible = True + self._apply_logo_theme() + + def disable_open_pulse_logo(self): + self._logo_visible = False + self._apply_logo_theme() def apply_user_preferences(self): self.update_open_pulse_logo_visibility() @@ -437,12 +486,6 @@ def update_open_pulse_logo_visibility(self): else: self.disable_open_pulse_logo() - def enable_open_pulse_logo(self): - self.open_pulse_logo.VisibilityOn() - - def disable_open_pulse_logo(self): - self.open_pulse_logo.VisibilityOff() - def update_scale_bar_visibility(self): user_preferences = app().config.user_preferences @@ -732,4 +775,4 @@ def update_render_tool_according_to_results_viewer_widget(self, has_selection=Tr def set_default_render_tool(self, base_tool=False): tool = RenderTool() self.set_interactor_style(tool) - tool.update_mouse_cursor_in_render_widgets(tool.current_cursor) + tool.update_mouse_cursor_in_render_widgets(tool.current_cursor) \ No newline at end of file diff --git a/pulse/interface/welcome_widget.py b/pulse/interface/welcome_widget.py index ae40b4354..cdc017271 100644 --- a/pulse/interface/welcome_widget.py +++ b/pulse/interface/welcome_widget.py @@ -10,7 +10,6 @@ from functools import partial from pathlib import Path -from PIL import Image class WelcomeWidget(QWidget): @@ -20,23 +19,19 @@ def __init__(self): self.main_window = app().main_window self.widget_layout = QVBoxLayout(self) self.setLayout(self.widget_layout) - self.define_logo_variables() + self.load_logo_pixmaps() self.setup_image(self.widget_layout) + self.update_logo() self.setup_labels(self.widget_layout) self.create_recents_setup() self.update_recent_projects() self.setup_example_projects(self.widget_layout) - self.main_window.theme_changed.connect(self.update_logo_text) + self.main_window.theme_changed.connect(self.update_logo) - def define_logo_variables(self): - self.light_logo_text = """OpenPulse
""" - - self.dark_logo_text = """OpenPulse
""" + def load_logo_pixmaps(self): + self.light_logo_pixmap = QPixmap(str(ICON_DIR / "logos/op_light_theme.png")) + self.dark_logo_pixmap = QPixmap(str(ICON_DIR / "logos/op_dark_theme.png")) def setup_image(self, layout: QVBoxLayout): self.logo_label = QLabel(self) @@ -47,11 +42,17 @@ def setup_image(self, layout: QVBoxLayout): layout.addWidget(self.logo_label) layout.addStretch() - def update_logo_text(self): + def update_logo(self): if app().config.user_preferences.interface_theme == "dark": - self.logo_label.setText(self.dark_logo_text) + pixmap = self.dark_logo_pixmap else: - self.logo_label.setText(self.light_logo_text) + pixmap = self.light_logo_pixmap + + dpr = self.devicePixelRatioF() + pixmap = pixmap.scaledToWidth(int(420 * dpr), Qt.SmoothTransformation) + pixmap.setDevicePixelRatio(dpr) + + self.logo_label.setPixmap(pixmap) def setup_labels(self, layout): labels_layout = QHBoxLayout() @@ -217,7 +218,4 @@ def shorten_text(self, text: str, max_width: int, font): subtext = text[:i] + "..." if draw.textlength(subtext, font) <= max_width: - return subtext - - - + return subtext \ No newline at end of file