Source code for sec_interp.gui.preview_legend_renderer

from __future__ import annotations

"""Legend rendering logic for SecInterp preview.

Handles the drawing of the legend on a QPainter, including topography,
structures, and geological units.
"""

from typing import Any

from qgis.PyQt.QtCore import QCoreApplication, QRectF, Qt
from qgis.PyQt.QtGui import QColor, QFont, QPainter, QPen

from sec_interp.logger_config import get_logger

logger = get_logger(__name__)


[docs] class PreviewLegendRenderer: """Handles drawing the map legend for the profile preview."""
[docs] @staticmethod def draw_legend( painter: QPainter, rect: QRectF, active_units: dict[str, QColor], has_topography: bool = False, has_structures: bool = False, ) -> None: """Draw legend on the given painter within the rect.""" if not active_units and not has_topography and not has_structures: return # Configuration config = { "padding": 6, "item_height": 16, "symbol_size": 10, "line_width": 2, "margin": 20, } painter.save() painter.setFont(QFont("Arial", 8)) legend_size, max_text_width = PreviewLegendRenderer._calculate_legend_size( painter, active_units, has_topography, has_structures, config ) # Position: Top Right x = rect.width() - legend_size.width() - config["margin"] y = config["margin"] PreviewLegendRenderer._draw_legend_background( painter, x, y, legend_size.width(), legend_size.height() ) # Draw items current_y = y + config["padding"] if has_topography: PreviewLegendRenderer._draw_line_item( painter, x, current_y, QCoreApplication.translate("PreviewLegendRenderer", "Topography"), QColor(0, 102, 204), max_text_width, config, ) current_y += config["item_height"] if has_structures: PreviewLegendRenderer._draw_line_item( painter, x, current_y, QCoreApplication.translate("PreviewLegendRenderer", "Structures"), QColor(204, 0, 0), max_text_width, config, ) current_y += config["item_height"] PreviewLegendRenderer._draw_geology_items( painter, x, current_y, active_units, max_text_width, config ) painter.restore()
@staticmethod def _calculate_legend_size( painter: QPainter, active_units: dict[str, QColor], has_topo: bool, has_struct: bool, config: dict[str, Any], ) -> tuple[QRectF, float]: """Calculate dimensions of the legend box.""" fm = painter.fontMetrics() max_text_width = 0 items = [] if has_topo: items.append(QCoreApplication.translate("PreviewLegendRenderer", "Topography")) if has_struct: items.append(QCoreApplication.translate("PreviewLegendRenderer", "Structures")) items.extend(active_units.keys()) for item in items: max_text_width = max(max_text_width, fm.boundingRect(item).width()) width = max_text_width + config["symbol_size"] + config["padding"] * 3 height = len(items) * config["item_height"] + config["padding"] * 2 return QRectF(0, 0, width, height), max_text_width @staticmethod def _draw_legend_background( painter: QPainter, x: float, y: float, width: float, height: float ) -> None: """Draw the legend box background and border.""" rect = QRectF(x, y, width, height) painter.setBrush(QColor(255, 255, 255, 200)) painter.setPen(Qt.NoPen) painter.drawRect(rect) painter.setBrush(Qt.NoBrush) painter.setPen(QColor(100, 100, 100)) painter.drawRect(rect) @staticmethod def _draw_line_item( painter: QPainter, x: float, y: float, label: str, color: QColor, max_width: float, config: dict[str, Any], ) -> None: """Draw a legend item with a line symbol.""" p = config["padding"] ih = config["item_height"] ss = config["symbol_size"] painter.setPen(QPen(color, config["line_width"])) painter.drawLine(int(x + p), int(y + ih / 2), int(x + p + ss), int(y + ih / 2)) painter.setPen(QColor(0, 0, 0)) text_rect = QRectF(x + p * 2 + ss, y, max_width, ih) painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, label) @staticmethod def _draw_geology_items( painter: QPainter, x: float, y: float, units: dict[str, QColor], max_width: float, config: dict[str, Any], ) -> None: """Draw geological unit legend items.""" p = config["padding"] ih = config["item_height"] ss = config["symbol_size"] for name, color in units.items(): painter.setBrush(color) painter.setPen(Qt.NoPen) painter.drawRect(QRectF(x + p, y + (ih - ss) / 2, ss, ss)) painter.setPen(QColor(0, 0, 0)) text_rect = QRectF(x + p * 2 + ss, y, max_width, ih) painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, name) y += ih