diff --git a/arshipdesign/ui/dialogs/wizards.py b/arshipdesign/ui/dialogs/wizards.py index b81dd37..310b241 100644 --- a/arshipdesign/ui/dialogs/wizards.py +++ b/arshipdesign/ui/dialogs/wizards.py @@ -468,36 +468,84 @@ class _StepRefine(QWidget): lcb_lo.addWidget(self._lcb_val_lbl, 0, Qt.AlignmentFlag.AlignHCenter) lo.addWidget(grp_lcb) - # ── Discretización ───────────────────────────────────────────── - grp_disc = QGroupBox("Discretización") + # ── Malla de control ──────────────────────────────────────────── + grp_disc = QGroupBox("Malla de control (puntos Bézier)") grp_disc.setStyleSheet(grp_cb.styleSheet()) disc_lo = QGridLayout(grp_disc) + disc_lo.setSpacing(8) - disc_lo.addWidget(QLabel("Estaciones:"), 0, 0) + # Nota filosófica: menos puntos = curvas más fáciles de afinar + hint = QLabel( + "Menos puntos → curvas naturalmente suaves y fáciles de editar.\n" + "Añade más sólo cuando necesites detalles locales." + ) + hint.setWordWrap(True) + hint.setStyleSheet(f"color:{_MUTED}; font-size:10px; font-style:italic;") + disc_lo.addWidget(hint, 0, 0, 1, 2) + + disc_lo.addWidget(QLabel("Estaciones (long.):"), 1, 0) self._n_sta = QSpinBox() - self._n_sta.setRange(7, 81) - self._n_sta.setValue(21) - self._n_sta.setSingleStep(2) + self._n_sta.setRange(4, 30) # mínimo 4 para cúbica, máximo razonable + self._n_sta.setValue(7) # 7 = como DELFTship en plantilla nueva + self._n_sta.setSingleStep(1) + self._n_sta.setToolTip( + "Número de secciones transversales del polígono de control.\n" + "7 es suficiente para la mayoría de cascos de eslora media." + ) self._n_sta.setStyleSheet( f"background:{_PANEL}; color:{_TEXT}; border:1px solid {_BORDER};" f"border-radius:4px; padding:2px 6px;" ) - disc_lo.addWidget(self._n_sta, 0, 1) + disc_lo.addWidget(self._n_sta, 1, 1) - disc_lo.addWidget(QLabel("Líneas de agua:"), 1, 0) + disc_lo.addWidget(QLabel("Líneas de agua (vert.):"), 2, 0) self._n_wl = QSpinBox() - self._n_wl.setRange(5, 31) - self._n_wl.setValue(11) - self._n_wl.setSingleStep(2) + self._n_wl.setRange(3, 12) # 3 mínimo (quilla, media, flotación) + self._n_wl.setValue(5) # 5 = quilla + 3 intermedias + flotación + self._n_wl.setSingleStep(1) + self._n_wl.setToolTip( + "Número de líneas de agua del polígono de control.\n" + "5 da una cúbica por sección con un punto a cada 25 % del calado." + ) self._n_wl.setStyleSheet(self._n_sta.styleSheet()) - disc_lo.addWidget(self._n_wl, 1, 1) + disc_lo.addWidget(self._n_wl, 2, 1) + + # Indicador en vivo del total de nodos + self._nodes_lbl = QLabel() + self._nodes_lbl.setStyleSheet(f"color:{_ACCENT}; font-size:11px; font-weight:600;") + disc_lo.addWidget(self._nodes_lbl, 3, 0, 1, 2) + self._n_sta.valueChanged.connect(self._update_nodes_lbl) + self._n_wl.valueChanged.connect(self._update_nodes_lbl) + self._update_nodes_lbl() for lbl in grp_disc.findChildren(QLabel): - lbl.setStyleSheet(f"color:{_TEXT}; font-size:11px;") + if lbl is not hint and lbl is not self._nodes_lbl: + lbl.setStyleSheet(f"color:{_TEXT}; font-size:11px;") lo.addWidget(grp_disc) lo.addStretch() + def _update_nodes_lbl(self) -> None: + n = self._n_sta.value() + wl = self._n_wl.value() + total = n * wl + # Feedback visual: color según cantidad (verde = manejable, rojo = muchos) + if total <= 50: + color = _GREEN + advice = "✓ manejable" + elif total <= 120: + color = _GOLD + advice = "⚠ moderado" + else: + color = "#d04040" + advice = "✗ difícil de afinar" + self._nodes_lbl.setText( + f"Total nodos: {total} ({advice})" + ) + self._nodes_lbl.setStyleSheet( + f"color:{color}; font-size:11px; font-weight:600;" + ) + def _cb_changed(self, val: int) -> None: cb = val / 100.0 self._cb_val_lbl.setText(f"Cb = {cb:.2f}")