Fenster: Rahmen-Kontur in Aufsicht separat von den geschnittenen Laibungsblöcken stylebar
Bisher teilten sich die geschnittenen Laibungs-/Stulp-Blöcke (O-Blöcke, Schnittfläche des Rahmenmaterials) und die durchlaufende Rahmen-Kontur zwischen ihnen (Aufsicht, nicht geschnitten) dieselbe frameLine-Farbe. Neues Opening.frameViewLine übersteuert nur noch die Kontur; ohne Angabe fällt sie weiterhin auf frameLine zurück (bisheriges Verhalten unverändert). frameLine im UI zu "Rahmen (Schnitt)" umbenannt, um die beiden Kategorien zu unterscheiden.
This commit is contained in:
@@ -3374,6 +3374,9 @@ export default function App() {
|
|||||||
onSetOpeningFrameLine: (v) => {
|
onSetOpeningFrameLine: (v) => {
|
||||||
if (selection?.kind === "opening") updateOpening(selection.id, { frameLine: v });
|
if (selection?.kind === "opening") updateOpening(selection.id, { frameLine: v });
|
||||||
},
|
},
|
||||||
|
onSetOpeningFrameViewLine: (v) => {
|
||||||
|
if (selection?.kind === "opening") updateOpening(selection.id, { frameViewLine: v });
|
||||||
|
},
|
||||||
onSetOpeningSashLine: (v) => {
|
onSetOpeningSashLine: (v) => {
|
||||||
if (selection?.kind === "opening") updateOpening(selection.id, { sashLine: v });
|
if (selection?.kind === "opening") updateOpening(selection.id, { sashLine: v });
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-1
@@ -482,7 +482,8 @@ export const de = {
|
|||||||
"objinfo.opening.lintelLines.innen": "Innen",
|
"objinfo.opening.lintelLines.innen": "Innen",
|
||||||
"objinfo.opening.lintelLines.aussen": "Außen",
|
"objinfo.opening.lintelLines.aussen": "Außen",
|
||||||
"objinfo.opening.lintelLines.beide": "Beide",
|
"objinfo.opening.lintelLines.beide": "Beide",
|
||||||
"objinfo.opening.frameLine": "Rahmen",
|
"objinfo.opening.frameLine": "Rahmen (Schnitt)",
|
||||||
|
"objinfo.opening.frameViewLine": "Rahmen (Aufsicht)",
|
||||||
"objinfo.opening.sashLine": "Fenster (Flügel/Sprossen)",
|
"objinfo.opening.sashLine": "Fenster (Flügel/Sprossen)",
|
||||||
"objinfo.opening.sillLine": "Sims",
|
"objinfo.opening.sillLine": "Sims",
|
||||||
"objinfo.lineWeight": "Strichstärke (mm)",
|
"objinfo.lineWeight": "Strichstärke (mm)",
|
||||||
|
|||||||
+2
-1
@@ -481,7 +481,8 @@ export const en: Record<TranslationKey, string> = {
|
|||||||
"objinfo.opening.lintelLines.innen": "Inside",
|
"objinfo.opening.lintelLines.innen": "Inside",
|
||||||
"objinfo.opening.lintelLines.aussen": "Outside",
|
"objinfo.opening.lintelLines.aussen": "Outside",
|
||||||
"objinfo.opening.lintelLines.beide": "Both",
|
"objinfo.opening.lintelLines.beide": "Both",
|
||||||
"objinfo.opening.frameLine": "Frame",
|
"objinfo.opening.frameLine": "Frame (cut)",
|
||||||
|
"objinfo.opening.frameViewLine": "Frame (view)",
|
||||||
"objinfo.opening.sashLine": "Window (sash/muntins)",
|
"objinfo.opening.sashLine": "Window (sash/muntins)",
|
||||||
"objinfo.opening.sillLine": "Sill",
|
"objinfo.opening.sillLine": "Sill",
|
||||||
"objinfo.lineWeight": "Line weight (mm)",
|
"objinfo.lineWeight": "Line weight (mm)",
|
||||||
|
|||||||
+15
-3
@@ -1219,11 +1219,23 @@ export interface Opening {
|
|||||||
*/
|
*/
|
||||||
color?: string;
|
color?: string;
|
||||||
/**
|
/**
|
||||||
* Nur Fenster, Grundriss: Übersteuerung von Farbe/Strichstärke des
|
* Nur Fenster, Grundriss: Übersteuerung von Farbe/Strichstärke der
|
||||||
* Blendrahmens + Stulp-/Laibungsblöcke ({@link LineStyleOverride}).
|
* GESCHNITTENEN Blendrahmen-Querschnittsblöcke an den Laibungs-Enden
|
||||||
* `undefined` ⇒ {@link Opening.color}, sonst Kategorie-Farbe/Haarlinie.
|
* ({@link LineStyleOverride}, entspricht `windowSymbol.jambMarks` — die
|
||||||
|
* Schnittfläche des Rahmenmaterials an der Wand-Laibung). `undefined` ⇒
|
||||||
|
* {@link Opening.color}, sonst Kategorie-Farbe/Haarlinie. Separat von
|
||||||
|
* {@link frameViewLine} (die durchlaufende Rahmen-Kontur in Aufsicht).
|
||||||
*/
|
*/
|
||||||
frameLine?: LineStyleOverride;
|
frameLine?: LineStyleOverride;
|
||||||
|
/**
|
||||||
|
* Nur Fenster, Grundriss: Übersteuerung von Farbe/Strichstärke der
|
||||||
|
* durchlaufenden Blendrahmen-KONTUR in Aufsicht (das Rechteck aus
|
||||||
|
* `windowSymbol.frame` — die beiden Linien zwischen den geschnittenen
|
||||||
|
* Laibungs-/Stulp-Blöcken, NICHT geschnitten, sondern von oben/unten
|
||||||
|
* projiziert). `undefined` ⇒ fällt auf {@link frameLine} zurück (bisheriges
|
||||||
|
* Verhalten: eine gemeinsame Farbe/Stärke für Schnitt UND Aufsicht).
|
||||||
|
*/
|
||||||
|
frameViewLine?: LineStyleOverride;
|
||||||
/**
|
/**
|
||||||
* Nur Fenster, Grundriss: Übersteuerung von Farbe/Strichstärke des
|
* Nur Fenster, Grundriss: Übersteuerung von Farbe/Strichstärke des
|
||||||
* Flügelrahmens/der Sprossen (window-sash/window-mullion).
|
* Flügelrahmens/der Sprossen (window-sash/window-mullion).
|
||||||
|
|||||||
@@ -1002,6 +1002,13 @@ export function OpeningSection({
|
|||||||
fallbackWeight={OPENING_LINE_DEFAULT_WEIGHT}
|
fallbackWeight={OPENING_LINE_DEFAULT_WEIGHT}
|
||||||
onChange={host.onSetOpeningFrameLine}
|
onChange={host.onSetOpeningFrameLine}
|
||||||
/>
|
/>
|
||||||
|
<LineStyleRow
|
||||||
|
label={t("objinfo.opening.frameViewLine")}
|
||||||
|
value={opening.frameViewLine}
|
||||||
|
fallbackColor={opening.frameLine?.color ?? OPENING_LINE_DEFAULT_COLOR}
|
||||||
|
fallbackWeight={opening.frameLine?.weight ?? OPENING_LINE_DEFAULT_WEIGHT}
|
||||||
|
onChange={host.onSetOpeningFrameViewLine}
|
||||||
|
/>
|
||||||
<LineStyleRow
|
<LineStyleRow
|
||||||
label={t("objinfo.opening.sashLine")}
|
label={t("objinfo.opening.sashLine")}
|
||||||
value={opening.sashLine}
|
value={opening.sashLine}
|
||||||
|
|||||||
+3
-1
@@ -311,8 +311,10 @@ export interface PanelHostValue {
|
|||||||
onSetOpeningDoorType: (doorType: "normal" | "wandoeffnung") => void;
|
onSetOpeningDoorType: (doorType: "normal" | "wandoeffnung") => void;
|
||||||
/** Setzt die Sturzlinien-Darstellung der Tür. */
|
/** Setzt die Sturzlinien-Darstellung der Tür. */
|
||||||
onSetOpeningLintelLines: (lintelLines: "keine" | "innen" | "aussen" | "beide") => void;
|
onSetOpeningLintelLines: (lintelLines: "keine" | "innen" | "aussen" | "beide") => void;
|
||||||
/** Übersteuert Farbe/Strichstärke des Blendrahmens + Stulp-/Laibungsblöcke. */
|
/** Übersteuert Farbe/Strichstärke der geschnittenen Laibungs-/Stulp-Blöcke. */
|
||||||
onSetOpeningFrameLine: (v: { color?: string; weight?: number } | undefined) => void;
|
onSetOpeningFrameLine: (v: { color?: string; weight?: number } | undefined) => void;
|
||||||
|
/** Übersteuert Farbe/Strichstärke der durchlaufenden Rahmen-Kontur in Aufsicht. */
|
||||||
|
onSetOpeningFrameViewLine: (v: { color?: string; weight?: number } | undefined) => void;
|
||||||
/** Übersteuert Farbe/Strichstärke von Flügelrahmen/Sprossen. */
|
/** Übersteuert Farbe/Strichstärke von Flügelrahmen/Sprossen. */
|
||||||
onSetOpeningSashLine: (v: { color?: string; weight?: number } | undefined) => void;
|
onSetOpeningSashLine: (v: { color?: string; weight?: number } | undefined) => void;
|
||||||
/** Übersteuert Farbe/Strichstärke der Auf-/Untersicht-Andeutung (Sims). */
|
/** Übersteuert Farbe/Strichstärke der Auf-/Untersicht-Andeutung (Sims). */
|
||||||
|
|||||||
@@ -2281,23 +2281,29 @@ function addOpeningSymbol(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Linien-Kategorien einzeln übersteuerbar (Nutzer-Wunsch): Rahmen (Blend-
|
// Linien-Kategorien einzeln übersteuerbar (Nutzer-Wunsch): Rahmen-Schnitt
|
||||||
// rahmen-Kontur + Stulp-/Laibungsblöcke), Fenster (Flügelrahmen/Sprossen),
|
// (Laibungs-/Stulp-Blöcke, geschnittenes Profil), Rahmen-Aufsicht (die
|
||||||
// Sims (Auf-/Untersicht-Andeutung, s. u.). `undefined` ⇒ bisheriges
|
// durchlaufende Kontur DAZWISCHEN, projiziert statt geschnitten), Fenster
|
||||||
// Verhalten (strokeColor/SYMBOL_HAIRLINE_MM).
|
// (Flügelrahmen/Sprossen), Sims (Auf-/Untersicht-Andeutung, s. u.).
|
||||||
|
// `undefined` ⇒ bisheriges Verhalten (strokeColor/SYMBOL_HAIRLINE_MM);
|
||||||
|
// `frameViewLine` fällt zusätzlich auf `frameLine` zurück (eine Farbe für
|
||||||
|
// Schnitt+Aufsicht, bis der Nutzer sie explizit trennt).
|
||||||
const frameColor = o.frameLine?.color ?? strokeColor;
|
const frameColor = o.frameLine?.color ?? strokeColor;
|
||||||
const frameWeight = o.frameLine?.weight ?? lwMm;
|
const frameWeight = o.frameLine?.weight ?? lwMm;
|
||||||
const frameHairline = o.frameLine?.weight ?? SYMBOL_HAIRLINE_MM;
|
const frameHairline = o.frameLine?.weight ?? SYMBOL_HAIRLINE_MM;
|
||||||
|
const frameViewColor = o.frameViewLine?.color ?? frameColor;
|
||||||
|
const frameViewWeight = o.frameViewLine?.weight ?? frameWeight;
|
||||||
const sashColor = o.sashLine?.color ?? strokeColor;
|
const sashColor = o.sashLine?.color ?? strokeColor;
|
||||||
const sashWeight = o.sashLine?.weight ?? SYMBOL_HAIRLINE_MM;
|
const sashWeight = o.sashLine?.weight ?? SYMBOL_HAIRLINE_MM;
|
||||||
|
|
||||||
// Blendrahmen-Rechteck (mittel + fein).
|
// Blendrahmen-Rechteck in Aufsicht (mittel + fein) — die durchlaufende
|
||||||
|
// Kontur zwischen den geschnittenen Laibungs-/Stulp-Blöcken.
|
||||||
out.push({
|
out.push({
|
||||||
kind: "polygon",
|
kind: "polygon",
|
||||||
pts: sym.frame,
|
pts: sym.frame,
|
||||||
fill: "none",
|
fill: "none",
|
||||||
stroke: frameColor,
|
stroke: frameViewColor,
|
||||||
strokeWidthMm: frameWeight,
|
strokeWidthMm: frameViewWeight,
|
||||||
hatch: NO_HATCH,
|
hatch: NO_HATCH,
|
||||||
greyed,
|
greyed,
|
||||||
openingId: o.id,
|
openingId: o.id,
|
||||||
|
|||||||
@@ -390,6 +390,42 @@ describe("generatePlan — Linien-Übersteuerung je Kategorie (Opening.frameLine
|
|||||||
expect(sill[0].kind === "line" && sill[0].weightMm).toBeCloseTo(0.4, 6);
|
expect(sill[0].kind === "line" && sill[0].weightMm).toBeCloseTo(0.4, 6);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("frameViewLine ohne Übersteuerung: die Rahmen-Kontur (Aufsicht) fällt auf frameLine zurück", () => {
|
||||||
|
const p = project(
|
||||||
|
{ ...baseWindow, typeId: "wt1", frameLine: { color: "#ff0000", weight: 0.5 } },
|
||||||
|
[baseWindowType],
|
||||||
|
);
|
||||||
|
const frame = generatePlan(p, "eg", visible, undefined, "mittel").primitives.find(
|
||||||
|
(pr) => pr.kind === "polygon" && pr.openingId === "F1" && pr.stroke !== "none",
|
||||||
|
);
|
||||||
|
expect(frame).toBeDefined();
|
||||||
|
expect(frame!.kind === "polygon" && frame!.stroke).toBe("#ff0000");
|
||||||
|
expect(frame!.kind === "polygon" && frame!.strokeWidthMm).toBeCloseTo(0.5, 6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("frameViewLine übersteuert NUR die Rahmen-Kontur (Aufsicht) — die Laibungs-Blöcke (Schnitt) bleiben beim frameLine-Default", () => {
|
||||||
|
const p = project(
|
||||||
|
{
|
||||||
|
...baseWindow,
|
||||||
|
typeId: "wt1",
|
||||||
|
frameLine: { color: "#ff0000", weight: 0.5 },
|
||||||
|
frameViewLine: { color: "#00ffff", weight: 0.2 },
|
||||||
|
},
|
||||||
|
[baseWindowType],
|
||||||
|
);
|
||||||
|
const out = generatePlan(p, "eg", visible, undefined, "mittel").primitives;
|
||||||
|
const frame = out.find((pr) => pr.kind === "polygon" && pr.openingId === "F1" && pr.stroke !== "none");
|
||||||
|
expect(frame!.kind === "polygon" && frame!.stroke).toBe("#00ffff");
|
||||||
|
expect(frame!.kind === "polygon" && frame!.strokeWidthMm).toBeCloseTo(0.2, 6);
|
||||||
|
// Laibungs-Blöcke (window-stulp) bleiben unverändert bei frameLine, NICHT frameViewLine.
|
||||||
|
const stulp = out.filter((pr) => pr.kind === "line" && pr.cls === "window-stulp");
|
||||||
|
expect(stulp.length).toBeGreaterThan(0);
|
||||||
|
for (const l of stulp) {
|
||||||
|
expect(l.kind === "line" && l.color).toBe("#ff0000");
|
||||||
|
expect(l.kind === "line" && l.weightMm).toBeCloseTo(0.5, 6);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("sashLine wirkt auch bei 'grob' (1:100) auf die einzige dort sichtbare Glaslinie", () => {
|
it("sashLine wirkt auch bei 'grob' (1:100) auf die einzige dort sichtbare Glaslinie", () => {
|
||||||
const p = project(
|
const p = project(
|
||||||
{ ...baseWindow, typeId: "wt1", sashLine: { color: "#00ff00", weight: 0.3 } },
|
{ ...baseWindow, typeId: "wt1", sashLine: { color: "#00ff00", weight: 0.3 } },
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ export interface OpeningInfo {
|
|||||||
zTop: number;
|
zTop: number;
|
||||||
/** Nur Fenster: Grundriss-Linien-Übersteuerungen je Kategorie. */
|
/** Nur Fenster: Grundriss-Linien-Übersteuerungen je Kategorie. */
|
||||||
frameLine?: { color?: string; weight?: number };
|
frameLine?: { color?: string; weight?: number };
|
||||||
|
frameViewLine?: { color?: string; weight?: number };
|
||||||
sashLine?: { color?: string; weight?: number };
|
sashLine?: { color?: string; weight?: number };
|
||||||
sillLineStyle?: { color?: string; weight?: number };
|
sillLineStyle?: { color?: string; weight?: number };
|
||||||
}
|
}
|
||||||
@@ -728,6 +729,7 @@ function openingSelection(project: Project, o: Opening): Selection {
|
|||||||
zBottom: ext.zBottom,
|
zBottom: ext.zBottom,
|
||||||
zTop: ext.zTop,
|
zTop: ext.zTop,
|
||||||
frameLine: o.frameLine,
|
frameLine: o.frameLine,
|
||||||
|
frameViewLine: o.frameViewLine,
|
||||||
sashLine: o.sashLine,
|
sashLine: o.sashLine,
|
||||||
sillLineStyle: o.sillLineStyle,
|
sillLineStyle: o.sillLineStyle,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user