feat(styles): overhaul style managers
Unify editor layouts, live previews, comparisons, read-only behavior, and localized controls across all named style managers. Refs #629
This commit is contained in:
parent
d06a1022f2
commit
25515fa33c
27 changed files with 5480 additions and 1636 deletions
|
|
@ -3193,3 +3193,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── __ocs_arg_MOD__-Tastenkürzel ──
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── Benutzerdefinierte Überschreibungen (SHORTCUTS SET)
|
||||
catalog-function-keys-b5a2df24e9 = ── Funktionstasten ────────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── Weitere Tasten ─────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = Text immer zwischen Hilfslinien halten
|
||||
dimstyle-angular-dimensions = Winkelbemaßungen
|
||||
dimstyle-arc-length-symbol = Bogenlängensymbol
|
||||
dimstyle-arrowheads = Pfeilspitzen
|
||||
dimstyle-available-style = Verfügbarer Stil
|
||||
dimstyle-baseline-spacing = Basislinienabstand
|
||||
dimstyle-basic = Theoretisch genau
|
||||
dimstyle-both-arrowheads = Beide Pfeilspitzen
|
||||
dimstyle-center-mark = Mittelpunktmarkierung
|
||||
dimstyle-center-mark-size = Größe der Mittelpunktmarkierung
|
||||
dimstyle-center-marks = Mittelpunktmarkierungen
|
||||
dimstyle-centerlines = Mittellinien
|
||||
dimstyle-compare-with = Vergleichen mit
|
||||
dimstyle-current-style = Aktueller Stil
|
||||
dimstyle-deviation = Abweichung
|
||||
dimstyle-different-sections = Abweichende Bereiche
|
||||
dimstyle-dimension-line-color = Maßlinienfarbe
|
||||
dimstyle-dimension-linetype = Maßlinientyp
|
||||
dimstyle-dimension-lineweight = Maßlinienstärke
|
||||
dimstyle-display-alternate-units = Alternative Einheiten anzeigen
|
||||
dimstyle-draw-dimension-line-between-extension-lines = Maßlinie zwischen Hilfslinien zeichnen
|
||||
dimstyle-extend-beyond-dimension-line = Über Maßlinie hinaus verlängern
|
||||
dimstyle-extend-beyond-ticks = Über Schrägstriche hinaus verlängern
|
||||
dimstyle-extension-line-color = Hilfslinienfarbe
|
||||
dimstyle-extension-lineweight = Hilfslinienstärke
|
||||
dimstyle-feet-and-inches = Fuß und Zoll
|
||||
dimstyle-fine-tuning = Feinabstimmung
|
||||
dimstyle-first-arrowhead = Erste Pfeilspitze
|
||||
dimstyle-first-extension-linetype = Linientyp der ersten Hilfslinie
|
||||
dimstyle-fit-options = Einpassungsoptionen
|
||||
dimstyle-fixed-length = Feste Länge
|
||||
dimstyle-fraction-format = Bruchformat
|
||||
dimstyle-height-scale = Höhenskalierung
|
||||
dimstyle-horizontal-placement = Horizontale Platzierung
|
||||
dimstyle-keep-text-horizontal-inside = Text innen horizontal halten
|
||||
dimstyle-keep-text-horizontal-outside = Text außen horizontal halten
|
||||
dimstyle-leader-arrowhead = Führungslinien-Pfeilspitze
|
||||
dimstyle-limits = Grenzmaße
|
||||
dimstyle-linear-dimensions = Lineare Bemaßungen
|
||||
dimstyle-lower-value = Unterer Wert
|
||||
dimstyle-measurement-scale = Maßstab der Messwerte
|
||||
dimstyle-measurement-template = Messwertvorlage
|
||||
dimstyle-method = Methode
|
||||
dimstyle-multiplier = Multiplikator
|
||||
dimstyle-no-differences = Keine Unterschiede
|
||||
dimstyle-not-applicable = Nicht zutreffend
|
||||
dimstyle-offset-from-measured-point = Abstand vom gemessenen Punkt
|
||||
dimstyle-place-text-manually = Text beim Erstellen der Bemaßung manuell platzieren
|
||||
dimstyle-radius-jog-angle = Winkel des Radiusknicks (°)
|
||||
dimstyle-read-left-to-right = Von links nach rechts lesen
|
||||
dimstyle-referenced-read-only = Referenzierter Stil · Schreibgeschützt
|
||||
dimstyle-round-off = Rundung
|
||||
dimstyle-second-arrowhead = Zweite Pfeilspitze
|
||||
dimstyle-second-extension-linetype = Linientyp der zweiten Hilfslinie
|
||||
dimstyle-show-zero-feet-and-inches = Null Fuß und null Zoll anzeigen
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = Null Fuß anzeigen; null Zoll unterdrücken
|
||||
dimstyle-suppress-arrows-when-no-fit = Pfeile unterdrücken, wenn sie nicht passen
|
||||
dimstyle-suppress-first-dimension-line = Erste Maßlinie unterdrücken
|
||||
dimstyle-suppress-first-extension-line = Erste Hilfslinie unterdrücken
|
||||
dimstyle-suppress-second-dimension-line = Zweite Maßlinie unterdrücken
|
||||
dimstyle-suppress-second-extension-line = Zweite Hilfslinie unterdrücken
|
||||
dimstyle-suppress-zero-feet-and-inches = Null Fuß und null Zoll unterdrücken
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = Null Fuß unterdrücken; null Zoll anzeigen
|
||||
dimstyle-symbols-and-arrows = Symbole und Pfeile
|
||||
dimstyle-symmetrical = Symmetrisch
|
||||
dimstyle-text-background = Texthintergrund
|
||||
dimstyle-text-gap = Textabstand
|
||||
dimstyle-fixed-text-height-note = Der gewählte Textstil legt die Höhe auf __ocs_arg_height__ fest.
|
||||
dimstyle-tick-size = Schrägstrichgröße
|
||||
dimstyle-tolerance-zero-suppression = Nullunterdrückung für Toleranzen
|
||||
dimstyle-unit-format = Einheitenformat
|
||||
dimstyle-upper-value = Oberer Wert
|
||||
dimstyle-measurement-template-help = Verwenden Sie <> für den Messwert; Text davor und danach wird zum Präfix bzw. Suffix.
|
||||
dimstyle-use-different-arrowheads = Unterschiedliche erste und zweite Pfeilspitzen verwenden
|
||||
dimstyle-use-fixed-length-extension-lines = Hilfslinien mit fester Länge verwenden
|
||||
dimstyle-used-in-drawing = In Zeichnung verwendet
|
||||
dimstyle-vertical-offset = Vertikaler Abstand
|
||||
dimstyle-vertical-placement = Vertikale Platzierung
|
||||
dimstyle-vertical-position = Vertikale Position
|
||||
dimstyle-when-space-is-limited = Bei begrenztem Platz
|
||||
dimstyle-when-text-is-moved = Wenn Text verschoben wird
|
||||
dimstyle-zero-suppression = Nullunterdrückung
|
||||
dimstyle-add-a-leader = Führungslinie hinzufügen
|
||||
dimstyle-automatic = Automatisch
|
||||
dimstyle-by-block = Von Block
|
||||
dimstyle-comma = Komma
|
||||
dimstyle-degrees-minutes-seconds = Grad, Minuten, Sekunden
|
||||
dimstyle-keep-dimension-line-with-text = Maßlinie mit Text verschieben
|
||||
dimstyle-leading-and-trailing = Führende und nachfolgende Nullen
|
||||
dimstyle-move-arrows-outside-first = Zuerst Pfeile nach außen verschieben
|
||||
dimstyle-move-text-and-arrows-outside = Text und Pfeile nach außen verschieben
|
||||
dimstyle-move-text-freely = Text frei verschieben
|
||||
dimstyle-move-text-outside-first = Zuerst Text nach außen verschieben
|
||||
dimstyle-period = Punkt
|
||||
dimstyle-space = Leerzeichen
|
||||
style-manager-alignment-spacing = Ausrichtungsabstand
|
||||
style-manager-always-left-align = Immer links ausrichten
|
||||
style-manager-attachment-direction = Anschlussrichtung
|
||||
style-manager-background-fill-enabled = Hintergrundfüllung aktiviert
|
||||
style-manager-big-font = Großschrift
|
||||
style-manager-block-scale-x = Blockskalierung X
|
||||
style-manager-block-scale-y = Blockskalierung Y
|
||||
style-manager-block-scale-z = Blockskalierung Z
|
||||
style-manager-borders = Rahmenlinien
|
||||
style-manager-bottom-attachment = Unterer Anschluss
|
||||
style-manager-break-gap-size = Unterbrechungsabstand
|
||||
style-manager-caps-and-fill = Abschlüsse und Füllung
|
||||
style-manager-content-type = Inhaltstyp
|
||||
style-manager-data-row = Datenzeile
|
||||
style-manager-data-type = Datentyp
|
||||
style-manager-default-text = Standardtext
|
||||
style-manager-different = Unterschiedlich
|
||||
style-manager-display-joints = Verbindungen anzeigen
|
||||
style-manager-drawing-height = Zeichnungshöhe
|
||||
style-manager-drawing-scale = Zeichnungsmaßstab
|
||||
style-manager-effects = Effekte
|
||||
style-manager-elements = Elemente
|
||||
style-manager-end-caps = Endabschlüsse
|
||||
style-manager-fill-and-joints = Füllung und Verbindungen
|
||||
style-manager-fill-enabled = Füllung aktiviert
|
||||
style-manager-first-segment-angle = Winkel des ersten Segments
|
||||
style-manager-fixed-height = Feste Höhe
|
||||
style-manager-flow-direction = Flussrichtung
|
||||
style-manager-font-file = Schriftdatei
|
||||
style-manager-fonts = Schriftarten
|
||||
style-manager-format-string = Formatzeichenfolge
|
||||
style-manager-header = Kopfzeile
|
||||
style-manager-header-row = Kopfzeile
|
||||
style-manager-horizontal-margin = Horizontaler Rand
|
||||
style-manager-inner-arcs = Innere Bögen
|
||||
style-manager-inside-horizontal = Innen horizontal
|
||||
style-manager-inside-vertical = Innen vertikal
|
||||
style-manager-leader-draw-order = Zeichnungsreihenfolge der Führungslinie
|
||||
style-manager-leader-note = Führungslinienhinweis
|
||||
style-manager-left-attachment = Linker Anschluss
|
||||
style-manager-line-color = Linienfarbe
|
||||
style-manager-line-type = Linientyp
|
||||
style-manager-line-weight = Linienstärke
|
||||
style-manager-maximum-leader-points = Maximale Führungslinienpunkte
|
||||
style-manager-multileader-draw-order = Zeichnungsreihenfolge der Multi-Führungslinie
|
||||
style-manager-no-preview = Keine Vorschau
|
||||
style-manager-oblique-angle = Schrägstellwinkel
|
||||
style-manager-outer-arc = Außenbogen
|
||||
style-manager-paper-height = Papierhöhe
|
||||
style-manager-paper-text-height = Papiertexthöhe
|
||||
style-manager-path-type = Pfadtyp
|
||||
style-manager-right-attachment = Rechter Anschluss
|
||||
style-manager-scale-factor = Skalierungsfaktor
|
||||
style-manager-second-segment-angle = Winkel des zweiten Segments
|
||||
style-manager-size-and-effects = Größe und Effekte
|
||||
style-manager-start-caps = Startabschlüsse
|
||||
style-manager-stroke-fonts = Strichschriftarten
|
||||
style-manager-suppress-header-row = Kopfzeile unterdrücken
|
||||
style-manager-suppress-title-row = Titelzeile unterdrücken
|
||||
style-manager-system-font = Systemschriftart
|
||||
style-manager-system-fonts = Systemschriftarten
|
||||
style-manager-text-alignment = Textausrichtung
|
||||
style-manager-text-angle = Textwinkel
|
||||
style-manager-title-row = Titelzeile
|
||||
style-manager-top-attachment = Oberer Anschluss
|
||||
style-manager-unit-type = Einheitentyp
|
||||
style-manager-vertical-margin = Vertikaler Rand
|
||||
style-manager-font-family-placeholder = Schriftfamilie…
|
||||
style-manager-bottom-to-top = Von unten nach oben
|
||||
style-manager-arrowhead-first = Pfeilspitze zuerst
|
||||
style-manager-content-first = Inhalt zuerst
|
||||
style-manager-leader-first = Führungslinie zuerst
|
||||
style-manager-straight = Gerade
|
||||
style-manager-parallel-last-segment = Parallel zum letzten Segment
|
||||
style-manager-top-of-top-line = Oberkante der obersten Zeile
|
||||
style-manager-middle-of-top-line = Mitte der obersten Zeile
|
||||
style-manager-middle-of-text = Textmitte
|
||||
style-manager-middle-of-bottom-line = Mitte der untersten Zeile
|
||||
style-manager-bottom-of-bottom-line = Unterkante der untersten Zeile
|
||||
style-manager-bottom-line = Unterste Zeile
|
||||
style-manager-underline-bottom-line = Unterste Zeile unterstreichen
|
||||
style-manager-underline-top-line = Oberste Zeile unterstreichen
|
||||
style-manager-underline-all-text = Gesamten Text unterstreichen
|
||||
style-manager-center-of-text = Textzentrum
|
||||
style-manager-center-of-text-overline = Textzentrum mit Oberstrich
|
||||
style-manager-block-extents = Blockgrenzen
|
||||
style-manager-base-point = Basispunkt
|
||||
|
|
|
|||
|
|
@ -3195,3 +3195,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── __ocs_arg_MOD__ Shortcuts ────
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── Custom Overrides (SHORTCUTS SET) ──────────────────
|
||||
catalog-function-keys-b5a2df24e9 = ── Function Keys ──────────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── Other Keys ──────────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = Always keep text between extension lines
|
||||
dimstyle-angular-dimensions = Angular dimensions
|
||||
dimstyle-arc-length-symbol = Arc length symbol
|
||||
dimstyle-arrowheads = Arrowheads
|
||||
dimstyle-available-style = Available style
|
||||
dimstyle-baseline-spacing = Baseline spacing
|
||||
dimstyle-basic = Basic
|
||||
dimstyle-both-arrowheads = Both arrowheads
|
||||
dimstyle-center-mark = Center mark
|
||||
dimstyle-center-mark-size = Center mark size
|
||||
dimstyle-center-marks = Center marks
|
||||
dimstyle-centerlines = Centerlines
|
||||
dimstyle-compare-with = Compare with
|
||||
dimstyle-current-style = Current style
|
||||
dimstyle-deviation = Deviation
|
||||
dimstyle-different-sections = Different sections
|
||||
dimstyle-dimension-line-color = Dimension line color
|
||||
dimstyle-dimension-linetype = Dimension linetype
|
||||
dimstyle-dimension-lineweight = Dimension lineweight
|
||||
dimstyle-display-alternate-units = Display alternate units
|
||||
dimstyle-draw-dimension-line-between-extension-lines = Draw dimension line between extension lines
|
||||
dimstyle-extend-beyond-dimension-line = Extend beyond dimension line
|
||||
dimstyle-extend-beyond-ticks = Extend beyond ticks
|
||||
dimstyle-extension-line-color = Extension line color
|
||||
dimstyle-extension-lineweight = Extension lineweight
|
||||
dimstyle-feet-and-inches = Feet and inches
|
||||
dimstyle-fine-tuning = Fine tuning
|
||||
dimstyle-first-arrowhead = First arrowhead
|
||||
dimstyle-first-extension-linetype = First extension linetype
|
||||
dimstyle-fit-options = Fit options
|
||||
dimstyle-fixed-length = Fixed length
|
||||
dimstyle-fraction-format = Fraction format
|
||||
dimstyle-height-scale = Height scale
|
||||
dimstyle-horizontal-placement = Horizontal placement
|
||||
dimstyle-keep-text-horizontal-inside = Keep text horizontal when inside
|
||||
dimstyle-keep-text-horizontal-outside = Keep text horizontal when outside
|
||||
dimstyle-leader-arrowhead = Leader arrowhead
|
||||
dimstyle-limits = Limits
|
||||
dimstyle-linear-dimensions = Linear dimensions
|
||||
dimstyle-lower-value = Lower value
|
||||
dimstyle-measurement-scale = Measurement scale
|
||||
dimstyle-measurement-template = Measurement template
|
||||
dimstyle-method = Method
|
||||
dimstyle-multiplier = Multiplier
|
||||
dimstyle-no-differences = No differences
|
||||
dimstyle-not-applicable = Not applicable
|
||||
dimstyle-offset-from-measured-point = Offset from measured point
|
||||
dimstyle-place-text-manually = Place text manually while creating dimensions
|
||||
dimstyle-radius-jog-angle = Radius jog angle (°)
|
||||
dimstyle-read-left-to-right = Read left to right
|
||||
dimstyle-referenced-read-only = Referenced style · Read only
|
||||
dimstyle-round-off = Round off
|
||||
dimstyle-second-arrowhead = Second arrowhead
|
||||
dimstyle-second-extension-linetype = Second extension linetype
|
||||
dimstyle-show-zero-feet-and-inches = Show zero feet and zero inches
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = Show zero feet; suppress zero inches
|
||||
dimstyle-suppress-arrows-when-no-fit = Suppress arrows when they do not fit
|
||||
dimstyle-suppress-first-dimension-line = Suppress first dimension line
|
||||
dimstyle-suppress-first-extension-line = Suppress first extension line
|
||||
dimstyle-suppress-second-dimension-line = Suppress second dimension line
|
||||
dimstyle-suppress-second-extension-line = Suppress second extension line
|
||||
dimstyle-suppress-zero-feet-and-inches = Suppress zero feet and zero inches
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = Suppress zero feet; show zero inches
|
||||
dimstyle-symbols-and-arrows = Symbols and Arrows
|
||||
dimstyle-symmetrical = Symmetrical
|
||||
dimstyle-text-background = Text background
|
||||
dimstyle-text-gap = Text gap
|
||||
dimstyle-fixed-text-height-note = The selected text style fixes the height at __ocs_arg_height__.
|
||||
dimstyle-tick-size = Tick size
|
||||
dimstyle-tolerance-zero-suppression = Tolerance zero suppression
|
||||
dimstyle-unit-format = Unit format
|
||||
dimstyle-upper-value = Upper value
|
||||
dimstyle-measurement-template-help = Use <> as the measured value; text before and after it becomes the prefix and suffix.
|
||||
dimstyle-use-different-arrowheads = Use different first and second arrowheads
|
||||
dimstyle-use-fixed-length-extension-lines = Use fixed-length extension lines
|
||||
dimstyle-used-in-drawing = Used in drawing
|
||||
dimstyle-vertical-offset = Vertical offset
|
||||
dimstyle-vertical-placement = Vertical placement
|
||||
dimstyle-vertical-position = Vertical position
|
||||
dimstyle-when-space-is-limited = When space is limited
|
||||
dimstyle-when-text-is-moved = When text is moved
|
||||
dimstyle-zero-suppression = Zero suppression
|
||||
dimstyle-add-a-leader = Add a leader
|
||||
dimstyle-automatic = Automatic
|
||||
dimstyle-by-block = By block
|
||||
dimstyle-comma = Comma
|
||||
dimstyle-degrees-minutes-seconds = Degrees, minutes, seconds
|
||||
dimstyle-keep-dimension-line-with-text = Keep dimension line with text
|
||||
dimstyle-leading-and-trailing = Leading and trailing
|
||||
dimstyle-move-arrows-outside-first = Move arrows outside first
|
||||
dimstyle-move-text-and-arrows-outside = Move text and arrows outside
|
||||
dimstyle-move-text-freely = Move text freely
|
||||
dimstyle-move-text-outside-first = Move text outside first
|
||||
dimstyle-period = Period
|
||||
dimstyle-space = Space
|
||||
style-manager-alignment-spacing = Alignment spacing
|
||||
style-manager-always-left-align = Always left align
|
||||
style-manager-attachment-direction = Attachment direction
|
||||
style-manager-background-fill-enabled = Background fill enabled
|
||||
style-manager-big-font = Big font
|
||||
style-manager-block-scale-x = Block scale X
|
||||
style-manager-block-scale-y = Block scale Y
|
||||
style-manager-block-scale-z = Block scale Z
|
||||
style-manager-borders = Borders
|
||||
style-manager-bottom-attachment = Bottom attachment
|
||||
style-manager-break-gap-size = Break gap size
|
||||
style-manager-caps-and-fill = Caps and Fill
|
||||
style-manager-content-type = Content type
|
||||
style-manager-data-row = Data Row
|
||||
style-manager-data-type = Data type
|
||||
style-manager-default-text = Default text
|
||||
style-manager-different = Different
|
||||
style-manager-display-joints = Display joints
|
||||
style-manager-drawing-height = Drawing height
|
||||
style-manager-drawing-scale = Drawing scale
|
||||
style-manager-effects = Effects
|
||||
style-manager-elements = Elements
|
||||
style-manager-end-caps = End caps
|
||||
style-manager-fill-and-joints = Fill and joints
|
||||
style-manager-fill-enabled = Fill enabled
|
||||
style-manager-first-segment-angle = First segment angle
|
||||
style-manager-fixed-height = Fixed height
|
||||
style-manager-flow-direction = Flow direction
|
||||
style-manager-font-file = Font file
|
||||
style-manager-fonts = Fonts
|
||||
style-manager-format-string = Format string
|
||||
style-manager-header = Header
|
||||
style-manager-header-row = Header Row
|
||||
style-manager-horizontal-margin = Horizontal margin
|
||||
style-manager-inner-arcs = Inner arcs
|
||||
style-manager-inside-horizontal = Inside horizontal
|
||||
style-manager-inside-vertical = Inside vertical
|
||||
style-manager-leader-draw-order = Leader draw order
|
||||
style-manager-leader-note = Leader note
|
||||
style-manager-left-attachment = Left attachment
|
||||
style-manager-line-color = Line color
|
||||
style-manager-line-type = Line type
|
||||
style-manager-line-weight = Line weight
|
||||
style-manager-maximum-leader-points = Maximum leader points
|
||||
style-manager-multileader-draw-order = Multileader draw order
|
||||
style-manager-no-preview = No preview
|
||||
style-manager-oblique-angle = Oblique angle
|
||||
style-manager-outer-arc = Outer arc
|
||||
style-manager-paper-height = Paper height
|
||||
style-manager-paper-text-height = Paper text height
|
||||
style-manager-path-type = Path type
|
||||
style-manager-right-attachment = Right attachment
|
||||
style-manager-scale-factor = Scale factor
|
||||
style-manager-second-segment-angle = Second segment angle
|
||||
style-manager-size-and-effects = Size and Effects
|
||||
style-manager-start-caps = Start caps
|
||||
style-manager-stroke-fonts = Stroke fonts
|
||||
style-manager-suppress-header-row = Suppress header row
|
||||
style-manager-suppress-title-row = Suppress title row
|
||||
style-manager-system-font = System font
|
||||
style-manager-system-fonts = System fonts
|
||||
style-manager-text-alignment = Text alignment
|
||||
style-manager-text-angle = Text angle
|
||||
style-manager-title-row = Title Row
|
||||
style-manager-top-attachment = Top attachment
|
||||
style-manager-unit-type = Unit type
|
||||
style-manager-vertical-margin = Vertical margin
|
||||
style-manager-font-family-placeholder = font family…
|
||||
style-manager-bottom-to-top = Bottom to top
|
||||
style-manager-arrowhead-first = Arrowhead first
|
||||
style-manager-content-first = Content first
|
||||
style-manager-leader-first = Leader first
|
||||
style-manager-straight = Straight
|
||||
style-manager-parallel-last-segment = Parallel to last segment
|
||||
style-manager-top-of-top-line = Top of top line
|
||||
style-manager-middle-of-top-line = Middle of top line
|
||||
style-manager-middle-of-text = Middle of text
|
||||
style-manager-middle-of-bottom-line = Middle of bottom line
|
||||
style-manager-bottom-of-bottom-line = Bottom of bottom line
|
||||
style-manager-bottom-line = Bottom line
|
||||
style-manager-underline-bottom-line = Underline bottom line
|
||||
style-manager-underline-top-line = Underline top line
|
||||
style-manager-underline-all-text = Underline all text
|
||||
style-manager-center-of-text = Center of text
|
||||
style-manager-center-of-text-overline = Center of text with overline
|
||||
style-manager-block-extents = Block extents
|
||||
style-manager-base-point = Base point
|
||||
|
|
|
|||
|
|
@ -3194,3 +3194,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── Raccourcis __ocs_arg_MOD__ ───
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── Remplacements personnalisés (SHORTCUTS SET) ───────
|
||||
catalog-function-keys-b5a2df24e9 = ── Touches de fonction ────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── Autres touches ─────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = Toujours conserver le texte entre les lignes d’attache
|
||||
dimstyle-angular-dimensions = Cotes angulaires
|
||||
dimstyle-arc-length-symbol = Symbole de longueur d’arc
|
||||
dimstyle-arrowheads = Pointes de flèche
|
||||
dimstyle-available-style = Style disponible
|
||||
dimstyle-baseline-spacing = Espacement des lignes de base
|
||||
dimstyle-basic = Théorique exacte
|
||||
dimstyle-both-arrowheads = Deux pointes de flèche
|
||||
dimstyle-center-mark = Marque de centre
|
||||
dimstyle-center-mark-size = Taille de la marque de centre
|
||||
dimstyle-center-marks = Marques de centre
|
||||
dimstyle-centerlines = Axes
|
||||
dimstyle-compare-with = Comparer avec
|
||||
dimstyle-current-style = Style courant
|
||||
dimstyle-deviation = Écarts
|
||||
dimstyle-different-sections = Sections différentes
|
||||
dimstyle-dimension-line-color = Couleur de ligne de cote
|
||||
dimstyle-dimension-linetype = Type de ligne de cote
|
||||
dimstyle-dimension-lineweight = Épaisseur de ligne de cote
|
||||
dimstyle-display-alternate-units = Afficher les unités alternatives
|
||||
dimstyle-draw-dimension-line-between-extension-lines = Tracer la ligne de cote entre les lignes d’attache
|
||||
dimstyle-extend-beyond-dimension-line = Dépassement de la ligne de cote
|
||||
dimstyle-extend-beyond-ticks = Dépassement des obliques
|
||||
dimstyle-extension-line-color = Couleur de ligne d’attache
|
||||
dimstyle-extension-lineweight = Épaisseur de ligne d’attache
|
||||
dimstyle-feet-and-inches = Pieds et pouces
|
||||
dimstyle-fine-tuning = Ajustement fin
|
||||
dimstyle-first-arrowhead = Première pointe de flèche
|
||||
dimstyle-first-extension-linetype = Type de la première ligne d’attache
|
||||
dimstyle-fit-options = Options d’ajustement
|
||||
dimstyle-fixed-length = Longueur fixe
|
||||
dimstyle-fraction-format = Format de fraction
|
||||
dimstyle-height-scale = Échelle de hauteur
|
||||
dimstyle-horizontal-placement = Placement horizontal
|
||||
dimstyle-keep-text-horizontal-inside = Conserver le texte horizontal à l’intérieur
|
||||
dimstyle-keep-text-horizontal-outside = Conserver le texte horizontal à l’extérieur
|
||||
dimstyle-leader-arrowhead = Pointe de flèche de repère
|
||||
dimstyle-limits = Limites
|
||||
dimstyle-linear-dimensions = Cotes linéaires
|
||||
dimstyle-lower-value = Valeur inférieure
|
||||
dimstyle-measurement-scale = Échelle de mesure
|
||||
dimstyle-measurement-template = Modèle de mesure
|
||||
dimstyle-method = Méthode
|
||||
dimstyle-multiplier = Multiplicateur
|
||||
dimstyle-no-differences = Aucune différence
|
||||
dimstyle-not-applicable = Sans objet
|
||||
dimstyle-offset-from-measured-point = Décalage depuis le point mesuré
|
||||
dimstyle-place-text-manually = Placer le texte manuellement lors de la cotation
|
||||
dimstyle-radius-jog-angle = Angle de la ligne brisée de rayon (°)
|
||||
dimstyle-read-left-to-right = Lire de gauche à droite
|
||||
dimstyle-referenced-read-only = Style référencé · Lecture seule
|
||||
dimstyle-round-off = Arrondi
|
||||
dimstyle-second-arrowhead = Deuxième pointe de flèche
|
||||
dimstyle-second-extension-linetype = Type de la deuxième ligne d’attache
|
||||
dimstyle-show-zero-feet-and-inches = Afficher zéro pied et zéro pouce
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = Afficher zéro pied ; supprimer zéro pouce
|
||||
dimstyle-suppress-arrows-when-no-fit = Supprimer les flèches si elles ne tiennent pas
|
||||
dimstyle-suppress-first-dimension-line = Supprimer la première ligne de cote
|
||||
dimstyle-suppress-first-extension-line = Supprimer la première ligne d’attache
|
||||
dimstyle-suppress-second-dimension-line = Supprimer la deuxième ligne de cote
|
||||
dimstyle-suppress-second-extension-line = Supprimer la deuxième ligne d’attache
|
||||
dimstyle-suppress-zero-feet-and-inches = Supprimer zéro pied et zéro pouce
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = Supprimer zéro pied ; afficher zéro pouce
|
||||
dimstyle-symbols-and-arrows = Symboles et flèches
|
||||
dimstyle-symmetrical = Symétrique
|
||||
dimstyle-text-background = Arrière-plan du texte
|
||||
dimstyle-text-gap = Espacement du texte
|
||||
dimstyle-fixed-text-height-note = Le style de texte sélectionné fixe la hauteur à __ocs_arg_height__.
|
||||
dimstyle-tick-size = Taille des obliques
|
||||
dimstyle-tolerance-zero-suppression = Suppression des zéros de tolérance
|
||||
dimstyle-unit-format = Format d’unité
|
||||
dimstyle-upper-value = Valeur supérieure
|
||||
dimstyle-measurement-template-help = Utilisez <> pour la valeur mesurée ; le texte placé avant et après devient le préfixe et le suffixe.
|
||||
dimstyle-use-different-arrowheads = Utiliser des pointes différentes aux deux extrémités
|
||||
dimstyle-use-fixed-length-extension-lines = Utiliser des lignes d’attache de longueur fixe
|
||||
dimstyle-used-in-drawing = Utilisé dans le dessin
|
||||
dimstyle-vertical-offset = Décalage vertical
|
||||
dimstyle-vertical-placement = Placement vertical
|
||||
dimstyle-vertical-position = Position verticale
|
||||
dimstyle-when-space-is-limited = Lorsque l’espace est limité
|
||||
dimstyle-when-text-is-moved = Lorsque le texte est déplacé
|
||||
dimstyle-zero-suppression = Suppression des zéros
|
||||
dimstyle-add-a-leader = Ajouter une ligne de repère
|
||||
dimstyle-automatic = Automatique
|
||||
dimstyle-by-block = Du bloc
|
||||
dimstyle-comma = Virgule
|
||||
dimstyle-degrees-minutes-seconds = Degrés, minutes, secondes
|
||||
dimstyle-keep-dimension-line-with-text = Déplacer la ligne de cote avec le texte
|
||||
dimstyle-leading-and-trailing = Zéros de début et de fin
|
||||
dimstyle-move-arrows-outside-first = Déplacer d’abord les flèches à l’extérieur
|
||||
dimstyle-move-text-and-arrows-outside = Déplacer le texte et les flèches à l’extérieur
|
||||
dimstyle-move-text-freely = Déplacer le texte librement
|
||||
dimstyle-move-text-outside-first = Déplacer d’abord le texte à l’extérieur
|
||||
dimstyle-period = Point
|
||||
dimstyle-space = Espace
|
||||
style-manager-alignment-spacing = Espacement d’alignement
|
||||
style-manager-always-left-align = Toujours aligner à gauche
|
||||
style-manager-attachment-direction = Direction d’attachement
|
||||
style-manager-background-fill-enabled = Remplissage d’arrière-plan activé
|
||||
style-manager-big-font = Police grande taille
|
||||
style-manager-block-scale-x = Échelle X du bloc
|
||||
style-manager-block-scale-y = Échelle Y du bloc
|
||||
style-manager-block-scale-z = Échelle Z du bloc
|
||||
style-manager-borders = Bordures
|
||||
style-manager-bottom-attachment = Attachement inférieur
|
||||
style-manager-break-gap-size = Taille de l’espacement de coupure
|
||||
style-manager-caps-and-fill = Extrémités et remplissage
|
||||
style-manager-content-type = Type de contenu
|
||||
style-manager-data-row = Ligne de données
|
||||
style-manager-data-type = Type de données
|
||||
style-manager-default-text = Texte par défaut
|
||||
style-manager-different = Différent
|
||||
style-manager-display-joints = Afficher les jonctions
|
||||
style-manager-drawing-height = Hauteur dans le dessin
|
||||
style-manager-drawing-scale = Échelle du dessin
|
||||
style-manager-effects = Effets
|
||||
style-manager-elements = Éléments
|
||||
style-manager-end-caps = Extrémités de fin
|
||||
style-manager-fill-and-joints = Remplissage et jonctions
|
||||
style-manager-fill-enabled = Remplissage activé
|
||||
style-manager-first-segment-angle = Angle du premier segment
|
||||
style-manager-fixed-height = Hauteur fixe
|
||||
style-manager-flow-direction = Sens de lecture
|
||||
style-manager-font-file = Fichier de police
|
||||
style-manager-fonts = Polices
|
||||
style-manager-format-string = Chaîne de format
|
||||
style-manager-header = En-tête
|
||||
style-manager-header-row = Ligne d’en-tête
|
||||
style-manager-horizontal-margin = Marge horizontale
|
||||
style-manager-inner-arcs = Arcs intérieurs
|
||||
style-manager-inside-horizontal = Intérieur horizontal
|
||||
style-manager-inside-vertical = Intérieur vertical
|
||||
style-manager-leader-draw-order = Ordre de tracé de la ligne de repère
|
||||
style-manager-leader-note = Note de repère
|
||||
style-manager-left-attachment = Attachement gauche
|
||||
style-manager-line-color = Couleur de ligne
|
||||
style-manager-line-type = Type de ligne
|
||||
style-manager-line-weight = Épaisseur de ligne
|
||||
style-manager-maximum-leader-points = Nombre maximal de points de repère
|
||||
style-manager-multileader-draw-order = Ordre de tracé du repère multiple
|
||||
style-manager-no-preview = Aucun aperçu
|
||||
style-manager-oblique-angle = Angle d’inclinaison
|
||||
style-manager-outer-arc = Arc extérieur
|
||||
style-manager-paper-height = Hauteur sur papier
|
||||
style-manager-paper-text-height = Hauteur de texte sur papier
|
||||
style-manager-path-type = Type de trajectoire
|
||||
style-manager-right-attachment = Attachement droit
|
||||
style-manager-scale-factor = Facteur d’échelle
|
||||
style-manager-second-segment-angle = Angle du deuxième segment
|
||||
style-manager-size-and-effects = Taille et effets
|
||||
style-manager-start-caps = Extrémités de départ
|
||||
style-manager-stroke-fonts = Polices filaires
|
||||
style-manager-suppress-header-row = Masquer la ligne d’en-tête
|
||||
style-manager-suppress-title-row = Masquer la ligne de titre
|
||||
style-manager-system-font = Police système
|
||||
style-manager-system-fonts = Polices système
|
||||
style-manager-text-alignment = Alignement du texte
|
||||
style-manager-text-angle = Angle du texte
|
||||
style-manager-title-row = Ligne de titre
|
||||
style-manager-top-attachment = Attachement supérieur
|
||||
style-manager-unit-type = Type d’unité
|
||||
style-manager-vertical-margin = Marge verticale
|
||||
style-manager-font-family-placeholder = famille de polices…
|
||||
style-manager-bottom-to-top = De bas en haut
|
||||
style-manager-arrowhead-first = Pointe de flèche en premier
|
||||
style-manager-content-first = Contenu en premier
|
||||
style-manager-leader-first = Ligne de repère en premier
|
||||
style-manager-straight = Droite
|
||||
style-manager-parallel-last-segment = Parallèle au dernier segment
|
||||
style-manager-top-of-top-line = Haut de la ligne supérieure
|
||||
style-manager-middle-of-top-line = Milieu de la ligne supérieure
|
||||
style-manager-middle-of-text = Milieu du texte
|
||||
style-manager-middle-of-bottom-line = Milieu de la ligne inférieure
|
||||
style-manager-bottom-of-bottom-line = Bas de la ligne inférieure
|
||||
style-manager-bottom-line = Ligne inférieure
|
||||
style-manager-underline-bottom-line = Souligner la ligne inférieure
|
||||
style-manager-underline-top-line = Souligner la ligne supérieure
|
||||
style-manager-underline-all-text = Souligner tout le texte
|
||||
style-manager-center-of-text = Centre du texte
|
||||
style-manager-center-of-text-overline = Centre du texte avec surlignement
|
||||
style-manager-block-extents = Limites du bloc
|
||||
style-manager-base-point = Point de base
|
||||
|
|
|
|||
|
|
@ -3183,3 +3183,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── __ocs_arg_MOD__ शॉर्टकट
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── कस्टम ओवरराइड (SHORTCUTS SET) ────────────────────
|
||||
catalog-function-keys-b5a2df24e9 = ── फ़ंक्शन कुंजियाँ ───────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── अन्य कुंजियाँ ─────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = पाठ को हमेशा विस्तार रेखाओं के बीच रखें
|
||||
dimstyle-angular-dimensions = कोणीय माप
|
||||
dimstyle-arc-length-symbol = चाप लंबाई चिह्न
|
||||
dimstyle-arrowheads = तीर शीर्ष
|
||||
dimstyle-available-style = उपलब्ध शैली
|
||||
dimstyle-baseline-spacing = आधार रेखा अंतर
|
||||
dimstyle-basic = मूल
|
||||
dimstyle-both-arrowheads = दोनों तीर शीर्ष
|
||||
dimstyle-center-mark = केंद्र चिह्न
|
||||
dimstyle-center-mark-size = केंद्र चिह्न का आकार
|
||||
dimstyle-center-marks = केंद्र चिह्न
|
||||
dimstyle-centerlines = केंद्र रेखाएँ
|
||||
dimstyle-compare-with = इससे तुलना करें
|
||||
dimstyle-current-style = वर्तमान शैली
|
||||
dimstyle-deviation = विचलन
|
||||
dimstyle-different-sections = भिन्न अनुभाग
|
||||
dimstyle-dimension-line-color = माप रेखा का रंग
|
||||
dimstyle-dimension-linetype = माप रेखा प्रकार
|
||||
dimstyle-dimension-lineweight = माप रेखा मोटाई
|
||||
dimstyle-display-alternate-units = वैकल्पिक इकाइयाँ दिखाएँ
|
||||
dimstyle-draw-dimension-line-between-extension-lines = विस्तार रेखाओं के बीच माप रेखा बनाएँ
|
||||
dimstyle-extend-beyond-dimension-line = माप रेखा से आगे बढ़ाएँ
|
||||
dimstyle-extend-beyond-ticks = तिरछे चिह्नों से आगे बढ़ाएँ
|
||||
dimstyle-extension-line-color = विस्तार रेखा का रंग
|
||||
dimstyle-extension-lineweight = विस्तार रेखा मोटाई
|
||||
dimstyle-feet-and-inches = फुट और इंच
|
||||
dimstyle-fine-tuning = सूक्ष्म समायोजन
|
||||
dimstyle-first-arrowhead = पहला तीर शीर्ष
|
||||
dimstyle-first-extension-linetype = पहली विस्तार रेखा का प्रकार
|
||||
dimstyle-fit-options = समायोजन विकल्प
|
||||
dimstyle-fixed-length = निश्चित लंबाई
|
||||
dimstyle-fraction-format = भिन्न प्रारूप
|
||||
dimstyle-height-scale = ऊँचाई मापनी
|
||||
dimstyle-horizontal-placement = क्षैतिज स्थान
|
||||
dimstyle-keep-text-horizontal-inside = अंदर होने पर पाठ क्षैतिज रखें
|
||||
dimstyle-keep-text-horizontal-outside = बाहर होने पर पाठ क्षैतिज रखें
|
||||
dimstyle-leader-arrowhead = संकेतक तीर शीर्ष
|
||||
dimstyle-limits = सीमाएँ
|
||||
dimstyle-linear-dimensions = रैखिक माप
|
||||
dimstyle-lower-value = निचला मान
|
||||
dimstyle-measurement-scale = मापन मापनी
|
||||
dimstyle-measurement-template = मापन साँचा
|
||||
dimstyle-method = विधि
|
||||
dimstyle-multiplier = गुणक
|
||||
dimstyle-no-differences = कोई अंतर नहीं
|
||||
dimstyle-not-applicable = लागू नहीं
|
||||
dimstyle-offset-from-measured-point = मापे गए बिंदु से दूरी
|
||||
dimstyle-place-text-manually = माप बनाते समय पाठ को स्वयं रखें
|
||||
dimstyle-radius-jog-angle = त्रिज्या मोड़ कोण (°)
|
||||
dimstyle-read-left-to-right = बाएँ से दाएँ पढ़ें
|
||||
dimstyle-referenced-read-only = संदर्भित शैली · केवल पढ़ने योग्य
|
||||
dimstyle-round-off = पूर्णांकन
|
||||
dimstyle-second-arrowhead = दूसरा तीर शीर्ष
|
||||
dimstyle-second-extension-linetype = दूसरी विस्तार रेखा का प्रकार
|
||||
dimstyle-show-zero-feet-and-inches = शून्य फुट और शून्य इंच दिखाएँ
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = शून्य फुट दिखाएँ; शून्य इंच छिपाएँ
|
||||
dimstyle-suppress-arrows-when-no-fit = जगह न होने पर तीर छिपाएँ
|
||||
dimstyle-suppress-first-dimension-line = पहली माप रेखा छिपाएँ
|
||||
dimstyle-suppress-first-extension-line = पहली विस्तार रेखा छिपाएँ
|
||||
dimstyle-suppress-second-dimension-line = दूसरी माप रेखा छिपाएँ
|
||||
dimstyle-suppress-second-extension-line = दूसरी विस्तार रेखा छिपाएँ
|
||||
dimstyle-suppress-zero-feet-and-inches = शून्य फुट और शून्य इंच छिपाएँ
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = शून्य फुट छिपाएँ; शून्य इंच दिखाएँ
|
||||
dimstyle-symbols-and-arrows = चिह्न और तीर
|
||||
dimstyle-symmetrical = सममित
|
||||
dimstyle-text-background = पाठ पृष्ठभूमि
|
||||
dimstyle-text-gap = पाठ अंतर
|
||||
dimstyle-fixed-text-height-note = चुनी गई पाठ शैली ऊँचाई को __ocs_arg_height__ पर स्थिर करती है।
|
||||
dimstyle-tick-size = तिरछे चिह्न का आकार
|
||||
dimstyle-tolerance-zero-suppression = सहनशीलता के शून्य छिपाना
|
||||
dimstyle-unit-format = इकाई प्रारूप
|
||||
dimstyle-upper-value = ऊपरी मान
|
||||
dimstyle-measurement-template-help = मापे गए मान के लिए <> का उपयोग करें; इसके पहले और बाद का पाठ उपसर्ग और प्रत्यय बनता है।
|
||||
dimstyle-use-different-arrowheads = पहले और दूसरे तीर शीर्ष अलग रखें
|
||||
dimstyle-use-fixed-length-extension-lines = निश्चित लंबाई की विस्तार रेखाएँ उपयोग करें
|
||||
dimstyle-used-in-drawing = आरेख में प्रयुक्त
|
||||
dimstyle-vertical-offset = ऊर्ध्वाधर दूरी
|
||||
dimstyle-vertical-placement = ऊर्ध्वाधर स्थान
|
||||
dimstyle-vertical-position = ऊर्ध्वाधर स्थिति
|
||||
dimstyle-when-space-is-limited = जब स्थान सीमित हो
|
||||
dimstyle-when-text-is-moved = जब पाठ हटाया जाए
|
||||
dimstyle-zero-suppression = शून्य छिपाना
|
||||
dimstyle-add-a-leader = संकेतक रेखा जोड़ें
|
||||
dimstyle-automatic = स्वचालित
|
||||
dimstyle-by-block = ब्लॉक के अनुसार
|
||||
dimstyle-comma = अल्पविराम
|
||||
dimstyle-degrees-minutes-seconds = अंश, मिनट, सेकंड
|
||||
dimstyle-keep-dimension-line-with-text = माप रेखा को पाठ के साथ रखें
|
||||
dimstyle-leading-and-trailing = आरंभिक और अंतिम
|
||||
dimstyle-move-arrows-outside-first = पहले तीर बाहर ले जाएँ
|
||||
dimstyle-move-text-and-arrows-outside = पाठ और तीर बाहर ले जाएँ
|
||||
dimstyle-move-text-freely = पाठ को स्वतंत्र रूप से ले जाएँ
|
||||
dimstyle-move-text-outside-first = पहले पाठ बाहर ले जाएँ
|
||||
dimstyle-period = दशमलव बिंदु
|
||||
dimstyle-space = रिक्त स्थान
|
||||
style-manager-alignment-spacing = संरेखण अंतराल
|
||||
style-manager-always-left-align = हमेशा बाएँ संरेखित करें
|
||||
style-manager-attachment-direction = संयोजन दिशा
|
||||
style-manager-background-fill-enabled = पृष्ठभूमि भराव सक्षम
|
||||
style-manager-big-font = बड़ा फ़ॉन्ट
|
||||
style-manager-block-scale-x = ब्लॉक X स्केल
|
||||
style-manager-block-scale-y = ब्लॉक Y स्केल
|
||||
style-manager-block-scale-z = ब्लॉक Z स्केल
|
||||
style-manager-borders = सीमाएँ
|
||||
style-manager-bottom-attachment = निचला संयोजन
|
||||
style-manager-break-gap-size = ब्रेक अंतराल आकार
|
||||
style-manager-caps-and-fill = सिरे और भराव
|
||||
style-manager-content-type = सामग्री प्रकार
|
||||
style-manager-data-row = डेटा पंक्ति
|
||||
style-manager-data-type = डेटा प्रकार
|
||||
style-manager-default-text = डिफ़ॉल्ट टेक्स्ट
|
||||
style-manager-different = भिन्न
|
||||
style-manager-display-joints = जोड़ दिखाएँ
|
||||
style-manager-drawing-height = ड्रॉइंग ऊँचाई
|
||||
style-manager-drawing-scale = ड्रॉइंग स्केल
|
||||
style-manager-effects = प्रभाव
|
||||
style-manager-elements = अवयव
|
||||
style-manager-end-caps = अंतिम सिरे
|
||||
style-manager-fill-and-joints = भराव और जोड़
|
||||
style-manager-fill-enabled = भराव सक्षम
|
||||
style-manager-first-segment-angle = पहले खंड का कोण
|
||||
style-manager-fixed-height = निश्चित ऊँचाई
|
||||
style-manager-flow-direction = प्रवाह दिशा
|
||||
style-manager-font-file = फ़ॉन्ट फ़ाइल
|
||||
style-manager-fonts = फ़ॉन्ट
|
||||
style-manager-format-string = प्रारूप स्ट्रिंग
|
||||
style-manager-header = शीर्षलेख
|
||||
style-manager-header-row = शीर्षलेख पंक्ति
|
||||
style-manager-horizontal-margin = क्षैतिज हाशिया
|
||||
style-manager-inner-arcs = आंतरिक चाप
|
||||
style-manager-inside-horizontal = आंतरिक क्षैतिज
|
||||
style-manager-inside-vertical = आंतरिक ऊर्ध्वाधर
|
||||
style-manager-leader-draw-order = लीडर आरेखन क्रम
|
||||
style-manager-leader-note = लीडर टिप्पणी
|
||||
style-manager-left-attachment = बायाँ संयोजन
|
||||
style-manager-line-color = रेखा रंग
|
||||
style-manager-line-type = रेखा प्रकार
|
||||
style-manager-line-weight = रेखा मोटाई
|
||||
style-manager-maximum-leader-points = अधिकतम लीडर बिंदु
|
||||
style-manager-multileader-draw-order = मल्टीलीडर आरेखन क्रम
|
||||
style-manager-no-preview = कोई पूर्वावलोकन नहीं
|
||||
style-manager-oblique-angle = तिरछा कोण
|
||||
style-manager-outer-arc = बाहरी चाप
|
||||
style-manager-paper-height = काग़ज़ ऊँचाई
|
||||
style-manager-paper-text-height = काग़ज़ पर टेक्स्ट ऊँचाई
|
||||
style-manager-path-type = पथ प्रकार
|
||||
style-manager-right-attachment = दायाँ संयोजन
|
||||
style-manager-scale-factor = स्केल गुणक
|
||||
style-manager-second-segment-angle = दूसरे खंड का कोण
|
||||
style-manager-size-and-effects = आकार और प्रभाव
|
||||
style-manager-start-caps = आरंभिक सिरे
|
||||
style-manager-stroke-fonts = रेखीय फ़ॉन्ट
|
||||
style-manager-suppress-header-row = शीर्षलेख पंक्ति छिपाएँ
|
||||
style-manager-suppress-title-row = शीर्षक पंक्ति छिपाएँ
|
||||
style-manager-system-font = सिस्टम फ़ॉन्ट
|
||||
style-manager-system-fonts = सिस्टम फ़ॉन्ट
|
||||
style-manager-text-alignment = टेक्स्ट संरेखण
|
||||
style-manager-text-angle = टेक्स्ट कोण
|
||||
style-manager-title-row = शीर्षक पंक्ति
|
||||
style-manager-top-attachment = ऊपरी संयोजन
|
||||
style-manager-unit-type = इकाई प्रकार
|
||||
style-manager-vertical-margin = ऊर्ध्वाधर हाशिया
|
||||
style-manager-font-family-placeholder = फ़ॉन्ट परिवार…
|
||||
style-manager-bottom-to-top = नीचे से ऊपर
|
||||
style-manager-arrowhead-first = पहले तीर का सिरा
|
||||
style-manager-content-first = पहले सामग्री
|
||||
style-manager-leader-first = पहले लीडर
|
||||
style-manager-straight = सीधा
|
||||
style-manager-parallel-last-segment = अंतिम खंड के समांतर
|
||||
style-manager-top-of-top-line = शीर्ष पंक्ति का ऊपरी भाग
|
||||
style-manager-middle-of-top-line = शीर्ष पंक्ति का मध्य
|
||||
style-manager-middle-of-text = टेक्स्ट का मध्य
|
||||
style-manager-middle-of-bottom-line = निचली पंक्ति का मध्य
|
||||
style-manager-bottom-of-bottom-line = निचली पंक्ति का निचला भाग
|
||||
style-manager-bottom-line = निचली पंक्ति
|
||||
style-manager-underline-bottom-line = निचली पंक्ति के नीचे रेखा
|
||||
style-manager-underline-top-line = शीर्ष पंक्ति के नीचे रेखा
|
||||
style-manager-underline-all-text = सभी टेक्स्ट के नीचे रेखा
|
||||
style-manager-center-of-text = टेक्स्ट का केंद्र
|
||||
style-manager-center-of-text-overline = ऊपरी रेखा सहित टेक्स्ट का केंद्र
|
||||
style-manager-block-extents = ब्लॉक परिमिति
|
||||
style-manager-base-point = आधार बिंदु
|
||||
|
|
|
|||
|
|
@ -3195,3 +3195,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── __ocs_arg_MOD__-sneltoetsen ───
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── Aangepaste overschrijvingen (SHORTCUTS SET) ────────
|
||||
catalog-function-keys-b5a2df24e9 = ── Functietoetsen ─────────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── Overige toetsen ────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = Tekst altijd tussen hulplijnen houden
|
||||
dimstyle-angular-dimensions = Hoekmaten
|
||||
dimstyle-arc-length-symbol = Booglengtesymbool
|
||||
dimstyle-arrowheads = Pijlpunten
|
||||
dimstyle-available-style = Beschikbare stijl
|
||||
dimstyle-baseline-spacing = Basislijnafstand
|
||||
dimstyle-basic = Basis
|
||||
dimstyle-both-arrowheads = Beide pijlpunten
|
||||
dimstyle-center-mark = Middelpuntmarkering
|
||||
dimstyle-center-mark-size = Grootte van middelpuntmarkering
|
||||
dimstyle-center-marks = Middelpuntmarkeringen
|
||||
dimstyle-centerlines = Hartlijnen
|
||||
dimstyle-compare-with = Vergelijken met
|
||||
dimstyle-current-style = Huidige stijl
|
||||
dimstyle-deviation = Afwijking
|
||||
dimstyle-different-sections = Afwijkende secties
|
||||
dimstyle-dimension-line-color = Kleur maatlijn
|
||||
dimstyle-dimension-linetype = Lijntype maatlijn
|
||||
dimstyle-dimension-lineweight = Lijndikte maatlijn
|
||||
dimstyle-display-alternate-units = Alternatieve eenheden weergeven
|
||||
dimstyle-draw-dimension-line-between-extension-lines = Maatlijn tussen hulplijnen tekenen
|
||||
dimstyle-extend-beyond-dimension-line = Voorbij maatlijn verlengen
|
||||
dimstyle-extend-beyond-ticks = Voorbij schuine streepjes verlengen
|
||||
dimstyle-extension-line-color = Kleur hulplijn
|
||||
dimstyle-extension-lineweight = Lijndikte hulplijn
|
||||
dimstyle-feet-and-inches = Voet en inch
|
||||
dimstyle-fine-tuning = Fijnafstelling
|
||||
dimstyle-first-arrowhead = Eerste pijlpunt
|
||||
dimstyle-first-extension-linetype = Lijntype eerste hulplijn
|
||||
dimstyle-fit-options = Inpasopties
|
||||
dimstyle-fixed-length = Vaste lengte
|
||||
dimstyle-fraction-format = Breuknotatie
|
||||
dimstyle-height-scale = Hoogteschaal
|
||||
dimstyle-horizontal-placement = Horizontale plaatsing
|
||||
dimstyle-keep-text-horizontal-inside = Tekst binnen horizontaal houden
|
||||
dimstyle-keep-text-horizontal-outside = Tekst buiten horizontaal houden
|
||||
dimstyle-leader-arrowhead = Pijlpunt van verwijslijn
|
||||
dimstyle-limits = Grenswaarden
|
||||
dimstyle-linear-dimensions = Lineaire maten
|
||||
dimstyle-lower-value = Onderwaarde
|
||||
dimstyle-measurement-scale = Meetschaal
|
||||
dimstyle-measurement-template = Meetwaardesjabloon
|
||||
dimstyle-method = Methode
|
||||
dimstyle-multiplier = Vermenigvuldigingsfactor
|
||||
dimstyle-no-differences = Geen verschillen
|
||||
dimstyle-not-applicable = Niet van toepassing
|
||||
dimstyle-offset-from-measured-point = Afstand vanaf meetpunt
|
||||
dimstyle-place-text-manually = Tekst handmatig plaatsen tijdens het bematen
|
||||
dimstyle-radius-jog-angle = Hoek van radiusknik (°)
|
||||
dimstyle-read-left-to-right = Van links naar rechts lezen
|
||||
dimstyle-referenced-read-only = Gerefereerde stijl · Alleen-lezen
|
||||
dimstyle-round-off = Afronding
|
||||
dimstyle-second-arrowhead = Tweede pijlpunt
|
||||
dimstyle-second-extension-linetype = Lijntype tweede hulplijn
|
||||
dimstyle-show-zero-feet-and-inches = Nul voet en nul inch weergeven
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = Nul voet weergeven; nul inch onderdrukken
|
||||
dimstyle-suppress-arrows-when-no-fit = Pijlen onderdrukken als ze niet passen
|
||||
dimstyle-suppress-first-dimension-line = Eerste maatlijn onderdrukken
|
||||
dimstyle-suppress-first-extension-line = Eerste hulplijn onderdrukken
|
||||
dimstyle-suppress-second-dimension-line = Tweede maatlijn onderdrukken
|
||||
dimstyle-suppress-second-extension-line = Tweede hulplijn onderdrukken
|
||||
dimstyle-suppress-zero-feet-and-inches = Nul voet en nul inch onderdrukken
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = Nul voet onderdrukken; nul inch weergeven
|
||||
dimstyle-symbols-and-arrows = Symbolen en pijlen
|
||||
dimstyle-symmetrical = Symmetrisch
|
||||
dimstyle-text-background = Tekstachtergrond
|
||||
dimstyle-text-gap = Tekstafstand
|
||||
dimstyle-fixed-text-height-note = De gekozen tekststijl legt de hoogte vast op __ocs_arg_height__.
|
||||
dimstyle-tick-size = Grootte schuine streep
|
||||
dimstyle-tolerance-zero-suppression = Nulonderdrukking tolerantie
|
||||
dimstyle-unit-format = Eenheidsnotatie
|
||||
dimstyle-upper-value = Bovenwaarde
|
||||
dimstyle-measurement-template-help = Gebruik <> voor de meetwaarde; tekst ervoor en erna wordt het voor- en achtervoegsel.
|
||||
dimstyle-use-different-arrowheads = Verschillende eerste en tweede pijlpunten gebruiken
|
||||
dimstyle-use-fixed-length-extension-lines = Hulplijnen met vaste lengte gebruiken
|
||||
dimstyle-used-in-drawing = Gebruikt in tekening
|
||||
dimstyle-vertical-offset = Verticale afstand
|
||||
dimstyle-vertical-placement = Verticale plaatsing
|
||||
dimstyle-vertical-position = Verticale positie
|
||||
dimstyle-when-space-is-limited = Wanneer de ruimte beperkt is
|
||||
dimstyle-when-text-is-moved = Wanneer tekst wordt verplaatst
|
||||
dimstyle-zero-suppression = Nulonderdrukking
|
||||
dimstyle-add-a-leader = Verwijslijn toevoegen
|
||||
dimstyle-automatic = Automatisch
|
||||
dimstyle-by-block = Per blok
|
||||
dimstyle-comma = Komma
|
||||
dimstyle-degrees-minutes-seconds = Graden, minuten, seconden
|
||||
dimstyle-keep-dimension-line-with-text = Maatlijn met tekst meeverplaatsen
|
||||
dimstyle-leading-and-trailing = Voorloop- en eindnullen
|
||||
dimstyle-move-arrows-outside-first = Eerst pijlen naar buiten verplaatsen
|
||||
dimstyle-move-text-and-arrows-outside = Tekst en pijlen naar buiten verplaatsen
|
||||
dimstyle-move-text-freely = Tekst vrij verplaatsen
|
||||
dimstyle-move-text-outside-first = Eerst tekst naar buiten verplaatsen
|
||||
dimstyle-period = Punt
|
||||
dimstyle-space = Spatie
|
||||
style-manager-alignment-spacing = Uitlijningsafstand
|
||||
style-manager-always-left-align = Altijd links uitlijnen
|
||||
style-manager-attachment-direction = Aanhechtingsrichting
|
||||
style-manager-background-fill-enabled = Achtergrondvulling ingeschakeld
|
||||
style-manager-big-font = Groot lettertype
|
||||
style-manager-block-scale-x = Blokschaal X
|
||||
style-manager-block-scale-y = Blokschaal Y
|
||||
style-manager-block-scale-z = Blokschaal Z
|
||||
style-manager-borders = Randen
|
||||
style-manager-bottom-attachment = Onderste aanhechting
|
||||
style-manager-break-gap-size = Grootte van onderbrekingsruimte
|
||||
style-manager-caps-and-fill = Eindkappen en vulling
|
||||
style-manager-content-type = Inhoudstype
|
||||
style-manager-data-row = Gegevensrij
|
||||
style-manager-data-type = Gegevenstype
|
||||
style-manager-default-text = Standaardtekst
|
||||
style-manager-different = Verschillend
|
||||
style-manager-display-joints = Verbindingen weergeven
|
||||
style-manager-drawing-height = Tekeninghoogte
|
||||
style-manager-drawing-scale = Tekenschaal
|
||||
style-manager-effects = Effecten
|
||||
style-manager-elements = Elementen
|
||||
style-manager-end-caps = Eindkappen
|
||||
style-manager-fill-and-joints = Vulling en verbindingen
|
||||
style-manager-fill-enabled = Vulling ingeschakeld
|
||||
style-manager-first-segment-angle = Hoek van eerste segment
|
||||
style-manager-fixed-height = Vaste hoogte
|
||||
style-manager-flow-direction = Leesrichting
|
||||
style-manager-font-file = Lettertypebestand
|
||||
style-manager-fonts = Lettertypen
|
||||
style-manager-format-string = Opmaakreeks
|
||||
style-manager-header = Kolomkop
|
||||
style-manager-header-row = Kolomkoprij
|
||||
style-manager-horizontal-margin = Horizontale marge
|
||||
style-manager-inner-arcs = Binnenbogen
|
||||
style-manager-inside-horizontal = Horizontaal binnen
|
||||
style-manager-inside-vertical = Verticaal binnen
|
||||
style-manager-leader-draw-order = Tekenvolgorde van verwijslijn
|
||||
style-manager-leader-note = Verwijslijnnotitie
|
||||
style-manager-left-attachment = Linker aanhechting
|
||||
style-manager-line-color = Lijnkleur
|
||||
style-manager-line-type = Lijntype
|
||||
style-manager-line-weight = Lijndikte
|
||||
style-manager-maximum-leader-points = Maximumaantal verwijslijnpunten
|
||||
style-manager-multileader-draw-order = Tekenvolgorde van multiverwijslijn
|
||||
style-manager-no-preview = Geen voorbeeld
|
||||
style-manager-oblique-angle = Schuintehoek
|
||||
style-manager-outer-arc = Buitenboog
|
||||
style-manager-paper-height = Papierhoogte
|
||||
style-manager-paper-text-height = Teksthoogte op papier
|
||||
style-manager-path-type = Padtype
|
||||
style-manager-right-attachment = Rechter aanhechting
|
||||
style-manager-scale-factor = Schaalfactor
|
||||
style-manager-second-segment-angle = Hoek van tweede segment
|
||||
style-manager-size-and-effects = Grootte en effecten
|
||||
style-manager-start-caps = Startkappen
|
||||
style-manager-stroke-fonts = Lijnlettertypen
|
||||
style-manager-suppress-header-row = Kolomkoprij verbergen
|
||||
style-manager-suppress-title-row = Titelrij verbergen
|
||||
style-manager-system-font = Systeemlettertype
|
||||
style-manager-system-fonts = Systeemlettertypen
|
||||
style-manager-text-alignment = Tekstuitlijning
|
||||
style-manager-text-angle = Teksthoek
|
||||
style-manager-title-row = Titelrij
|
||||
style-manager-top-attachment = Bovenste aanhechting
|
||||
style-manager-unit-type = Eenheidstype
|
||||
style-manager-vertical-margin = Verticale marge
|
||||
style-manager-font-family-placeholder = lettertypefamilie…
|
||||
style-manager-bottom-to-top = Van onder naar boven
|
||||
style-manager-arrowhead-first = Pijlpunt eerst
|
||||
style-manager-content-first = Inhoud eerst
|
||||
style-manager-leader-first = Verwijslijn eerst
|
||||
style-manager-straight = Recht
|
||||
style-manager-parallel-last-segment = Evenwijdig aan laatste segment
|
||||
style-manager-top-of-top-line = Bovenkant van bovenste regel
|
||||
style-manager-middle-of-top-line = Midden van bovenste regel
|
||||
style-manager-middle-of-text = Midden van tekst
|
||||
style-manager-middle-of-bottom-line = Midden van onderste regel
|
||||
style-manager-bottom-of-bottom-line = Onderkant van onderste regel
|
||||
style-manager-bottom-line = Onderste regel
|
||||
style-manager-underline-bottom-line = Onderste regel onderstrepen
|
||||
style-manager-underline-top-line = Bovenste regel onderstrepen
|
||||
style-manager-underline-all-text = Alle tekst onderstrepen
|
||||
style-manager-center-of-text = Tekstmiddelpunt
|
||||
style-manager-center-of-text-overline = Tekstmiddelpunt met bovenstreep
|
||||
style-manager-block-extents = Blokgrenzen
|
||||
style-manager-base-point = Basispunt
|
||||
|
|
|
|||
|
|
@ -3198,3 +3198,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── Сочетания __ocs_arg_MOD__ ─
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── Пользовательские переопределения (SHORTCUTS SET) ─
|
||||
catalog-function-keys-b5a2df24e9 = ── Функциональные клавиши ─────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── Прочие клавиши ─────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = Всегда размещать текст между выносными линиями
|
||||
dimstyle-angular-dimensions = Угловые размеры
|
||||
dimstyle-arc-length-symbol = Символ длины дуги
|
||||
dimstyle-arrowheads = Стрелки
|
||||
dimstyle-available-style = Доступный стиль
|
||||
dimstyle-baseline-spacing = Шаг базовых размеров
|
||||
dimstyle-basic = Теоретически точный
|
||||
dimstyle-both-arrowheads = Обе стрелки
|
||||
dimstyle-center-mark = Маркер центра
|
||||
dimstyle-center-mark-size = Размер маркера центра
|
||||
dimstyle-center-marks = Маркеры центра
|
||||
dimstyle-centerlines = Осевые линии
|
||||
dimstyle-compare-with = Сравнить с
|
||||
dimstyle-current-style = Текущий стиль
|
||||
dimstyle-deviation = Отклонения
|
||||
dimstyle-different-sections = Различающиеся разделы
|
||||
dimstyle-dimension-line-color = Цвет размерной линии
|
||||
dimstyle-dimension-linetype = Тип размерной линии
|
||||
dimstyle-dimension-lineweight = Вес размерной линии
|
||||
dimstyle-display-alternate-units = Показывать альтернативные единицы
|
||||
dimstyle-draw-dimension-line-between-extension-lines = Рисовать размерную линию между выносными
|
||||
dimstyle-extend-beyond-dimension-line = Выступ за размерную линию
|
||||
dimstyle-extend-beyond-ticks = Выступ за засечки
|
||||
dimstyle-extension-line-color = Цвет выносной линии
|
||||
dimstyle-extension-lineweight = Вес выносной линии
|
||||
dimstyle-feet-and-inches = Футы и дюймы
|
||||
dimstyle-fine-tuning = Точная настройка
|
||||
dimstyle-first-arrowhead = Первая стрелка
|
||||
dimstyle-first-extension-linetype = Тип первой выносной линии
|
||||
dimstyle-fit-options = Параметры размещения
|
||||
dimstyle-fixed-length = Фиксированная длина
|
||||
dimstyle-fraction-format = Формат дробей
|
||||
dimstyle-height-scale = Масштаб высоты
|
||||
dimstyle-horizontal-placement = Размещение по горизонтали
|
||||
dimstyle-keep-text-horizontal-inside = Сохранять текст горизонтальным внутри
|
||||
dimstyle-keep-text-horizontal-outside = Сохранять текст горизонтальным снаружи
|
||||
dimstyle-leader-arrowhead = Стрелка выноски
|
||||
dimstyle-limits = Предельные значения
|
||||
dimstyle-linear-dimensions = Линейные размеры
|
||||
dimstyle-lower-value = Нижнее значение
|
||||
dimstyle-measurement-scale = Масштаб измерения
|
||||
dimstyle-measurement-template = Шаблон значения
|
||||
dimstyle-method = Способ
|
||||
dimstyle-multiplier = Множитель
|
||||
dimstyle-no-differences = Различий нет
|
||||
dimstyle-not-applicable = Неприменимо
|
||||
dimstyle-offset-from-measured-point = Отступ от измеряемой точки
|
||||
dimstyle-place-text-manually = Размещать текст вручную при создании размера
|
||||
dimstyle-radius-jog-angle = Угол излома радиуса (°)
|
||||
dimstyle-read-left-to-right = Читать слева направо
|
||||
dimstyle-referenced-read-only = Ссылочный стиль · Только чтение
|
||||
dimstyle-round-off = Округление
|
||||
dimstyle-second-arrowhead = Вторая стрелка
|
||||
dimstyle-second-extension-linetype = Тип второй выносной линии
|
||||
dimstyle-show-zero-feet-and-inches = Показывать нулевые футы и дюймы
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = Показывать нулевые футы; подавлять нулевые дюймы
|
||||
dimstyle-suppress-arrows-when-no-fit = Подавлять стрелки, если они не помещаются
|
||||
dimstyle-suppress-first-dimension-line = Подавлять первую размерную линию
|
||||
dimstyle-suppress-first-extension-line = Подавлять первую выносную линию
|
||||
dimstyle-suppress-second-dimension-line = Подавлять вторую размерную линию
|
||||
dimstyle-suppress-second-extension-line = Подавлять вторую выносную линию
|
||||
dimstyle-suppress-zero-feet-and-inches = Подавлять нулевые футы и дюймы
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = Подавлять нулевые футы; показывать нулевые дюймы
|
||||
dimstyle-symbols-and-arrows = Символы и стрелки
|
||||
dimstyle-symmetrical = Симметрично
|
||||
dimstyle-text-background = Фон текста
|
||||
dimstyle-text-gap = Отступ текста
|
||||
dimstyle-fixed-text-height-note = Выбранный стиль текста фиксирует высоту: __ocs_arg_height__.
|
||||
dimstyle-tick-size = Размер засечек
|
||||
dimstyle-tolerance-zero-suppression = Подавление нулей допуска
|
||||
dimstyle-unit-format = Формат единиц
|
||||
dimstyle-upper-value = Верхнее значение
|
||||
dimstyle-measurement-template-help = Используйте <> для измеренного значения; текст до и после него станет префиксом и суффиксом.
|
||||
dimstyle-use-different-arrowheads = Использовать разные первую и вторую стрелки
|
||||
dimstyle-use-fixed-length-extension-lines = Использовать выносные линии фиксированной длины
|
||||
dimstyle-used-in-drawing = Используется в чертеже
|
||||
dimstyle-vertical-offset = Вертикальный отступ
|
||||
dimstyle-vertical-placement = Размещение по вертикали
|
||||
dimstyle-vertical-position = Положение по вертикали
|
||||
dimstyle-when-space-is-limited = При недостатке места
|
||||
dimstyle-when-text-is-moved = При перемещении текста
|
||||
dimstyle-zero-suppression = Подавление нулей
|
||||
dimstyle-add-a-leader = Добавить выноску
|
||||
dimstyle-automatic = Автоматически
|
||||
dimstyle-by-block = По блоку
|
||||
dimstyle-comma = Запятая
|
||||
dimstyle-degrees-minutes-seconds = Градусы, минуты, секунды
|
||||
dimstyle-keep-dimension-line-with-text = Перемещать размерную линию вместе с текстом
|
||||
dimstyle-leading-and-trailing = Ведущие и конечные
|
||||
dimstyle-move-arrows-outside-first = Сначала вынести стрелки
|
||||
dimstyle-move-text-and-arrows-outside = Вынести текст и стрелки
|
||||
dimstyle-move-text-freely = Свободно перемещать текст
|
||||
dimstyle-move-text-outside-first = Сначала вынести текст
|
||||
dimstyle-period = Точка
|
||||
dimstyle-space = Пробел
|
||||
style-manager-alignment-spacing = Интервал выравнивания
|
||||
style-manager-always-left-align = Всегда выравнивать по левому краю
|
||||
style-manager-attachment-direction = Направление присоединения
|
||||
style-manager-background-fill-enabled = Фоновая заливка включена
|
||||
style-manager-big-font = Большой шрифт
|
||||
style-manager-block-scale-x = Масштаб блока X
|
||||
style-manager-block-scale-y = Масштаб блока Y
|
||||
style-manager-block-scale-z = Масштаб блока Z
|
||||
style-manager-borders = Границы
|
||||
style-manager-bottom-attachment = Нижнее присоединение
|
||||
style-manager-break-gap-size = Размер зазора разрыва
|
||||
style-manager-caps-and-fill = Торцы и заливка
|
||||
style-manager-content-type = Тип содержимого
|
||||
style-manager-data-row = Строка данных
|
||||
style-manager-data-type = Тип данных
|
||||
style-manager-default-text = Текст по умолчанию
|
||||
style-manager-different = Отличается
|
||||
style-manager-display-joints = Показывать стыки
|
||||
style-manager-drawing-height = Высота в чертеже
|
||||
style-manager-drawing-scale = Масштаб чертежа
|
||||
style-manager-effects = Эффекты
|
||||
style-manager-elements = Элементы
|
||||
style-manager-end-caps = Конечные торцы
|
||||
style-manager-fill-and-joints = Заливка и стыки
|
||||
style-manager-fill-enabled = Заливка включена
|
||||
style-manager-first-segment-angle = Угол первого сегмента
|
||||
style-manager-fixed-height = Фиксированная высота
|
||||
style-manager-flow-direction = Направление заполнения
|
||||
style-manager-font-file = Файл шрифта
|
||||
style-manager-fonts = Шрифты
|
||||
style-manager-format-string = Строка формата
|
||||
style-manager-header = Заголовок столбцов
|
||||
style-manager-header-row = Строка заголовков
|
||||
style-manager-horizontal-margin = Горизонтальное поле
|
||||
style-manager-inner-arcs = Внутренние дуги
|
||||
style-manager-inside-horizontal = Внутренняя горизонтальная
|
||||
style-manager-inside-vertical = Внутренняя вертикальная
|
||||
style-manager-leader-draw-order = Порядок отрисовки выноски
|
||||
style-manager-leader-note = Примечание выноски
|
||||
style-manager-left-attachment = Левое присоединение
|
||||
style-manager-line-color = Цвет линии
|
||||
style-manager-line-type = Тип линии
|
||||
style-manager-line-weight = Вес линии
|
||||
style-manager-maximum-leader-points = Максимум точек выноски
|
||||
style-manager-multileader-draw-order = Порядок отрисовки мультивыноски
|
||||
style-manager-no-preview = Нет предпросмотра
|
||||
style-manager-oblique-angle = Угол наклона
|
||||
style-manager-outer-arc = Внешняя дуга
|
||||
style-manager-paper-height = Высота на бумаге
|
||||
style-manager-paper-text-height = Высота текста на бумаге
|
||||
style-manager-path-type = Тип траектории
|
||||
style-manager-right-attachment = Правое присоединение
|
||||
style-manager-scale-factor = Масштабный коэффициент
|
||||
style-manager-second-segment-angle = Угол второго сегмента
|
||||
style-manager-size-and-effects = Размер и эффекты
|
||||
style-manager-start-caps = Начальные торцы
|
||||
style-manager-stroke-fonts = Штриховые шрифты
|
||||
style-manager-suppress-header-row = Скрыть строку заголовков
|
||||
style-manager-suppress-title-row = Скрыть строку названия
|
||||
style-manager-system-font = Системный шрифт
|
||||
style-manager-system-fonts = Системные шрифты
|
||||
style-manager-text-alignment = Выравнивание текста
|
||||
style-manager-text-angle = Угол текста
|
||||
style-manager-title-row = Строка названия
|
||||
style-manager-top-attachment = Верхнее присоединение
|
||||
style-manager-unit-type = Тип единиц
|
||||
style-manager-vertical-margin = Вертикальное поле
|
||||
style-manager-font-family-placeholder = семейство шрифтов…
|
||||
style-manager-bottom-to-top = Снизу вверх
|
||||
style-manager-arrowhead-first = Сначала стрелка
|
||||
style-manager-content-first = Сначала содержимое
|
||||
style-manager-leader-first = Сначала выноска
|
||||
style-manager-straight = Прямая
|
||||
style-manager-parallel-last-segment = Параллельно последнему сегменту
|
||||
style-manager-top-of-top-line = Верх верхней строки
|
||||
style-manager-middle-of-top-line = Середина верхней строки
|
||||
style-manager-middle-of-text = Середина текста
|
||||
style-manager-middle-of-bottom-line = Середина нижней строки
|
||||
style-manager-bottom-of-bottom-line = Низ нижней строки
|
||||
style-manager-bottom-line = Нижняя строка
|
||||
style-manager-underline-bottom-line = Подчеркнуть нижнюю строку
|
||||
style-manager-underline-top-line = Подчеркнуть верхнюю строку
|
||||
style-manager-underline-all-text = Подчеркнуть весь текст
|
||||
style-manager-center-of-text = Центр текста
|
||||
style-manager-center-of-text-overline = Центр текста с надчёркиванием
|
||||
style-manager-block-extents = Габариты блока
|
||||
style-manager-base-point = Базовая точка
|
||||
|
|
|
|||
|
|
@ -3118,3 +3118,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── __ocs_arg_MOD__ Kısayolları ──
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── Özel Geçersiz Kılmalar (SHORTCUTS SET) ─────────────
|
||||
catalog-function-keys-b5a2df24e9 = ── İşlev Tuşları ───────────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── Diğer Tuşlar ────────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = Metni her zaman uzatma çizgileri arasında tut
|
||||
dimstyle-angular-dimensions = Açısal ölçüler
|
||||
dimstyle-arc-length-symbol = Yay uzunluğu simgesi
|
||||
dimstyle-arrowheads = Ok uçları
|
||||
dimstyle-available-style = Kullanılabilir stil
|
||||
dimstyle-baseline-spacing = Taban çizgisi aralığı
|
||||
dimstyle-basic = Temel
|
||||
dimstyle-both-arrowheads = Her iki ok ucu
|
||||
dimstyle-center-mark = Merkez işareti
|
||||
dimstyle-center-mark-size = Merkez işareti boyutu
|
||||
dimstyle-center-marks = Merkez işaretleri
|
||||
dimstyle-centerlines = Merkez çizgileri
|
||||
dimstyle-compare-with = Karşılaştır
|
||||
dimstyle-current-style = Geçerli stil
|
||||
dimstyle-deviation = Sapma
|
||||
dimstyle-different-sections = Farklı bölümler
|
||||
dimstyle-dimension-line-color = Ölçü çizgisi rengi
|
||||
dimstyle-dimension-linetype = Ölçü çizgisi türü
|
||||
dimstyle-dimension-lineweight = Ölçü çizgisi kalınlığı
|
||||
dimstyle-display-alternate-units = Alternatif birimleri göster
|
||||
dimstyle-draw-dimension-line-between-extension-lines = Uzatma çizgileri arasına ölçü çizgisi çiz
|
||||
dimstyle-extend-beyond-dimension-line = Ölçü çizgisini aşma
|
||||
dimstyle-extend-beyond-ticks = İşaretleri aşma
|
||||
dimstyle-extension-line-color = Uzatma çizgisi rengi
|
||||
dimstyle-extension-lineweight = Uzatma çizgisi kalınlığı
|
||||
dimstyle-feet-and-inches = Fit ve inç
|
||||
dimstyle-fine-tuning = İnce ayar
|
||||
dimstyle-first-arrowhead = Birinci ok ucu
|
||||
dimstyle-first-extension-linetype = Birinci uzatma çizgisi türü
|
||||
dimstyle-fit-options = Sığdırma seçenekleri
|
||||
dimstyle-fixed-length = Sabit uzunluk
|
||||
dimstyle-fraction-format = Kesir biçimi
|
||||
dimstyle-height-scale = Yükseklik ölçeği
|
||||
dimstyle-horizontal-placement = Yatay yerleşim
|
||||
dimstyle-keep-text-horizontal-inside = İçerideyken metni yatay tut
|
||||
dimstyle-keep-text-horizontal-outside = Dışarıdayken metni yatay tut
|
||||
dimstyle-leader-arrowhead = Kılavuz ok ucu
|
||||
dimstyle-limits = Sınırlar
|
||||
dimstyle-linear-dimensions = Doğrusal ölçüler
|
||||
dimstyle-lower-value = Alt değer
|
||||
dimstyle-measurement-scale = Ölçüm ölçeği
|
||||
dimstyle-measurement-template = Ölçüm şablonu
|
||||
dimstyle-method = Yöntem
|
||||
dimstyle-multiplier = Çarpan
|
||||
dimstyle-no-differences = Fark yok
|
||||
dimstyle-not-applicable = Uygulanamaz
|
||||
dimstyle-offset-from-measured-point = Ölçülen noktadan uzaklık
|
||||
dimstyle-place-text-manually = Ölçü oluştururken metni elle yerleştir
|
||||
dimstyle-radius-jog-angle = Yarıçap kırılma açısı (°)
|
||||
dimstyle-read-left-to-right = Soldan sağa oku
|
||||
dimstyle-referenced-read-only = Başvurulan stil · Salt okunur
|
||||
dimstyle-round-off = Yuvarlama
|
||||
dimstyle-second-arrowhead = İkinci ok ucu
|
||||
dimstyle-second-extension-linetype = İkinci uzatma çizgisi türü
|
||||
dimstyle-show-zero-feet-and-inches = Sıfır fit ve sıfır inçi göster
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = Sıfır fiti göster; sıfır inçi gizle
|
||||
dimstyle-suppress-arrows-when-no-fit = Sığmadığında okları gizle
|
||||
dimstyle-suppress-first-dimension-line = Birinci ölçü çizgisini gizle
|
||||
dimstyle-suppress-first-extension-line = Birinci uzatma çizgisini gizle
|
||||
dimstyle-suppress-second-dimension-line = İkinci ölçü çizgisini gizle
|
||||
dimstyle-suppress-second-extension-line = İkinci uzatma çizgisini gizle
|
||||
dimstyle-suppress-zero-feet-and-inches = Sıfır fit ve sıfır inçi gizle
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = Sıfır fiti gizle; sıfır inçi göster
|
||||
dimstyle-symbols-and-arrows = Simgeler ve Oklar
|
||||
dimstyle-symmetrical = Simetrik
|
||||
dimstyle-text-background = Metin arka planı
|
||||
dimstyle-text-gap = Metin boşluğu
|
||||
dimstyle-fixed-text-height-note = Seçili metin stili yüksekliği __ocs_arg_height__ olarak sabitler.
|
||||
dimstyle-tick-size = İşaret boyutu
|
||||
dimstyle-tolerance-zero-suppression = Tolerans sıfırlarını gizleme
|
||||
dimstyle-unit-format = Birim biçimi
|
||||
dimstyle-upper-value = Üst değer
|
||||
dimstyle-measurement-template-help = Ölçülen değer için <> kullanın; önündeki ve arkasındaki metin, ön ek ve son ek olur.
|
||||
dimstyle-use-different-arrowheads = Birinci ve ikinci ok uçlarını farklı kullan
|
||||
dimstyle-use-fixed-length-extension-lines = Sabit uzunlukta uzatma çizgileri kullan
|
||||
dimstyle-used-in-drawing = Çizimde kullanılıyor
|
||||
dimstyle-vertical-offset = Dikey uzaklık
|
||||
dimstyle-vertical-placement = Dikey yerleşim
|
||||
dimstyle-vertical-position = Dikey konum
|
||||
dimstyle-when-space-is-limited = Alan yetersiz olduğunda
|
||||
dimstyle-when-text-is-moved = Metin taşındığında
|
||||
dimstyle-zero-suppression = Sıfırları gizleme
|
||||
dimstyle-add-a-leader = Kılavuz ekle
|
||||
dimstyle-automatic = Otomatik
|
||||
dimstyle-by-block = Bloğa göre
|
||||
dimstyle-comma = Virgül
|
||||
dimstyle-degrees-minutes-seconds = Derece, dakika, saniye
|
||||
dimstyle-keep-dimension-line-with-text = Ölçü çizgisini metinle birlikte taşı
|
||||
dimstyle-leading-and-trailing = Baştaki ve sondaki
|
||||
dimstyle-move-arrows-outside-first = Önce okları dışarı taşı
|
||||
dimstyle-move-text-and-arrows-outside = Metni ve okları dışarı taşı
|
||||
dimstyle-move-text-freely = Metni serbestçe taşı
|
||||
dimstyle-move-text-outside-first = Önce metni dışarı taşı
|
||||
dimstyle-period = Nokta
|
||||
dimstyle-space = Boşluk
|
||||
style-manager-alignment-spacing = Hizalama aralığı
|
||||
style-manager-always-left-align = Her zaman sola hizala
|
||||
style-manager-attachment-direction = Bağlantı yönü
|
||||
style-manager-background-fill-enabled = Arka plan dolgusu etkin
|
||||
style-manager-big-font = Büyük yazı tipi
|
||||
style-manager-block-scale-x = Blok X ölçeği
|
||||
style-manager-block-scale-y = Blok Y ölçeği
|
||||
style-manager-block-scale-z = Blok Z ölçeği
|
||||
style-manager-borders = Kenarlar
|
||||
style-manager-bottom-attachment = Alt bağlantı
|
||||
style-manager-break-gap-size = Kesinti boşluğu boyutu
|
||||
style-manager-caps-and-fill = Kapaklar ve Dolgu
|
||||
style-manager-content-type = İçerik türü
|
||||
style-manager-data-row = Veri Satırı
|
||||
style-manager-data-type = Veri türü
|
||||
style-manager-default-text = Varsayılan metin
|
||||
style-manager-different = Farklı
|
||||
style-manager-display-joints = Birleşimleri göster
|
||||
style-manager-drawing-height = Çizim yüksekliği
|
||||
style-manager-drawing-scale = Çizim ölçeği
|
||||
style-manager-effects = Etkiler
|
||||
style-manager-elements = Elemanlar
|
||||
style-manager-end-caps = Bitiş kapakları
|
||||
style-manager-fill-and-joints = Dolgu ve birleşimler
|
||||
style-manager-fill-enabled = Dolgu etkin
|
||||
style-manager-first-segment-angle = Birinci segment açısı
|
||||
style-manager-fixed-height = Sabit yükseklik
|
||||
style-manager-flow-direction = Akış yönü
|
||||
style-manager-font-file = Yazı tipi dosyası
|
||||
style-manager-fonts = Yazı tipleri
|
||||
style-manager-format-string = Biçim dizgesi
|
||||
style-manager-header = Sütun başlığı
|
||||
style-manager-header-row = Sütun Başlığı Satırı
|
||||
style-manager-horizontal-margin = Yatay kenar boşluğu
|
||||
style-manager-inner-arcs = İç yaylar
|
||||
style-manager-inside-horizontal = Yatay iç kenar
|
||||
style-manager-inside-vertical = Dikey iç kenar
|
||||
style-manager-leader-draw-order = Lider çizim sırası
|
||||
style-manager-leader-note = Lider notu
|
||||
style-manager-left-attachment = Sol bağlantı
|
||||
style-manager-line-color = Çizgi rengi
|
||||
style-manager-line-type = Çizgi türü
|
||||
style-manager-line-weight = Çizgi kalınlığı
|
||||
style-manager-maximum-leader-points = En fazla lider noktası
|
||||
style-manager-multileader-draw-order = Çoklu lider çizim sırası
|
||||
style-manager-no-preview = Önizleme yok
|
||||
style-manager-oblique-angle = Eğiklik açısı
|
||||
style-manager-outer-arc = Dış yay
|
||||
style-manager-paper-height = Kağıt yüksekliği
|
||||
style-manager-paper-text-height = Kağıt metin yüksekliği
|
||||
style-manager-path-type = Yol türü
|
||||
style-manager-right-attachment = Sağ bağlantı
|
||||
style-manager-scale-factor = Ölçek çarpanı
|
||||
style-manager-second-segment-angle = İkinci segment açısı
|
||||
style-manager-size-and-effects = Boyut ve Etkiler
|
||||
style-manager-start-caps = Başlangıç kapakları
|
||||
style-manager-stroke-fonts = Çizgi yazı tipleri
|
||||
style-manager-suppress-header-row = Sütun başlığı satırını gizle
|
||||
style-manager-suppress-title-row = Tablo başlığı satırını gizle
|
||||
style-manager-system-font = Sistem yazı tipi
|
||||
style-manager-system-fonts = Sistem yazı tipleri
|
||||
style-manager-text-alignment = Metin hizalaması
|
||||
style-manager-text-angle = Metin açısı
|
||||
style-manager-title-row = Tablo Başlığı Satırı
|
||||
style-manager-top-attachment = Üst bağlantı
|
||||
style-manager-unit-type = Birim türü
|
||||
style-manager-vertical-margin = Dikey kenar boşluğu
|
||||
style-manager-font-family-placeholder = yazı tipi ailesi…
|
||||
style-manager-bottom-to-top = Aşağıdan yukarıya
|
||||
style-manager-arrowhead-first = Önce ok ucu
|
||||
style-manager-content-first = Önce içerik
|
||||
style-manager-leader-first = Önce lider
|
||||
style-manager-straight = Düz
|
||||
style-manager-parallel-last-segment = Son segmente paralel
|
||||
style-manager-top-of-top-line = Üst satırın üstü
|
||||
style-manager-middle-of-top-line = Üst satırın ortası
|
||||
style-manager-middle-of-text = Metnin ortası
|
||||
style-manager-middle-of-bottom-line = Alt satırın ortası
|
||||
style-manager-bottom-of-bottom-line = Alt satırın altı
|
||||
style-manager-bottom-line = Alt satır
|
||||
style-manager-underline-bottom-line = Alt satırın altını çiz
|
||||
style-manager-underline-top-line = Üst satırın altını çiz
|
||||
style-manager-underline-all-text = Tüm metnin altını çiz
|
||||
style-manager-center-of-text = Metnin merkezi
|
||||
style-manager-center-of-text-overline = Üst çizgili metin merkezi
|
||||
style-manager-block-extents = Blok sınırları
|
||||
style-manager-base-point = Taban noktası
|
||||
|
|
|
|||
|
|
@ -3180,3 +3180,185 @@ catalog-mod-shortcuts-4c54bbb78e = ── __ocs_arg_MOD__ 快捷键 ────
|
|||
catalog-custom-overrides-shortcuts-set-07be563dec = ── 自定义覆盖 (SHORTCUTS SET) ──────────────────
|
||||
catalog-function-keys-b5a2df24e9 = ── 功能键 ──────────────────────────────────────
|
||||
catalog-other-keys-a882812cf2 = ── 其他按键 ──────────────────────────────────────────
|
||||
dimstyle-keep-text-between-extension-lines = 始终将文字置于尺寸界线之间
|
||||
dimstyle-angular-dimensions = 角度标注
|
||||
dimstyle-arc-length-symbol = 弧长符号
|
||||
dimstyle-arrowheads = 箭头
|
||||
dimstyle-available-style = 可用样式
|
||||
dimstyle-baseline-spacing = 基线间距
|
||||
dimstyle-basic = 基本尺寸
|
||||
dimstyle-both-arrowheads = 两端箭头
|
||||
dimstyle-center-mark = 圆心标记
|
||||
dimstyle-center-mark-size = 圆心标记大小
|
||||
dimstyle-center-marks = 圆心标记
|
||||
dimstyle-centerlines = 中心线
|
||||
dimstyle-compare-with = 比较对象
|
||||
dimstyle-current-style = 当前样式
|
||||
dimstyle-deviation = 偏差
|
||||
dimstyle-different-sections = 存在差异的分区
|
||||
dimstyle-dimension-line-color = 尺寸线颜色
|
||||
dimstyle-dimension-linetype = 尺寸线线型
|
||||
dimstyle-dimension-lineweight = 尺寸线线宽
|
||||
dimstyle-display-alternate-units = 显示换算单位
|
||||
dimstyle-draw-dimension-line-between-extension-lines = 在尺寸界线之间绘制尺寸线
|
||||
dimstyle-extend-beyond-dimension-line = 超出尺寸线
|
||||
dimstyle-extend-beyond-ticks = 超出斜线
|
||||
dimstyle-extension-line-color = 尺寸界线颜色
|
||||
dimstyle-extension-lineweight = 尺寸界线线宽
|
||||
dimstyle-feet-and-inches = 英尺和英寸
|
||||
dimstyle-fine-tuning = 精细调整
|
||||
dimstyle-first-arrowhead = 第一个箭头
|
||||
dimstyle-first-extension-linetype = 第一条尺寸界线线型
|
||||
dimstyle-fit-options = 调整选项
|
||||
dimstyle-fixed-length = 固定长度
|
||||
dimstyle-fraction-format = 分数格式
|
||||
dimstyle-height-scale = 高度比例
|
||||
dimstyle-horizontal-placement = 水平位置
|
||||
dimstyle-keep-text-horizontal-inside = 位于内部时保持文字水平
|
||||
dimstyle-keep-text-horizontal-outside = 位于外部时保持文字水平
|
||||
dimstyle-leader-arrowhead = 引线箭头
|
||||
dimstyle-limits = 极限尺寸
|
||||
dimstyle-linear-dimensions = 线性标注
|
||||
dimstyle-lower-value = 下偏差
|
||||
dimstyle-measurement-scale = 测量比例
|
||||
dimstyle-measurement-template = 测量值模板
|
||||
dimstyle-method = 方式
|
||||
dimstyle-multiplier = 换算系数
|
||||
dimstyle-no-differences = 无差异
|
||||
dimstyle-not-applicable = 不适用
|
||||
dimstyle-offset-from-measured-point = 与测量点的偏移
|
||||
dimstyle-place-text-manually = 创建标注时手动放置文字
|
||||
dimstyle-radius-jog-angle = 半径折弯角度 (°)
|
||||
dimstyle-read-left-to-right = 从左向右阅读
|
||||
dimstyle-referenced-read-only = 参照样式 · 只读
|
||||
dimstyle-round-off = 舍入值
|
||||
dimstyle-second-arrowhead = 第二个箭头
|
||||
dimstyle-second-extension-linetype = 第二条尺寸界线线型
|
||||
dimstyle-show-zero-feet-and-inches = 显示零英尺和零英寸
|
||||
dimstyle-show-zero-feet-suppress-zero-inches = 显示零英尺;抑制零英寸
|
||||
dimstyle-suppress-arrows-when-no-fit = 箭头无法容纳时将其隐藏
|
||||
dimstyle-suppress-first-dimension-line = 隐藏第一条尺寸线
|
||||
dimstyle-suppress-first-extension-line = 隐藏第一条尺寸界线
|
||||
dimstyle-suppress-second-dimension-line = 隐藏第二条尺寸线
|
||||
dimstyle-suppress-second-extension-line = 隐藏第二条尺寸界线
|
||||
dimstyle-suppress-zero-feet-and-inches = 抑制零英尺和零英寸
|
||||
dimstyle-suppress-zero-feet-show-zero-inches = 抑制零英尺;显示零英寸
|
||||
dimstyle-symbols-and-arrows = 符号和箭头
|
||||
dimstyle-symmetrical = 对称
|
||||
dimstyle-text-background = 文字背景
|
||||
dimstyle-text-gap = 文字间距
|
||||
dimstyle-fixed-text-height-note = 所选文字样式将高度固定为 __ocs_arg_height__。
|
||||
dimstyle-tick-size = 斜线大小
|
||||
dimstyle-tolerance-zero-suppression = 公差零值抑制
|
||||
dimstyle-unit-format = 单位格式
|
||||
dimstyle-upper-value = 上偏差
|
||||
dimstyle-measurement-template-help = 使用 <> 表示测量值;其前后的文字将分别成为前缀和后缀。
|
||||
dimstyle-use-different-arrowheads = 两端使用不同箭头
|
||||
dimstyle-use-fixed-length-extension-lines = 使用固定长度的尺寸界线
|
||||
dimstyle-used-in-drawing = 已在图形中使用
|
||||
dimstyle-vertical-offset = 垂直偏移
|
||||
dimstyle-vertical-placement = 垂直位置
|
||||
dimstyle-vertical-position = 垂直定位
|
||||
dimstyle-when-space-is-limited = 空间不足时
|
||||
dimstyle-when-text-is-moved = 移动文字时
|
||||
dimstyle-zero-suppression = 零值抑制
|
||||
dimstyle-add-a-leader = 添加引线
|
||||
dimstyle-automatic = 自动
|
||||
dimstyle-by-block = 随块
|
||||
dimstyle-comma = 逗号
|
||||
dimstyle-degrees-minutes-seconds = 度、分、秒
|
||||
dimstyle-keep-dimension-line-with-text = 尺寸线随文字移动
|
||||
dimstyle-leading-and-trailing = 前导和后续
|
||||
dimstyle-move-arrows-outside-first = 优先将箭头移到外部
|
||||
dimstyle-move-text-and-arrows-outside = 将文字和箭头移到外部
|
||||
dimstyle-move-text-freely = 自由移动文字
|
||||
dimstyle-move-text-outside-first = 优先将文字移到外部
|
||||
dimstyle-period = 句点
|
||||
dimstyle-space = 空格
|
||||
style-manager-alignment-spacing = 对齐间距
|
||||
style-manager-always-left-align = 始终左对齐
|
||||
style-manager-attachment-direction = 附着方向
|
||||
style-manager-background-fill-enabled = 启用背景填充
|
||||
style-manager-big-font = 大字体
|
||||
style-manager-block-scale-x = 块 X 比例
|
||||
style-manager-block-scale-y = 块 Y 比例
|
||||
style-manager-block-scale-z = 块 Z 比例
|
||||
style-manager-borders = 边框
|
||||
style-manager-bottom-attachment = 底部附着
|
||||
style-manager-break-gap-size = 打断间隙大小
|
||||
style-manager-caps-and-fill = 端盖和填充
|
||||
style-manager-content-type = 内容类型
|
||||
style-manager-data-row = 数据行
|
||||
style-manager-data-type = 数据类型
|
||||
style-manager-default-text = 默认文字
|
||||
style-manager-different = 不同
|
||||
style-manager-display-joints = 显示接合处
|
||||
style-manager-drawing-height = 图形高度
|
||||
style-manager-drawing-scale = 图形比例
|
||||
style-manager-effects = 效果
|
||||
style-manager-elements = 元素
|
||||
style-manager-end-caps = 终点端盖
|
||||
style-manager-fill-and-joints = 填充和接合处
|
||||
style-manager-fill-enabled = 启用填充
|
||||
style-manager-first-segment-angle = 第一段角度
|
||||
style-manager-fixed-height = 固定高度
|
||||
style-manager-flow-direction = 排列方向
|
||||
style-manager-font-file = 字体文件
|
||||
style-manager-fonts = 字体
|
||||
style-manager-format-string = 格式字符串
|
||||
style-manager-header = 列标题
|
||||
style-manager-header-row = 列标题行
|
||||
style-manager-horizontal-margin = 水平边距
|
||||
style-manager-inner-arcs = 内弧
|
||||
style-manager-inside-horizontal = 内部水平
|
||||
style-manager-inside-vertical = 内部垂直
|
||||
style-manager-leader-draw-order = 引线绘制顺序
|
||||
style-manager-leader-note = 引线注释
|
||||
style-manager-left-attachment = 左侧附着
|
||||
style-manager-line-color = 线颜色
|
||||
style-manager-line-type = 线型
|
||||
style-manager-line-weight = 线宽
|
||||
style-manager-maximum-leader-points = 最大引线点数
|
||||
style-manager-multileader-draw-order = 多重引线绘制顺序
|
||||
style-manager-no-preview = 无预览
|
||||
style-manager-oblique-angle = 倾斜角
|
||||
style-manager-outer-arc = 外弧
|
||||
style-manager-paper-height = 图纸高度
|
||||
style-manager-paper-text-height = 图纸文字高度
|
||||
style-manager-path-type = 路径类型
|
||||
style-manager-right-attachment = 右侧附着
|
||||
style-manager-scale-factor = 比例因子
|
||||
style-manager-second-segment-angle = 第二段角度
|
||||
style-manager-size-and-effects = 大小和效果
|
||||
style-manager-start-caps = 起点端盖
|
||||
style-manager-stroke-fonts = 线性字体
|
||||
style-manager-suppress-header-row = 隐藏列标题行
|
||||
style-manager-suppress-title-row = 隐藏标题行
|
||||
style-manager-system-font = 系统字体
|
||||
style-manager-system-fonts = 系统字体
|
||||
style-manager-text-alignment = 文字对齐
|
||||
style-manager-text-angle = 文字角度
|
||||
style-manager-title-row = 标题行
|
||||
style-manager-top-attachment = 顶部附着
|
||||
style-manager-unit-type = 单位类型
|
||||
style-manager-vertical-margin = 垂直边距
|
||||
style-manager-font-family-placeholder = 字体族…
|
||||
style-manager-bottom-to-top = 从下到上
|
||||
style-manager-arrowhead-first = 先绘制箭头
|
||||
style-manager-content-first = 先绘制内容
|
||||
style-manager-leader-first = 先绘制引线
|
||||
style-manager-straight = 直线
|
||||
style-manager-parallel-last-segment = 平行于最后一段
|
||||
style-manager-top-of-top-line = 顶行顶部
|
||||
style-manager-middle-of-top-line = 顶行中部
|
||||
style-manager-middle-of-text = 文字中部
|
||||
style-manager-middle-of-bottom-line = 底行中部
|
||||
style-manager-bottom-of-bottom-line = 底行底部
|
||||
style-manager-bottom-line = 底行
|
||||
style-manager-underline-bottom-line = 底行下划线
|
||||
style-manager-underline-top-line = 顶行下划线
|
||||
style-manager-underline-all-text = 所有文字下划线
|
||||
style-manager-center-of-text = 文字中心
|
||||
style-manager-center-of-text-overline = 带上划线的文字中心
|
||||
style-manager-block-extents = 块范围
|
||||
style-manager-base-point = 基点
|
||||
|
|
|
|||
|
|
@ -670,9 +670,18 @@ pub(super) struct OpenCADStudio {
|
|||
|
||||
// ── MLineStyle Dialog ─────────────────────────────────────────────────
|
||||
mlstyle_selected: String,
|
||||
mlstyle_tab: u8,
|
||||
mlstyle_compare: String,
|
||||
mln_description: String,
|
||||
mln_start_angle: String,
|
||||
mln_end_angle: String,
|
||||
mln_fill_color: String,
|
||||
mln_elements: Vec<[String; 3]>,
|
||||
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────────
|
||||
mleaderstyle_selected: String,
|
||||
mleaderstyle_tab: u8,
|
||||
mleaderstyle_compare: String,
|
||||
/// Colour field whose expanded palette is open (line/text/block).
|
||||
mls_color_open: Option<&'static str>,
|
||||
mls_landing_distance: String,
|
||||
|
|
@ -697,6 +706,8 @@ pub(super) struct OpenCADStudio {
|
|||
|
||||
// ── TableStyle Dialog ─────────────────────────────────────────────────
|
||||
tablestyle_selected: String,
|
||||
tablestyle_tab: u8,
|
||||
tablestyle_compare: String,
|
||||
/// Edit buffers for the table style's general margins.
|
||||
ts_hmargin: String,
|
||||
ts_vmargin: String,
|
||||
|
|
@ -732,6 +743,8 @@ pub(super) struct OpenCADStudio {
|
|||
|
||||
// ── TextStyle Font Browser ────────────────────────────────────────────
|
||||
textstyle_selected: String,
|
||||
textstyle_tab: u8,
|
||||
textstyle_compare: String,
|
||||
/// Edit buffer for font file name.
|
||||
textstyle_font: String,
|
||||
/// Edit buffer for width factor.
|
||||
|
|
@ -868,8 +881,10 @@ pub(super) struct OpenCADStudio {
|
|||
dimstyle_selected: String,
|
||||
/// Which colour field currently has its expanded palette open (if any).
|
||||
ds_color_open: Option<DsField>,
|
||||
/// Active tab: 0=Lines, 1=Arrows, 2=Text, 3=Scale/Units, 4=Tolerances.
|
||||
/// Active property group in the dimension style manager.
|
||||
dimstyle_tab: u8,
|
||||
/// Style used by the manager's comparison summary.
|
||||
dimstyle_compare: String,
|
||||
// Edit buffers (strings while typing):
|
||||
ds_dimdle: String,
|
||||
ds_dimdli: String,
|
||||
|
|
@ -2438,6 +2453,8 @@ pub enum Message {
|
|||
#[allow(dead_code)]
|
||||
TextStyleDialogClose,
|
||||
TextStyleDialogSelect(String),
|
||||
TextStyleDialogTab(u8),
|
||||
TextStyleDialogCompare(String),
|
||||
TextStyleDialogSetCurrent,
|
||||
TextStyleDialogNew,
|
||||
TextStyleDialogCopy,
|
||||
|
|
@ -2465,6 +2482,8 @@ pub enum Message {
|
|||
#[allow(dead_code)]
|
||||
TableStyleDialogClose,
|
||||
TableStyleDialogSelect(String),
|
||||
TableStyleDialogTab(u8),
|
||||
TableStyleDialogCompare(String),
|
||||
TableStyleDialogNew,
|
||||
TableStyleDialogCopy,
|
||||
TableStyleDialogDelete,
|
||||
|
|
@ -2523,16 +2542,32 @@ pub enum Message {
|
|||
#[allow(dead_code)]
|
||||
MlStyleDialogClose,
|
||||
MlStyleDialogSelect(String),
|
||||
MlStyleDialogTab(u8),
|
||||
MlStyleDialogCompare(String),
|
||||
MlStyleDialogSetCurrent,
|
||||
MlStyleApply,
|
||||
MlStyleDialogNew,
|
||||
MlStyleDialogCopy,
|
||||
MlStyleDialogDelete,
|
||||
MlStyleEdit {
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
MlStyleToggle(&'static str),
|
||||
MlStyleElementEdit {
|
||||
index: usize,
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
MlStyleElementAdd,
|
||||
MlStyleElementDelete(usize),
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────────
|
||||
MLeaderStyleDialogOpen,
|
||||
#[allow(dead_code)]
|
||||
MLeaderStyleDialogClose,
|
||||
MLeaderStyleDialogSelect(String),
|
||||
MLeaderStyleDialogTab(u8),
|
||||
MLeaderStyleDialogCompare(String),
|
||||
MLeaderStyleDialogSetCurrent,
|
||||
MLeaderStyleDialogNew,
|
||||
MLeaderStyleDialogCopy,
|
||||
|
|
@ -2565,6 +2600,8 @@ pub enum Message {
|
|||
DimStyleDialogSelect(String),
|
||||
/// Switch the active tab.
|
||||
DimStyleDialogTab(u8),
|
||||
/// Change the style used by the comparison summary.
|
||||
DimStyleDialogCompare(String),
|
||||
/// Create a new empty style (prompts via command line).
|
||||
DimStyleDialogNew,
|
||||
DimStyleDialogCopy,
|
||||
|
|
@ -2575,6 +2612,14 @@ pub enum Message {
|
|||
// Field edit messages:
|
||||
DsEdit(DsField, String),
|
||||
DsToggle(DsField),
|
||||
/// Select the mutually-exclusive tolerance presentation.
|
||||
DsToleranceMode(String),
|
||||
/// Change the feet/inches mode in a zero-suppression bit field.
|
||||
DsZeroBase(DsField, i16),
|
||||
/// Toggle leading/trailing suppression in a zero-suppression bit field.
|
||||
DsZeroFlag(DsField, i16),
|
||||
/// Select no center mark, a mark, or centerlines.
|
||||
DsCenterMarkMode(String),
|
||||
/// Toggle the expanded colour palette for a DimStyle colour field.
|
||||
DsColorMore(DsField),
|
||||
/// Open the `iced_aw` colour picker for a field and its current colour.
|
||||
|
|
@ -2887,6 +2932,8 @@ impl OpenCADStudio {
|
|||
style_rename_buf: String::new(),
|
||||
style_stage: None,
|
||||
textstyle_selected: "Standard".to_string(),
|
||||
textstyle_tab: 0,
|
||||
textstyle_compare: String::new(),
|
||||
textstyle_font: String::new(),
|
||||
textstyle_width: "1.0".to_string(),
|
||||
textstyle_oblique: "0.0".to_string(),
|
||||
|
|
@ -2895,6 +2942,8 @@ impl OpenCADStudio {
|
|||
textstyle_ttf: String::new(),
|
||||
// TableStyle dialog
|
||||
tablestyle_selected: "Standard".to_string(),
|
||||
tablestyle_tab: 0,
|
||||
tablestyle_compare: String::new(),
|
||||
ts_hmargin: "1.5".to_string(),
|
||||
ts_vmargin: "1.5".to_string(),
|
||||
ts_description: String::new(),
|
||||
|
|
@ -2911,8 +2960,17 @@ impl OpenCADStudio {
|
|||
ts_border_spacing: Default::default(),
|
||||
// MLineStyle dialog
|
||||
mlstyle_selected: "Standard".to_string(),
|
||||
mlstyle_tab: 0,
|
||||
mlstyle_compare: String::new(),
|
||||
mln_description: String::new(),
|
||||
mln_start_angle: "90".to_string(),
|
||||
mln_end_angle: "90".to_string(),
|
||||
mln_fill_color: "256".to_string(),
|
||||
mln_elements: Vec::new(),
|
||||
// MLeaderStyle dialog
|
||||
mleaderstyle_selected: "Standard".to_string(),
|
||||
mleaderstyle_tab: 0,
|
||||
mleaderstyle_compare: String::new(),
|
||||
mls_color_open: None,
|
||||
mls_landing_distance: String::new(),
|
||||
mls_landing_gap: String::new(),
|
||||
|
|
@ -2937,6 +2995,7 @@ impl OpenCADStudio {
|
|||
dimstyle_selected: "Standard".to_string(),
|
||||
ds_color_open: None,
|
||||
dimstyle_tab: 0,
|
||||
dimstyle_compare: String::new(),
|
||||
ds_dimdle: "0".to_string(),
|
||||
ds_dimdli: "3.75".to_string(),
|
||||
ds_dimgap: "0.625".to_string(),
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
|
||||
fn style_in_use(&self, kind: StyleKind, name: &str) -> bool {
|
||||
pub(super) fn style_in_use(&self, kind: StyleKind, name: &str) -> bool {
|
||||
use acadrust::entities::EntityType;
|
||||
|
||||
let i = self.active_tab;
|
||||
|
|
@ -613,6 +613,20 @@ impl OpenCADStudio {
|
|||
|
||||
pub(super) fn style_delete(&mut self, kind: StyleKind) {
|
||||
let name = self.style_selected(kind);
|
||||
if matches!(kind, StyleKind::Dim)
|
||||
&& self.tabs[self.active_tab]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get(&name)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
})
|
||||
{
|
||||
self.command_line
|
||||
.push_error(crate::t!("Referenced styles are read only.").as_ref());
|
||||
return;
|
||||
}
|
||||
if name.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error(crate::t!("Cannot delete the Standard style.").as_ref());
|
||||
|
|
@ -657,6 +671,20 @@ impl OpenCADStudio {
|
|||
if new.is_empty() || new.eq_ignore_ascii_case(&old) {
|
||||
return;
|
||||
}
|
||||
if matches!(kind, StyleKind::Dim)
|
||||
&& self.tabs[self.active_tab]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get(&old)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
})
|
||||
{
|
||||
self.command_line
|
||||
.push_error(crate::t!("Referenced styles are read only.").as_ref());
|
||||
return;
|
||||
}
|
||||
if old.eq_ignore_ascii_case("Standard") {
|
||||
self.command_line
|
||||
.push_error(crate::t!("Cannot rename the Standard style.").as_ref());
|
||||
|
|
|
|||
|
|
@ -5408,11 +5408,25 @@ impl OpenCADStudio {
|
|||
self.load_textstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::TextStyleDialogTab(tab) => {
|
||||
self.textstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::TextStyleDialogCompare(name) => {
|
||||
self.textstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::TextStyleDialogSetCurrent => {
|
||||
// Staged: persists on Apply.
|
||||
let i = self.active_tab;
|
||||
let name = self.textstyle_selected.clone();
|
||||
if self.tabs[i].scene.document.text_styles.get(&name).is_some() {
|
||||
if self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.text_styles
|
||||
.get(&name)
|
||||
.is_some_and(|style| !style.xref_dependent)
|
||||
{
|
||||
self.tabs[i].scene.document.header.current_text_style_name = name.clone();
|
||||
self.sync_ribbon_styles();
|
||||
self.command_line
|
||||
|
|
@ -5468,9 +5482,13 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
let name = self.textstyle_selected.clone();
|
||||
if let Some(s) = self.tabs[i].scene.document.text_styles.get_mut(&name) {
|
||||
if s.xref_dependent {
|
||||
return Task::none();
|
||||
}
|
||||
match field {
|
||||
"backward" => s.flags.backward = !s.flags.backward,
|
||||
"upside_down" => s.flags.upside_down = !s.flags.upside_down,
|
||||
"vertical" => s.is_vertical = !s.is_vertical,
|
||||
"annotative" => s.annotative = !s.annotative,
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -5481,8 +5499,17 @@ impl OpenCADStudio {
|
|||
Message::TextStyleFontPick(font_file) => {
|
||||
// Staged: update the buffer + live style; persist on Apply.
|
||||
let i = self.active_tab;
|
||||
self.textstyle_font = font_file.clone();
|
||||
let name = self.textstyle_selected.clone();
|
||||
if self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.text_styles
|
||||
.get(&name)
|
||||
.is_some_and(|style| style.xref_dependent)
|
||||
{
|
||||
return Task::none();
|
||||
}
|
||||
self.textstyle_font = font_file.clone();
|
||||
if let Some(s) = self.tabs[i].scene.document.text_styles.get_mut(&name) {
|
||||
s.font_file = font_file;
|
||||
}
|
||||
|
|
@ -5516,12 +5543,23 @@ impl OpenCADStudio {
|
|||
Task::none()
|
||||
}
|
||||
Message::TableStyleDialogSelect(name) => {
|
||||
for row in 0..3 {
|
||||
let _ = self.on_table_style_cell_apply(row);
|
||||
}
|
||||
self.stage_tablestyle_bufs();
|
||||
self.tablestyle_selected = name;
|
||||
let i = self.active_tab;
|
||||
self.load_tablestyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::TableStyleDialogTab(tab) => {
|
||||
self.tablestyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::TableStyleDialogCompare(name) => {
|
||||
self.tablestyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableStyleEdit { field, value } => {
|
||||
match field {
|
||||
|
|
@ -5534,6 +5572,9 @@ impl OpenCADStudio {
|
|||
}
|
||||
|
||||
Message::TableStyleApply => {
|
||||
for row in 0..3 {
|
||||
let _ = self.on_table_style_cell_apply(row);
|
||||
}
|
||||
self.stage_tablestyle_bufs();
|
||||
self.style_stage_commit();
|
||||
Task::none()
|
||||
|
|
@ -5728,7 +5769,18 @@ impl OpenCADStudio {
|
|||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogSelect(name) => {
|
||||
self.stage_mlstyle_bufs();
|
||||
self.mlstyle_selected = name;
|
||||
let i = self.active_tab;
|
||||
self.load_mlstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogTab(tab) => {
|
||||
self.mlstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogCompare(name) => {
|
||||
self.mlstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleDialogSetCurrent => {
|
||||
|
|
@ -5749,13 +5801,8 @@ impl OpenCADStudio {
|
|||
}
|
||||
Task::none()
|
||||
}
|
||||
// Placeholder so the Multiline manager has the same Set Current +
|
||||
// Apply pair as every other style manager. The editor is currently
|
||||
// read-only, so there is nothing to apply yet — wire this up when
|
||||
// editable MLineStyle properties land.
|
||||
Message::MlStyleApply => {
|
||||
// Multiline styles have no editable properties yet; Apply still
|
||||
// commits any staged structural / current-style changes.
|
||||
self.stage_mlstyle_bufs();
|
||||
self.style_stage_commit();
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -5771,6 +5818,66 @@ impl OpenCADStudio {
|
|||
self.style_delete(crate::app::StyleKind::MLine);
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleEdit { field, value } => {
|
||||
match field {
|
||||
"description" => self.mln_description = value,
|
||||
"start_angle" => self.mln_start_angle = value,
|
||||
"end_angle" => self.mln_end_angle = value,
|
||||
"fill_color" => self.mln_fill_color = value,
|
||||
_ => {}
|
||||
}
|
||||
self.stage_mlstyle_bufs();
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleToggle(field) => {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.mlstyle_mut(i) {
|
||||
match field {
|
||||
"fill" => style.flags.fill_on = !style.flags.fill_on,
|
||||
"joints" => style.flags.display_joints = !style.flags.display_joints,
|
||||
"start_square" => style.flags.start_square_cap = !style.flags.start_square_cap,
|
||||
"start_inner" => style.flags.start_inner_arcs_cap = !style.flags.start_inner_arcs_cap,
|
||||
"start_round" => style.flags.start_round_cap = !style.flags.start_round_cap,
|
||||
"end_square" => style.flags.end_square_cap = !style.flags.end_square_cap,
|
||||
"end_inner" => style.flags.end_inner_arcs_cap = !style.flags.end_inner_arcs_cap,
|
||||
"end_round" => style.flags.end_round_cap = !style.flags.end_round_cap,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleElementEdit { index, field, value } => {
|
||||
if let Some(element) = self.mln_elements.get_mut(index) {
|
||||
match field {
|
||||
"offset" => element[0] = value,
|
||||
"color" => element[1] = value,
|
||||
"linetype" => element[2] = value,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.stage_mlstyle_bufs();
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleElementAdd => {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.mlstyle_mut(i) {
|
||||
style
|
||||
.elements
|
||||
.push(acadrust::objects::MLineStyleElement::default());
|
||||
}
|
||||
self.load_mlstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::MlStyleElementDelete(index) => {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.mlstyle_mut(i) {
|
||||
if style.elements.len() > 1 && index < style.elements.len() {
|
||||
style.elements.remove(index);
|
||||
}
|
||||
}
|
||||
self.load_mlstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────
|
||||
Message::MLeaderStyleDialogOpen => self.on_mleader_style_dialog_open(),
|
||||
|
|
@ -5785,6 +5892,14 @@ impl OpenCADStudio {
|
|||
self.load_mleaderstyle_bufs(i);
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleDialogTab(tab) => {
|
||||
self.mleaderstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleDialogCompare(name) => {
|
||||
self.mleaderstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleDialogSetCurrent => self.on_mleader_style_dialog_set_current(),
|
||||
Message::MLeaderStyleDialogNew => {
|
||||
self.style_new(crate::app::StyleKind::MLeader);
|
||||
|
|
@ -5864,6 +5979,10 @@ impl OpenCADStudio {
|
|||
self.dimstyle_tab = tab;
|
||||
Task::none()
|
||||
}
|
||||
Message::DimStyleDialogCompare(name) => {
|
||||
self.dimstyle_compare = name;
|
||||
Task::none()
|
||||
}
|
||||
Message::DimStyleDialogNew => {
|
||||
self.style_new(crate::app::StyleKind::Dim);
|
||||
Task::none()
|
||||
|
|
@ -5875,6 +5994,19 @@ impl OpenCADStudio {
|
|||
Message::DimStyleDialogSetCurrent => {
|
||||
// Staged: persists on Apply.
|
||||
let i = self.active_tab;
|
||||
let read_only = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get(&self.dimstyle_selected)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference
|
||||
|| style.xref_dependent
|
||||
|| !style.xref_handle.is_null()
|
||||
});
|
||||
if read_only {
|
||||
return Task::none();
|
||||
}
|
||||
self.tabs[i].scene.document.header.current_dimstyle_name =
|
||||
self.dimstyle_selected.clone();
|
||||
self.sync_ribbon_styles();
|
||||
|
|
@ -5894,7 +6026,75 @@ impl OpenCADStudio {
|
|||
Task::none()
|
||||
}
|
||||
Message::DsToggle(field) => {
|
||||
let separate_arrows = field == crate::app::DsField::Dimsah;
|
||||
self.apply_ds_toggle(field);
|
||||
if separate_arrows && self.ds_dimsah {
|
||||
let i = self.active_tab;
|
||||
if let Some(style) = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.get_mut(&self.dimstyle_selected)
|
||||
{
|
||||
if style.dimblk1.is_null() {
|
||||
style.dimblk1 = style.dimblk;
|
||||
}
|
||||
if style.dimblk2.is_null() {
|
||||
style.dimblk2 = style.dimblk1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::DsToleranceMode(mode) => {
|
||||
self.ds_dimlim = mode == "limits";
|
||||
self.ds_dimtol = matches!(mode.as_str(), "symmetrical" | "deviation");
|
||||
if mode == "symmetrical" {
|
||||
self.ds_dimtm = self.ds_dimtp.clone();
|
||||
}
|
||||
let gap = self.ds_dimgap.trim().parse::<f64>().unwrap_or(0.625).abs();
|
||||
self.ds_dimgap = if mode == "basic" {
|
||||
format!("-{}", gap.max(f64::EPSILON))
|
||||
} else {
|
||||
format!("{}", gap)
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::DsZeroBase(field, base) => {
|
||||
let current = match &field {
|
||||
crate::app::DsField::Dimzin => &self.ds_dimzin,
|
||||
crate::app::DsField::Dimaltz => &self.ds_dimaltz,
|
||||
crate::app::DsField::Dimalttz => &self.ds_dimalttz,
|
||||
crate::app::DsField::Dimtzin => &self.ds_dimtzin,
|
||||
_ => return Task::none(),
|
||||
}
|
||||
.trim()
|
||||
.parse::<i16>()
|
||||
.unwrap_or(0);
|
||||
self.apply_ds_edit(field, ((current & !3) | (base & 3)).to_string());
|
||||
Task::none()
|
||||
}
|
||||
Message::DsZeroFlag(field, bit) => {
|
||||
let current = match &field {
|
||||
crate::app::DsField::Dimzin => &self.ds_dimzin,
|
||||
crate::app::DsField::Dimaltz => &self.ds_dimaltz,
|
||||
crate::app::DsField::Dimalttz => &self.ds_dimalttz,
|
||||
crate::app::DsField::Dimtzin => &self.ds_dimtzin,
|
||||
_ => return Task::none(),
|
||||
}
|
||||
.trim()
|
||||
.parse::<i16>()
|
||||
.unwrap_or(0);
|
||||
self.apply_ds_edit(field, (current ^ bit).to_string());
|
||||
Task::none()
|
||||
}
|
||||
Message::DsCenterMarkMode(mode) => {
|
||||
let size = self.ds_dimcen.trim().parse::<f64>().unwrap_or(0.09).abs();
|
||||
self.ds_dimcen = match mode.as_str() {
|
||||
"mark" => size.max(f64::EPSILON).to_string(),
|
||||
"lines" => format!("-{}", size.max(f64::EPSILON)),
|
||||
_ => "0".to_string(),
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::DsColorMore(field) => {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,91 @@ use iced::{mouse, Point, Task};
|
|||
|
||||
|
||||
impl OpenCADStudio {
|
||||
pub(in crate::app) fn mlstyle_mut(
|
||||
&mut self,
|
||||
tab: usize,
|
||||
) -> Option<&mut acadrust::objects::MLineStyle> {
|
||||
use acadrust::objects::ObjectType;
|
||||
let name = self.mlstyle_selected.clone();
|
||||
self.tabs[tab]
|
||||
.scene
|
||||
.document
|
||||
.objects
|
||||
.values_mut()
|
||||
.find_map(|object| match object {
|
||||
ObjectType::MLineStyle(style) if style.name == name => Some(style),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub(in crate::app) fn load_mlstyle_bufs(&mut self, tab: usize) {
|
||||
use acadrust::objects::ObjectType;
|
||||
let name = self.mlstyle_selected.clone();
|
||||
let Some((description, start_angle, end_angle, fill_color, elements)) = self.tabs[tab]
|
||||
.scene
|
||||
.document
|
||||
.objects
|
||||
.values()
|
||||
.find_map(|object| match object {
|
||||
ObjectType::MLineStyle(style) if style.name == name => Some((
|
||||
style.description.clone(),
|
||||
style.start_angle.to_degrees(),
|
||||
style.end_angle.to_degrees(),
|
||||
style.fill_color.index().unwrap_or(256),
|
||||
style
|
||||
.elements
|
||||
.iter()
|
||||
.map(|element| {
|
||||
[
|
||||
format!("{}", element.offset),
|
||||
element.color.index().unwrap_or(256).to_string(),
|
||||
element.linetype.clone(),
|
||||
]
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)),
|
||||
_ => None,
|
||||
})
|
||||
else {
|
||||
return;
|
||||
};
|
||||
self.mln_description = description;
|
||||
self.mln_start_angle = format!("{start_angle:.4}");
|
||||
self.mln_end_angle = format!("{end_angle:.4}");
|
||||
self.mln_fill_color = fill_color.to_string();
|
||||
self.mln_elements = elements;
|
||||
}
|
||||
|
||||
pub(in crate::app) fn stage_mlstyle_bufs(&mut self) {
|
||||
let tab = self.active_tab;
|
||||
let description = self.mln_description.clone();
|
||||
let start_angle = self.mln_start_angle.trim().parse::<f64>().ok();
|
||||
let end_angle = self.mln_end_angle.trim().parse::<f64>().ok();
|
||||
let fill_color = self.mln_fill_color.trim().parse::<i16>().ok();
|
||||
let elements = self.mln_elements.clone();
|
||||
if let Some(style) = self.mlstyle_mut(tab) {
|
||||
style.description = description;
|
||||
if let Some(value) = start_angle {
|
||||
style.start_angle = value.to_radians();
|
||||
}
|
||||
if let Some(value) = end_angle {
|
||||
style.end_angle = value.to_radians();
|
||||
}
|
||||
if let Some(value) = fill_color {
|
||||
style.fill_color = acadrust::types::Color::from_index(value);
|
||||
}
|
||||
for (element, values) in style.elements.iter_mut().zip(elements) {
|
||||
if let Ok(value) = values[0].trim().parse::<f64>() {
|
||||
element.offset = value;
|
||||
}
|
||||
if let Ok(value) = values[1].trim().parse::<i16>() {
|
||||
element.color = acadrust::types::Color::from_index(value);
|
||||
}
|
||||
element.linetype = values[2].clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::app) fn tablestyle_mut(&mut self, tab: usize) -> Option<&mut acadrust::objects::TableStyle> {
|
||||
use acadrust::objects::ObjectType;
|
||||
let name = self.tablestyle_selected.clone();
|
||||
|
|
@ -163,8 +248,8 @@ impl OpenCADStudio {
|
|||
self.mls_text_height = format!("{:.4}", s.text_height);
|
||||
self.mls_scale_factor = format!("{:.4}", s.scale_factor);
|
||||
self.mls_break_gap = format!("{:.4}", s.break_gap_size);
|
||||
self.mls_first_seg_angle = format!("{:.4}", s.first_segment_angle);
|
||||
self.mls_second_seg_angle = format!("{:.4}", s.second_segment_angle);
|
||||
self.mls_first_seg_angle = format!("{:.4}", s.first_segment_angle.to_degrees());
|
||||
self.mls_second_seg_angle = format!("{:.4}", s.second_segment_angle.to_degrees());
|
||||
self.mls_max_points = s.max_leader_points.to_string();
|
||||
self.mls_default_text = s.default_text.clone();
|
||||
self.mls_line_color = s
|
||||
|
|
@ -184,7 +269,7 @@ impl OpenCADStudio {
|
|||
.index()
|
||||
.map(|c| c.to_string())
|
||||
.unwrap_or_default();
|
||||
self.mls_block_rotation = format!("{:.4}", s.block_content_rotation);
|
||||
self.mls_block_rotation = format!("{:.4}", s.block_content_rotation.to_degrees());
|
||||
self.mls_block_scale_x = format!("{:.4}", s.block_content_scale_x);
|
||||
self.mls_block_scale_y = format!("{:.4}", s.block_content_scale_y);
|
||||
self.mls_block_scale_z = format!("{:.4}", s.block_content_scale_z);
|
||||
|
|
@ -273,6 +358,20 @@ impl OpenCADStudio {
|
|||
|
||||
pub(in crate::app) fn apply_dimstyle_bufs(&mut self, tab: usize) {
|
||||
let doc = &mut self.tabs[tab].scene.document;
|
||||
let read_only = doc
|
||||
.dim_styles
|
||||
.get(&self.dimstyle_selected)
|
||||
.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
});
|
||||
if read_only {
|
||||
return;
|
||||
}
|
||||
let text_style_handle = doc
|
||||
.text_styles
|
||||
.get(&self.ds_dimtxsty)
|
||||
.map(|style| style.handle)
|
||||
.unwrap_or(acadrust::types::Handle::NULL);
|
||||
let Some(ds) = doc.dim_styles.get_mut(&self.dimstyle_selected) else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -323,6 +422,7 @@ impl OpenCADStudio {
|
|||
ds.dimlim = self.ds_dimlim;
|
||||
ds.dimpost = self.ds_dimpost.clone();
|
||||
ds.dimtxsty = self.ds_dimtxsty.clone();
|
||||
ds.dimtxsty_handle = text_style_handle;
|
||||
ds.annotative = self.ds_annotative;
|
||||
set_i16!(dimclrd, self.ds_dimclrd);
|
||||
set_i16!(dimlwd, self.ds_dimlwd);
|
||||
|
|
@ -392,7 +492,15 @@ impl OpenCADStudio {
|
|||
Dimlunit => self.ds_dimlunit = val,
|
||||
Dimdec => self.ds_dimdec = val,
|
||||
Dimpost => self.ds_dimpost = val,
|
||||
Dimtp => self.ds_dimtp = val,
|
||||
Dimtp => {
|
||||
let symmetrical = self.ds_dimtol
|
||||
&& !self.ds_dimlim
|
||||
&& self.ds_dimtp.trim() == self.ds_dimtm.trim();
|
||||
self.ds_dimtp = val.clone();
|
||||
if symmetrical {
|
||||
self.ds_dimtm = val;
|
||||
}
|
||||
}
|
||||
Dimtm => self.ds_dimtm = val,
|
||||
Dimtdec => self.ds_dimtdec = val,
|
||||
Dimtfac => self.ds_dimtfac = val,
|
||||
|
|
@ -518,6 +626,9 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
let bigfont = self.textstyle_bigfont.clone();
|
||||
let ttf = self.textstyle_ttf.clone();
|
||||
if let Some(s) = self.tabs[i].scene.document.text_styles.get_mut(&name) {
|
||||
if s.xref_dependent {
|
||||
return;
|
||||
}
|
||||
s.font_file = font;
|
||||
s.big_font_file = bigfont;
|
||||
s.true_type_font = ttf;
|
||||
|
|
@ -629,6 +740,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
.unwrap_or_else(|| "Standard".to_string())
|
||||
};
|
||||
self.active_modal = Some(crate::app::ModalKind::MlStyle);
|
||||
self.load_mlstyle_bufs(i);
|
||||
self.style_stage_begin();
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -818,7 +930,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
pub(super) fn on_mleader_style_set_handle(&mut self, field: &'static str, value: String) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let handle: Option<acadrust::types::Handle> = if value == "None" {
|
||||
let handle: Option<acadrust::types::Handle> = if value == "None"
|
||||
|| value == "ByBlock"
|
||||
|| value == "Closed filled"
|
||||
{
|
||||
None
|
||||
} else {
|
||||
match field {
|
||||
|
|
@ -897,10 +1012,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
s.break_gap_size = v;
|
||||
}
|
||||
if let Some(v) = fsa {
|
||||
s.first_segment_angle = v;
|
||||
s.first_segment_angle = v.to_radians();
|
||||
}
|
||||
if let Some(v) = ssa {
|
||||
s.second_segment_angle = v;
|
||||
s.second_segment_angle = v.to_radians();
|
||||
}
|
||||
if let Some(v) = mp {
|
||||
s.max_leader_points = v;
|
||||
|
|
@ -920,7 +1035,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
s.block_content_color = acadrust::types::Color::from_index(v);
|
||||
}
|
||||
if let Some(v) = brot {
|
||||
s.block_content_rotation = v;
|
||||
s.block_content_rotation = v.to_radians();
|
||||
}
|
||||
if let Some(v) = bsx {
|
||||
s.block_content_scale_x = v;
|
||||
|
|
@ -962,6 +1077,14 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
.unwrap_or_else(|| "Standard".to_string())
|
||||
};
|
||||
self.dimstyle_selected = selected.clone();
|
||||
self.dimstyle_compare = self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.dim_styles
|
||||
.iter()
|
||||
.map(|style| style.name.clone())
|
||||
.find(|name| !name.eq_ignore_ascii_case(&selected))
|
||||
.unwrap_or_default();
|
||||
self.load_dimstyle_bufs(i);
|
||||
self.active_modal = Some(crate::app::ModalKind::DimStyle);
|
||||
self.style_stage_begin();
|
||||
|
|
@ -1018,6 +1141,11 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
"dimltex_handle" | "dimltex1_handle" | "dimltex2_handle"
|
||||
);
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
if doc.dim_styles.get(&name).is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
}) {
|
||||
return Task::none();
|
||||
}
|
||||
let handle = if value == "Default" || value == "ByBlock" {
|
||||
acadrust::types::Handle::NULL
|
||||
} else if is_lt {
|
||||
|
|
@ -1037,7 +1165,10 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
|
|||
if let Some(ds) = self.tabs[i].scene.document.dim_styles.get_mut(&name) {
|
||||
match field {
|
||||
"dimblk" => ds.dimblk = handle,
|
||||
"dimblk1" => ds.dimblk1 = handle,
|
||||
"dimblk1" => {
|
||||
ds.dimblk1 = handle;
|
||||
ds.dimblk2 = handle;
|
||||
}
|
||||
"dimblk2" => ds.dimblk2 = handle,
|
||||
"dimldrblk" => ds.dimldrblk = handle,
|
||||
"dimltex_handle" => ds.dimltex_handle = handle,
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ impl OpenCADStudio {
|
|||
),
|
||||
super::super::ModalKind::TextStyle => {
|
||||
let tab = &self.tabs[self.active_tab];
|
||||
let doc = &tab.scene.document;
|
||||
let styles: Vec<String> = tab
|
||||
.scene
|
||||
.document
|
||||
|
|
@ -369,23 +370,77 @@ impl OpenCADStudio {
|
|||
.iter()
|
||||
.map(|s| s.name.clone())
|
||||
.collect();
|
||||
let (backward, upside_down, annotative) = tab
|
||||
.scene
|
||||
.document
|
||||
let selected_style = doc
|
||||
.text_styles
|
||||
.get(&self.textstyle_selected)
|
||||
.map(|s| (s.flags.backward, s.flags.upside_down, s.annotative))
|
||||
.unwrap_or((false, false, false));
|
||||
.get(&self.textstyle_selected);
|
||||
let (backward, upside_down, vertical, annotative, read_only) = selected_style
|
||||
.map(|style| {
|
||||
(
|
||||
style.flags.backward,
|
||||
style.flags.upside_down,
|
||||
style.is_vertical,
|
||||
style.annotative,
|
||||
style.xref_dependent,
|
||||
)
|
||||
})
|
||||
.unwrap_or((false, false, false, false, false));
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::Text,
|
||||
&self.textstyle_selected,
|
||||
);
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.textstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.textstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, doc.text_styles.get(&compare_name)) {
|
||||
if (
|
||||
&a.font_file,
|
||||
&a.big_font_file,
|
||||
&a.true_type_font,
|
||||
a.is_shape_file,
|
||||
) != (
|
||||
&b.font_file,
|
||||
&b.big_font_file,
|
||||
&b.true_type_font,
|
||||
b.is_shape_file,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Fonts").into_owned());
|
||||
}
|
||||
if (a.height, a.width_factor, a.oblique_angle, a.last_height)
|
||||
!= (b.height, b.width_factor, b.oblique_angle, b.last_height)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Size").into_owned());
|
||||
}
|
||||
if (a.flags, a.is_vertical, a.annotative)
|
||||
!= (b.flags, b.is_vertical, b.annotative)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Effects").into_owned());
|
||||
}
|
||||
}
|
||||
sized_flow(
|
||||
ex,
|
||||
860,
|
||||
480,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::textstyle::view_window(
|
||||
crate::ui::style::textstyle::TextStyleView {
|
||||
styles: styles.clone(),
|
||||
selected: &self.textstyle_selected,
|
||||
current: &tab.scene.document.header.current_text_style_name,
|
||||
tab: self.textstyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
read_only,
|
||||
in_use,
|
||||
font_buf: &self.textstyle_font,
|
||||
width_buf: &self.textstyle_width,
|
||||
oblique_buf: &self.textstyle_oblique,
|
||||
|
|
@ -394,6 +449,7 @@ impl OpenCADStudio {
|
|||
ttf_buf: &self.textstyle_ttf,
|
||||
backward,
|
||||
upside_down,
|
||||
vertical,
|
||||
annotative,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
|
|
@ -420,18 +476,60 @@ impl OpenCADStudio {
|
|||
ObjectType::MLineStyle(s) if s.name == self.mlstyle_selected => Some(s),
|
||||
_ => None,
|
||||
});
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.mlstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.mlstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let compare_style = tab.scene.document.objects.values().find_map(|object| match object {
|
||||
ObjectType::MLineStyle(style) if style.name == compare_name => Some(style),
|
||||
_ => None,
|
||||
});
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, compare_style) {
|
||||
if (&a.description, a.flags, a.fill_color, a.start_angle, a.end_angle)
|
||||
!= (&b.description, b.flags, b.fill_color, b.start_angle, b.end_angle)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Caps and Fill").into_owned());
|
||||
}
|
||||
if a.elements != b.elements {
|
||||
comparison_sections.push(crate::i18n::translate("Elements").into_owned());
|
||||
}
|
||||
}
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::MLine,
|
||||
&self.mlstyle_selected,
|
||||
);
|
||||
sized_flow(
|
||||
ex,
|
||||
620,
|
||||
420,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::mlstyle::view_window(
|
||||
styles.clone(),
|
||||
&self.mlstyle_selected,
|
||||
selected_style,
|
||||
tab.scene.document.header.multiline_style.clone(),
|
||||
self.style_rename.as_deref(),
|
||||
&self.style_rename_buf,
|
||||
crate::ui::style::mlstyle::MlStyleView {
|
||||
styles: styles.clone(),
|
||||
selected: &self.mlstyle_selected,
|
||||
style: selected_style,
|
||||
current: tab.scene.document.header.multiline_style.clone(),
|
||||
tab: self.mlstyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
in_use,
|
||||
description: &self.mln_description,
|
||||
start_angle: &self.mln_start_angle,
|
||||
end_angle: &self.mln_end_angle,
|
||||
fill_color: &self.mln_fill_color,
|
||||
elements: &self.mln_elements,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
},
|
||||
flow,
|
||||
)
|
||||
},
|
||||
|
|
@ -454,32 +552,89 @@ impl OpenCADStudio {
|
|||
ObjectType::TableStyle(s) if s.name == self.tablestyle_selected => Some(s),
|
||||
_ => None,
|
||||
});
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.tablestyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.tablestyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let compare_style = tab.scene.document.objects.values().find_map(|object| match object {
|
||||
ObjectType::TableStyle(style) if style.name == compare_name => Some(style),
|
||||
_ => None,
|
||||
});
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, compare_style) {
|
||||
if (
|
||||
&a.description,
|
||||
a.flow_direction,
|
||||
a.horizontal_margin,
|
||||
a.vertical_margin,
|
||||
a.title_suppressed,
|
||||
a.header_suppressed,
|
||||
a.annotative,
|
||||
) != (
|
||||
&b.description,
|
||||
b.flow_direction,
|
||||
b.horizontal_margin,
|
||||
b.vertical_margin,
|
||||
b.title_suppressed,
|
||||
b.header_suppressed,
|
||||
b.annotative,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("General").into_owned());
|
||||
}
|
||||
for (label, different) in [
|
||||
("Data Row", a.data_row_style != b.data_row_style),
|
||||
("Header Row", a.header_row_style != b.header_row_style),
|
||||
("Title Row", a.title_row_style != b.title_row_style),
|
||||
] {
|
||||
if different {
|
||||
comparison_sections.push(crate::i18n::translate(label).into_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::Table,
|
||||
&self.tablestyle_selected,
|
||||
);
|
||||
sized_flow(
|
||||
ex,
|
||||
620,
|
||||
420,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::tablestyle::view_window(
|
||||
styles.clone(),
|
||||
&self.tablestyle_selected,
|
||||
&self.ribbon.active_table_style,
|
||||
selected_style,
|
||||
&self.ts_hmargin,
|
||||
&self.ts_vmargin,
|
||||
&self.ts_description,
|
||||
&self.ts_cell_textstyle,
|
||||
&self.ts_cell_height,
|
||||
&self.ts_cell_textcolor,
|
||||
&self.ts_cell_fillcolor,
|
||||
&self.ts_cell_datatype,
|
||||
&self.ts_cell_unittype,
|
||||
&self.ts_cell_format,
|
||||
&self.ts_border_lw,
|
||||
&self.ts_border_color,
|
||||
&self.ts_border_spacing,
|
||||
self.style_rename.as_deref(),
|
||||
&self.style_rename_buf,
|
||||
self.ts_color_open,
|
||||
crate::ui::style::tablestyle::TableStyleView {
|
||||
styles: styles.clone(),
|
||||
selected: &self.tablestyle_selected,
|
||||
current: &tab.scene.document.header.current_table_style_name,
|
||||
style: selected_style,
|
||||
tab: self.tablestyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
in_use,
|
||||
hmargin: &self.ts_hmargin,
|
||||
vmargin: &self.ts_vmargin,
|
||||
description: &self.ts_description,
|
||||
cell_textstyle: &self.ts_cell_textstyle,
|
||||
cell_height: &self.ts_cell_height,
|
||||
cell_textcolor: &self.ts_cell_textcolor,
|
||||
cell_fillcolor: &self.ts_cell_fillcolor,
|
||||
cell_datatype: &self.ts_cell_datatype,
|
||||
cell_unittype: &self.ts_cell_unittype,
|
||||
cell_format: &self.ts_cell_format,
|
||||
border_lw: &self.ts_border_lw,
|
||||
border_color: &self.ts_border_color,
|
||||
border_spacing: &self.ts_border_spacing,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
color_open: self.ts_color_open,
|
||||
},
|
||||
flow,
|
||||
)
|
||||
},
|
||||
|
|
@ -507,7 +662,9 @@ impl OpenCADStudio {
|
|||
let doc = &tab.scene.document;
|
||||
let mut block_opts: Vec<String> = vec!["None".to_string()];
|
||||
block_opts.extend(doc.block_records.iter().map(|b| b.name.clone()));
|
||||
let mut lt_opts: Vec<String> = vec!["None".to_string()];
|
||||
let mut arrow_opts: Vec<String> = vec!["Closed filled".to_string()];
|
||||
arrow_opts.extend(doc.block_records.iter().map(|b| b.name.clone()));
|
||||
let mut lt_opts: Vec<String> = vec!["ByBlock".to_string()];
|
||||
lt_opts.extend(doc.line_types.iter().map(|lt| lt.name.clone()));
|
||||
let mut textstyle_opts: Vec<String> = vec!["None".to_string()];
|
||||
textstyle_opts.extend(doc.text_styles.iter().map(|t| t.name.clone()));
|
||||
|
|
@ -529,8 +686,8 @@ impl OpenCADStudio {
|
|||
.iter()
|
||||
.find(|lt| lt.handle == h)
|
||||
.map(|lt| lt.name.clone())
|
||||
.unwrap_or_else(|| "None".to_string()),
|
||||
None => "None".to_string(),
|
||||
.unwrap_or_else(|| "ByBlock".to_string()),
|
||||
None => "ByBlock".to_string(),
|
||||
}
|
||||
};
|
||||
let opt_ts = |h: Option<acadrust::types::Handle>| -> String {
|
||||
|
|
@ -548,16 +705,153 @@ impl OpenCADStudio {
|
|||
match selected_style {
|
||||
Some(s) => (
|
||||
opt_lt(s.line_type_handle),
|
||||
opt_block(s.arrowhead_handle),
|
||||
s.arrowhead_handle
|
||||
.and_then(|handle| {
|
||||
doc.block_records
|
||||
.iter()
|
||||
.find(|record| record.handle == handle)
|
||||
.map(|record| record.name.clone())
|
||||
})
|
||||
.unwrap_or_else(|| "Closed filled".to_string()),
|
||||
opt_ts(s.text_style_handle),
|
||||
opt_block(s.block_content_handle),
|
||||
),
|
||||
None => Default::default(),
|
||||
};
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.mleaderstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.mleaderstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let compare_style = doc.objects.values().find_map(|object| match object {
|
||||
ObjectType::MultiLeaderStyle(style) if style.name == compare_name => Some(style),
|
||||
_ => None,
|
||||
});
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (selected_style, compare_style) {
|
||||
if (
|
||||
&a.description,
|
||||
a.path_type,
|
||||
a.line_color,
|
||||
a.line_type_handle,
|
||||
a.line_weight,
|
||||
a.arrowhead_handle,
|
||||
a.arrowhead_size,
|
||||
a.break_gap_size,
|
||||
) != (
|
||||
&b.description,
|
||||
b.path_type,
|
||||
b.line_color,
|
||||
b.line_type_handle,
|
||||
b.line_weight,
|
||||
b.arrowhead_handle,
|
||||
b.arrowhead_size,
|
||||
b.break_gap_size,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Leader Format").into_owned());
|
||||
}
|
||||
if (
|
||||
a.enable_landing,
|
||||
a.enable_dogleg,
|
||||
a.landing_distance,
|
||||
a.landing_gap,
|
||||
a.scale_factor,
|
||||
a.align_space,
|
||||
a.max_leader_points,
|
||||
a.first_segment_angle,
|
||||
a.second_segment_angle,
|
||||
a.leader_draw_order,
|
||||
a.multileader_draw_order,
|
||||
a.is_annotative,
|
||||
) != (
|
||||
b.enable_landing,
|
||||
b.enable_dogleg,
|
||||
b.landing_distance,
|
||||
b.landing_gap,
|
||||
b.scale_factor,
|
||||
b.align_space,
|
||||
b.max_leader_points,
|
||||
b.first_segment_angle,
|
||||
b.second_segment_angle,
|
||||
b.leader_draw_order,
|
||||
b.multileader_draw_order,
|
||||
b.is_annotative,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Leader Structure").into_owned());
|
||||
}
|
||||
if (
|
||||
a.content_type,
|
||||
&a.default_text,
|
||||
a.text_style_handle,
|
||||
a.text_height,
|
||||
a.text_color,
|
||||
a.text_angle_type,
|
||||
a.text_alignment,
|
||||
) != (
|
||||
b.content_type,
|
||||
&b.default_text,
|
||||
b.text_style_handle,
|
||||
b.text_height,
|
||||
b.text_color,
|
||||
b.text_angle_type,
|
||||
b.text_alignment,
|
||||
) || (
|
||||
a.text_left_attachment,
|
||||
a.text_right_attachment,
|
||||
a.text_top_attachment,
|
||||
a.text_bottom_attachment,
|
||||
a.text_attachment_direction,
|
||||
a.text_frame,
|
||||
a.text_always_left,
|
||||
) != (
|
||||
b.text_left_attachment,
|
||||
b.text_right_attachment,
|
||||
b.text_top_attachment,
|
||||
b.text_bottom_attachment,
|
||||
b.text_attachment_direction,
|
||||
b.text_frame,
|
||||
b.text_always_left,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Content").into_owned());
|
||||
}
|
||||
if (
|
||||
a.block_content_handle,
|
||||
a.block_content_color,
|
||||
a.block_content_connection,
|
||||
a.block_content_rotation,
|
||||
a.block_content_scale_x,
|
||||
a.block_content_scale_y,
|
||||
a.block_content_scale_z,
|
||||
a.enable_block_scale,
|
||||
a.enable_block_rotation,
|
||||
) != (
|
||||
b.block_content_handle,
|
||||
b.block_content_color,
|
||||
b.block_content_connection,
|
||||
b.block_content_rotation,
|
||||
b.block_content_scale_x,
|
||||
b.block_content_scale_y,
|
||||
b.block_content_scale_z,
|
||||
b.enable_block_scale,
|
||||
b.enable_block_rotation,
|
||||
) {
|
||||
comparison_sections.push(crate::i18n::translate("Block Content").into_owned());
|
||||
}
|
||||
}
|
||||
let in_use = self.style_in_use(
|
||||
crate::app::StyleKind::MLeader,
|
||||
&self.mleaderstyle_selected,
|
||||
);
|
||||
sized_flow(
|
||||
ex,
|
||||
560,
|
||||
560,
|
||||
960,
|
||||
680,
|
||||
|flow| {
|
||||
crate::ui::style::mleaderstyle::view_window(
|
||||
crate::ui::style::mleaderstyle::MLeaderStyleView {
|
||||
|
|
@ -565,6 +859,11 @@ impl OpenCADStudio {
|
|||
selected: &self.mleaderstyle_selected,
|
||||
style: selected_style,
|
||||
current: tab.active_mleader_style.clone(),
|
||||
tab: self.mleaderstyle_tab,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
in_use,
|
||||
landing_distance: &self.mls_landing_distance,
|
||||
landing_gap: &self.mls_landing_gap,
|
||||
arrowhead_size: &self.mls_arrowhead_size,
|
||||
|
|
@ -585,6 +884,7 @@ impl OpenCADStudio {
|
|||
block_scale_y: &self.mls_block_scale_y,
|
||||
block_scale_z: &self.mls_block_scale_z,
|
||||
block_opts: block_opts.clone(),
|
||||
arrow_opts: arrow_opts.clone(),
|
||||
lt_opts: lt_opts.clone(),
|
||||
textstyle_opts: textstyle_opts.clone(),
|
||||
line_type_name: line_type_name.clone(),
|
||||
|
|
@ -630,6 +930,13 @@ impl OpenCADStudio {
|
|||
);
|
||||
let mut lt_opts: Vec<String> = vec!["ByBlock".to_string()];
|
||||
lt_opts.extend(doc.line_types.iter().map(|lt| lt.name.clone()));
|
||||
let text_style_opts: Vec<String> =
|
||||
doc.text_styles.iter().map(|style| style.name.clone()).collect();
|
||||
let text_style_fixed_height = doc
|
||||
.text_styles
|
||||
.get(&self.ds_dimtxsty)
|
||||
.map(|style| style.height)
|
||||
.filter(|height| *height > 0.0);
|
||||
let blk_name = |h: acadrust::types::Handle| -> String {
|
||||
if h.is_null() {
|
||||
"Default".to_string()
|
||||
|
|
@ -653,6 +960,70 @@ impl OpenCADStudio {
|
|||
}
|
||||
};
|
||||
let ds_sel = doc.dim_styles.get(&self.dimstyle_selected);
|
||||
let read_only = ds_sel.is_some_and(|style| {
|
||||
style.xref_reference || style.xref_dependent || !style.xref_handle.is_null()
|
||||
});
|
||||
let in_use = doc.entities().any(|entity| {
|
||||
matches!(entity, acadrust::EntityType::Dimension(dimension)
|
||||
if dimension.base().style_name.eq_ignore_ascii_case(&self.dimstyle_selected))
|
||||
});
|
||||
let compare_opts: Vec<String> = styles
|
||||
.iter()
|
||||
.filter(|name| !name.eq_ignore_ascii_case(&self.dimstyle_selected))
|
||||
.cloned()
|
||||
.collect();
|
||||
let compare_name = compare_opts
|
||||
.iter()
|
||||
.find(|name| name.eq_ignore_ascii_case(&self.dimstyle_compare))
|
||||
.cloned()
|
||||
.or_else(|| compare_opts.first().cloned())
|
||||
.unwrap_or_default();
|
||||
let mut comparison_sections = Vec::new();
|
||||
if let (Some(a), Some(b)) = (ds_sel, doc.dim_styles.get(&compare_name)) {
|
||||
if (a.dimdle, a.dimdli, a.dimgap, a.dimclrd, a.dimlwd, a.dimsd1, a.dimsd2)
|
||||
!= (b.dimdle, b.dimdli, b.dimgap, b.dimclrd, b.dimlwd, b.dimsd1, b.dimsd2)
|
||||
|| (a.dimexe, a.dimexo, a.dimclre, a.dimlwe, a.dimse1, a.dimse2, a.dimfxl, a.dimfxlon)
|
||||
!= (b.dimexe, b.dimexo, b.dimclre, b.dimlwe, b.dimse1, b.dimse2, b.dimfxl, b.dimfxlon)
|
||||
|| (a.dimltex_handle, a.dimltex1_handle, a.dimltex2_handle)
|
||||
!= (b.dimltex_handle, b.dimltex1_handle, b.dimltex2_handle)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Lines").into_owned());
|
||||
}
|
||||
if (a.dimasz, a.dimblk, a.dimblk1, a.dimblk2, a.dimldrblk, a.dimsah, a.dimcen, a.dimtsz)
|
||||
!= (b.dimasz, b.dimblk, b.dimblk1, b.dimblk2, b.dimldrblk, b.dimsah, b.dimcen, b.dimtsz)
|
||||
|| (a.dimarcsym, a.dimjogang) != (b.dimarcsym, b.dimjogang)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Symbols and Arrows").into_owned());
|
||||
}
|
||||
if (a.dimclrt, a.dimtxt, &a.dimtxsty, a.dimjust, a.dimtad, a.dimtvp)
|
||||
!= (b.dimclrt, b.dimtxt, &b.dimtxsty, b.dimjust, b.dimtad, b.dimtvp)
|
||||
|| (a.dimtih, a.dimtoh, a.dimtfill, a.dimtfillclr, a.dimtxtdirection)
|
||||
!= (b.dimtih, b.dimtoh, b.dimtfill, b.dimtfillclr, b.dimtxtdirection)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Text").into_owned());
|
||||
}
|
||||
if (a.dimatfit, a.dimtix, a.dimsoxd, a.dimtmove, a.dimupt, a.dimtofl, a.dimscale, a.annotative)
|
||||
!= (b.dimatfit, b.dimtix, b.dimsoxd, b.dimtmove, b.dimupt, b.dimtofl, b.dimscale, b.annotative)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Fit").into_owned());
|
||||
}
|
||||
if (a.dimlfac, a.dimlunit, a.dimdec, &a.dimpost, a.dimdsep, a.dimrnd, a.dimzin, a.dimfrac)
|
||||
!= (b.dimlfac, b.dimlunit, b.dimdec, &b.dimpost, b.dimdsep, b.dimrnd, b.dimzin, b.dimfrac)
|
||||
|| (a.dimaunit, a.dimadec, a.dimazin) != (b.dimaunit, b.dimadec, b.dimazin)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Primary Units").into_owned());
|
||||
}
|
||||
if (a.dimalt, a.dimaltf, a.dimaltd, a.dimaltu, a.dimalttd, a.dimaltrnd, &a.dimapost, a.dimaltz, a.dimalttz)
|
||||
!= (b.dimalt, b.dimaltf, b.dimaltd, b.dimaltu, b.dimalttd, b.dimaltrnd, &b.dimapost, b.dimaltz, b.dimalttz)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Alternate Units").into_owned());
|
||||
}
|
||||
if (a.dimtol, a.dimlim, a.dimtp, a.dimtm, a.dimtdec, a.dimtfac, a.dimtolj, a.dimtzin)
|
||||
!= (b.dimtol, b.dimlim, b.dimtp, b.dimtm, b.dimtdec, b.dimtfac, b.dimtolj, b.dimtzin)
|
||||
{
|
||||
comparison_sections.push(crate::i18n::translate("Tolerances").into_owned());
|
||||
}
|
||||
}
|
||||
let (
|
||||
dimblk_name,
|
||||
dimblk1_name,
|
||||
|
|
@ -673,7 +1044,7 @@ impl OpenCADStudio {
|
|||
),
|
||||
None => Default::default(),
|
||||
};
|
||||
sized_flow(ex, 720, 560, |flow| {
|
||||
sized_flow(ex, 960, 680, |flow| {
|
||||
crate::ui::style::dimstyle::view_window(
|
||||
styles.clone(),
|
||||
&self.dimstyle_selected,
|
||||
|
|
@ -734,14 +1105,12 @@ impl OpenCADStudio {
|
|||
dimtmove: &self.ds_dimtmove,
|
||||
dimupt: self.ds_dimupt,
|
||||
dimtofl: self.ds_dimtofl,
|
||||
dimfit: &self.ds_dimfit,
|
||||
dimdsep: &self.ds_dimdsep,
|
||||
dimrnd: &self.ds_dimrnd,
|
||||
dimzin: &self.ds_dimzin,
|
||||
dimfrac: &self.ds_dimfrac,
|
||||
dimaunit: &self.ds_dimaunit,
|
||||
dimadec: &self.ds_dimadec,
|
||||
dimunit: &self.ds_dimunit,
|
||||
dimazin: &self.ds_dimazin,
|
||||
dimalt: self.ds_dimalt,
|
||||
dimaltf: &self.ds_dimaltf,
|
||||
|
|
@ -763,6 +1132,13 @@ impl OpenCADStudio {
|
|||
dimltex2_name: dimltex2_name.clone(),
|
||||
block_opts: block_opts.clone(),
|
||||
lt_opts: lt_opts.clone(),
|
||||
text_style_opts: text_style_opts.clone(),
|
||||
text_style_fixed_height,
|
||||
compare_name: compare_name.clone(),
|
||||
compare_opts: compare_opts.clone(),
|
||||
comparison_sections: comparison_sections.clone(),
|
||||
read_only,
|
||||
in_use,
|
||||
color_open: self.ds_color_open.clone(),
|
||||
},
|
||||
self.style_rename.as_deref(),
|
||||
|
|
|
|||
|
|
@ -13,12 +13,79 @@ use acadrust::{CadDocument, Handle};
|
|||
|
||||
// DXF group codes of the dimension variables surfaced on the leader panel.
|
||||
pub const DIMSCALE: i16 = 40; // overall scale (real)
|
||||
pub const DIMPOST: i16 = 3;
|
||||
pub const DIMAPOST: i16 = 4;
|
||||
pub const DIMASZ: i16 = 41; // arrow size (real)
|
||||
pub const DIMTAD: i16 = 77; // text vertical pos (int16)
|
||||
pub const DIMCLRD: i16 = 176; // dim line colour (int16 = ACI index)
|
||||
pub const DIMGAP: i16 = 147; // text offset / gap (real)
|
||||
pub const DIMLWD: i16 = 371; // dim line lineweight (int16)
|
||||
pub const DIMLDRBLK: i16 = 341; // leader arrow block (handle)
|
||||
pub const DIMEXO: i16 = 42;
|
||||
pub const DIMDLI: i16 = 43;
|
||||
pub const DIMEXE: i16 = 44;
|
||||
pub const DIMRND: i16 = 45;
|
||||
pub const DIMDLE: i16 = 46;
|
||||
pub const DIMTP: i16 = 47;
|
||||
pub const DIMTM: i16 = 48;
|
||||
pub const DIMFXL: i16 = 49;
|
||||
pub const DIMJOGANG: i16 = 50;
|
||||
pub const DIMTOL: i16 = 71;
|
||||
pub const DIMLIM: i16 = 72;
|
||||
pub const DIMTIH: i16 = 73;
|
||||
pub const DIMTOH: i16 = 74;
|
||||
pub const DIMSE1: i16 = 75;
|
||||
pub const DIMSE2: i16 = 76;
|
||||
pub const DIMZIN: i16 = 78;
|
||||
pub const DIMAZIN: i16 = 79;
|
||||
pub const DIMARCSYM: i16 = 90;
|
||||
pub const DIMTXT: i16 = 140;
|
||||
pub const DIMCEN: i16 = 141;
|
||||
pub const DIMTSZ: i16 = 142;
|
||||
pub const DIMALTF: i16 = 143;
|
||||
pub const DIMLFAC: i16 = 144;
|
||||
pub const DIMTVP: i16 = 145;
|
||||
pub const DIMTFAC: i16 = 146;
|
||||
pub const DIMALTRND: i16 = 148;
|
||||
pub const DIMALT: i16 = 170;
|
||||
pub const DIMALTD: i16 = 171;
|
||||
pub const DIMTOFL: i16 = 172;
|
||||
pub const DIMSAH: i16 = 173;
|
||||
pub const DIMTIX: i16 = 174;
|
||||
pub const DIMSOXD: i16 = 175;
|
||||
pub const DIMCLRE: i16 = 177;
|
||||
pub const DIMCLRT: i16 = 178;
|
||||
pub const DIMADEC: i16 = 179;
|
||||
pub const DIMDEC: i16 = 271;
|
||||
pub const DIMTDEC: i16 = 272;
|
||||
pub const DIMALTU: i16 = 273;
|
||||
pub const DIMALTTD: i16 = 274;
|
||||
pub const DIMAUNIT: i16 = 275;
|
||||
pub const DIMFRAC: i16 = 276;
|
||||
pub const DIMLUNIT: i16 = 277;
|
||||
pub const DIMDSEP: i16 = 278;
|
||||
pub const DIMTMOVE: i16 = 279;
|
||||
pub const DIMJUST: i16 = 280;
|
||||
pub const DIMSD1: i16 = 281;
|
||||
pub const DIMSD2: i16 = 282;
|
||||
pub const DIMTOLJ: i16 = 283;
|
||||
pub const DIMTZIN: i16 = 284;
|
||||
pub const DIMALTZ: i16 = 285;
|
||||
pub const DIMALTTZ: i16 = 286;
|
||||
pub const DIMUPT: i16 = 288;
|
||||
pub const DIMATFIT: i16 = 289;
|
||||
pub const DIMFXLON: i16 = 290;
|
||||
pub const DIMTFILL: i16 = 69;
|
||||
pub const DIMTFILLCLR: i16 = 70;
|
||||
pub const DIMTXTDIRECTION: i16 = 295;
|
||||
pub const DIMTXSTY: i16 = 340;
|
||||
pub const DIMBLK: i16 = 342;
|
||||
pub const DIMBLK1: i16 = 343;
|
||||
pub const DIMBLK2: i16 = 344;
|
||||
pub const DIMLTYPE: i16 = 345;
|
||||
pub const DIMLTEX1: i16 = 346;
|
||||
pub const DIMLTEX2: i16 = 347;
|
||||
pub const DIMLWE: i16 = 372;
|
||||
|
||||
/// Every (code, value) override present in the `ACAD`/`DSTYLE` record.
|
||||
pub fn pairs(xd: &ExtendedData) -> Vec<(i16, XDataValue)> {
|
||||
|
|
@ -90,6 +157,16 @@ pub fn handle(xd: &ExtendedData, code: i16) -> Option<Handle> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn string(xd: &ExtendedData, code: i16) -> Option<String> {
|
||||
pairs(xd)
|
||||
.into_iter()
|
||||
.find(|(c, _)| *c == code)
|
||||
.and_then(|(_, value)| match value {
|
||||
XDataValue::String(text) => Some(text),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_pairs(doc: &mut CadDocument, handle: Handle, pairs: Vec<(i16, XDataValue)>) {
|
||||
let Some(entity) = doc.get_entity(handle) else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1389,27 +1389,6 @@ fn apply_dimension_breaks(
|
|||
*lines = output;
|
||||
}
|
||||
|
||||
pub(crate) fn uses_custom_arrow_blocks(document: &CadDocument, dim: &Dimension) -> bool {
|
||||
let style_name = &dim.base().style_name;
|
||||
let Some(style) = document.dim_styles.iter().find(|style| {
|
||||
style.name.eq_ignore_ascii_case(style_name)
|
||||
|| (style_name.trim().is_empty() && style.name.eq_ignore_ascii_case("Standard"))
|
||||
}) else {
|
||||
return false;
|
||||
};
|
||||
if style.dimtsz > 1e-9 {
|
||||
return false;
|
||||
}
|
||||
let is_custom = |handle| {
|
||||
crate::scene::convert::tessellate::arrow_block_is_custom(document, handle)
|
||||
};
|
||||
if style.dimsah {
|
||||
is_custom(style.dimblk1) || is_custom(style.dimblk2)
|
||||
} else {
|
||||
is_custom(style.dimblk)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DimensionTess {
|
||||
fn tessellate(
|
||||
&self,
|
||||
|
|
@ -1481,10 +1460,126 @@ fn tessellate_dimension_inner(
|
|||
// recursive call goes through the LOD ladder, not the truck path.)
|
||||
|
||||
let style_name = &dim.base().style_name;
|
||||
let style = document.dim_styles.iter().find(|s| {
|
||||
let source_style = document.dim_styles.iter().find(|s| {
|
||||
s.name.eq_ignore_ascii_case(style_name)
|
||||
|| (style_name.trim().is_empty() && s.name.eq_ignore_ascii_case("Standard"))
|
||||
});
|
||||
let mut effective_style = source_style.cloned();
|
||||
if let Some(style) = &mut effective_style {
|
||||
use crate::entities::dim_override as ov;
|
||||
let data = &dim.base().common.extended_data;
|
||||
macro_rules! real {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::real(data, ov::$code) {
|
||||
style.$field = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! int {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::int(data, ov::$code) {
|
||||
style.$field = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! flag {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::int(data, ov::$code) {
|
||||
style.$field = value != 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! handle {
|
||||
($field:ident, $code:ident) => {
|
||||
if let Some(value) = ov::handle(data, ov::$code) {
|
||||
style.$field = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
real!(dimscale, DIMSCALE);
|
||||
real!(dimasz, DIMASZ);
|
||||
real!(dimexo, DIMEXO);
|
||||
real!(dimdli, DIMDLI);
|
||||
real!(dimexe, DIMEXE);
|
||||
real!(dimrnd, DIMRND);
|
||||
real!(dimdle, DIMDLE);
|
||||
real!(dimtp, DIMTP);
|
||||
real!(dimtm, DIMTM);
|
||||
real!(dimfxl, DIMFXL);
|
||||
real!(dimjogang, DIMJOGANG);
|
||||
real!(dimtxt, DIMTXT);
|
||||
real!(dimcen, DIMCEN);
|
||||
real!(dimtsz, DIMTSZ);
|
||||
real!(dimaltf, DIMALTF);
|
||||
real!(dimlfac, DIMLFAC);
|
||||
real!(dimtvp, DIMTVP);
|
||||
real!(dimtfac, DIMTFAC);
|
||||
real!(dimgap, DIMGAP);
|
||||
real!(dimaltrnd, DIMALTRND);
|
||||
flag!(dimtol, DIMTOL);
|
||||
flag!(dimlim, DIMLIM);
|
||||
flag!(dimtih, DIMTIH);
|
||||
flag!(dimtoh, DIMTOH);
|
||||
flag!(dimse1, DIMSE1);
|
||||
flag!(dimse2, DIMSE2);
|
||||
flag!(dimalt, DIMALT);
|
||||
flag!(dimtofl, DIMTOFL);
|
||||
flag!(dimsah, DIMSAH);
|
||||
flag!(dimtix, DIMTIX);
|
||||
flag!(dimsoxd, DIMSOXD);
|
||||
flag!(dimsd1, DIMSD1);
|
||||
flag!(dimsd2, DIMSD2);
|
||||
flag!(dimupt, DIMUPT);
|
||||
flag!(dimfxlon, DIMFXLON);
|
||||
flag!(dimtxtdirection, DIMTXTDIRECTION);
|
||||
int!(dimzin, DIMZIN);
|
||||
int!(dimazin, DIMAZIN);
|
||||
int!(dimarcsym, DIMARCSYM);
|
||||
int!(dimclrd, DIMCLRD);
|
||||
int!(dimclre, DIMCLRE);
|
||||
int!(dimclrt, DIMCLRT);
|
||||
int!(dimadec, DIMADEC);
|
||||
int!(dimaltd, DIMALTD);
|
||||
int!(dimdec, DIMDEC);
|
||||
int!(dimtdec, DIMTDEC);
|
||||
int!(dimaltu, DIMALTU);
|
||||
int!(dimalttd, DIMALTTD);
|
||||
int!(dimaunit, DIMAUNIT);
|
||||
int!(dimfrac, DIMFRAC);
|
||||
int!(dimlunit, DIMLUNIT);
|
||||
int!(dimdsep, DIMDSEP);
|
||||
int!(dimtmove, DIMTMOVE);
|
||||
int!(dimjust, DIMJUST);
|
||||
int!(dimtolj, DIMTOLJ);
|
||||
int!(dimtzin, DIMTZIN);
|
||||
int!(dimaltz, DIMALTZ);
|
||||
int!(dimalttz, DIMALTTZ);
|
||||
int!(dimatfit, DIMATFIT);
|
||||
int!(dimtfill, DIMTFILL);
|
||||
int!(dimtfillclr, DIMTFILLCLR);
|
||||
int!(dimlwd, DIMLWD);
|
||||
int!(dimlwe, DIMLWE);
|
||||
handle!(dimldrblk, DIMLDRBLK);
|
||||
handle!(dimblk, DIMBLK);
|
||||
handle!(dimblk1, DIMBLK1);
|
||||
handle!(dimblk2, DIMBLK2);
|
||||
handle!(dimltex_handle, DIMLTYPE);
|
||||
handle!(dimltex1_handle, DIMLTEX1);
|
||||
handle!(dimltex2_handle, DIMLTEX2);
|
||||
if let Some(value) = ov::string(data, ov::DIMPOST) {
|
||||
style.dimpost = value;
|
||||
}
|
||||
if let Some(value) = ov::string(data, ov::DIMAPOST) {
|
||||
style.dimapost = value;
|
||||
}
|
||||
if let Some(value) = ov::handle(data, ov::DIMTXSTY) {
|
||||
style.dimtxsty_handle = value;
|
||||
if let Some(record) = document.text_styles.iter().find(|record| record.handle == value) {
|
||||
style.dimtxsty = record.name.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
let style = effective_style.as_ref();
|
||||
|
||||
// DIMSCALE rule:
|
||||
// dimstyle.dimscale > 0 → final multiplier; ignore anno_scale.
|
||||
|
|
@ -1655,7 +1750,7 @@ fn tessellate_dimension_inner(
|
|||
// preserved on save:
|
||||
// - base.insertion_point: legacy anchor reference; render uses
|
||||
// text_middle_point + dim-line geometry instead.
|
||||
// - base.block_name: AutoCAD-style "*D..." anonymous block name for
|
||||
// - base.block_name: generated anonymous block name for
|
||||
// the dim graphics — we re-tessellate so don't need it.
|
||||
// - base.version: DXF format marker (metadata only).
|
||||
let _ = (
|
||||
|
|
@ -2391,7 +2486,7 @@ fn append_linear_dimension(
|
|||
|
||||
// DIMDLE: dim line overshoots the ext line by `dimdle` at each end,
|
||||
// but only when ticks are in use (DIMTSZ > 0). With arrowheads this
|
||||
// is ignored, matching AutoCAD.
|
||||
// is ignored.
|
||||
let dle = if params.ticks { params.dimdle } else { 0.0 };
|
||||
let dir_d1_to_d2 = normalized_or(d2 - d1, axis);
|
||||
let d1_out = d1 - dir_d1_to_d2 * dle;
|
||||
|
|
@ -2404,30 +2499,50 @@ fn append_linear_dimension(
|
|||
let gap = (d2 - d1).length();
|
||||
let arrows_outside = !params.ticks && params.arrow_len > 1e-6 && gap < 2.0 * params.arrow_len;
|
||||
|
||||
// DIMSD1/DIMSD2: when *both* set, omit the dim line entirely. AutoCAD
|
||||
// splits at text otherwise — without that pivot info, leave as-is.
|
||||
if !(suppress.dim1 && suppress.dim2) {
|
||||
// Break the dim line where the text sits on it, so a DIMTFILL
|
||||
// background reads over the line (2-D fills draw under all wires, so the
|
||||
// line is gapped rather than z-masked).
|
||||
let mut drew = false;
|
||||
if let Some((tc, half_w, half_h)) = params.text_break {
|
||||
let dir = normalized_or(d2_out - d1_out, axis);
|
||||
let len = (d2_out - d1_out).length();
|
||||
let along = (tc - d1_out).dot(dir);
|
||||
let perp_dist = (tc - (d1_out + dir * along)).length();
|
||||
if perp_dist < half_h && along - half_w > 0.0 && along + half_w < len {
|
||||
add_segment(&mut g.dim_lines, d1_out, d1_out + dir * (along - half_w));
|
||||
add_segment(&mut g.dim_lines, d1_out + dir * (along + half_w), d2_out);
|
||||
drew = true;
|
||||
// The two suppression flags address the portions at the first and second
|
||||
// measured points independently. The text gap is also the natural split;
|
||||
// when there is no gap, split at the projected text position or midpoint.
|
||||
let line_dir = normalized_or(d2_out - d1_out, axis);
|
||||
let line_len = (d2_out - d1_out).length();
|
||||
let mut split = line_len * 0.5;
|
||||
let mut left_end = split;
|
||||
let mut right_start = split;
|
||||
if let Some((text_center, half_width, half_height)) = params.text_break {
|
||||
let along = (text_center - d1_out).dot(line_dir);
|
||||
if along > 0.0 && along < line_len {
|
||||
split = along;
|
||||
left_end = split;
|
||||
right_start = split;
|
||||
let perpendicular = (text_center - (d1_out + line_dir * along)).length();
|
||||
if perpendicular < half_height
|
||||
&& along - half_width > 0.0
|
||||
&& along + half_width < line_len
|
||||
{
|
||||
left_end = along - half_width;
|
||||
right_start = along + half_width;
|
||||
}
|
||||
}
|
||||
if !drew {
|
||||
add_segment(&mut g.dim_lines, d1_out, d2_out);
|
||||
}
|
||||
if arrows_outside && !params.dimsoxd {
|
||||
let stub = params.arrow_len * 2.0;
|
||||
}
|
||||
if !suppress.dim1 && left_end > 1e-6 {
|
||||
add_segment(
|
||||
&mut g.dim_lines,
|
||||
d1_out,
|
||||
d1_out + line_dir * left_end,
|
||||
);
|
||||
}
|
||||
if !suppress.dim2 && line_len - right_start > 1e-6 {
|
||||
add_segment(
|
||||
&mut g.dim_lines,
|
||||
d1_out + line_dir * right_start,
|
||||
d2_out,
|
||||
);
|
||||
}
|
||||
if arrows_outside && !params.dimsoxd {
|
||||
let stub = params.arrow_len * 2.0;
|
||||
if !suppress.dim1 {
|
||||
add_segment(&mut g.dim_lines, d1 - dir_d1_to_d2 * stub, d1);
|
||||
}
|
||||
if !suppress.dim2 {
|
||||
add_segment(&mut g.dim_lines, d2, d2 + dir_d1_to_d2 * stub);
|
||||
}
|
||||
}
|
||||
|
|
@ -2838,8 +2953,8 @@ fn dimension_text_parts(
|
|||
let base = dim.base();
|
||||
let is_angular = matches!(dim, Dimension::Angular2Ln(_) | Dimension::Angular3Pt(_));
|
||||
|
||||
// Auto-generated body (the value AutoCAD would emit if the user did not
|
||||
// override it). Built first so user_text "<>" substitution can re-use it.
|
||||
// Auto-generated body used when the user did not override it. Built first
|
||||
// so user_text "<>" substitution can re-use it.
|
||||
let primary_raw = if is_angular {
|
||||
format_angular_value(dim.measurement(), style)
|
||||
} else {
|
||||
|
|
@ -3168,7 +3283,7 @@ fn format_fractional(value: f64, dimfrac: i16) -> String {
|
|||
}
|
||||
|
||||
/// Power-of-two denominator for architectural / fractional output. DIMFRAC is
|
||||
/// the exponent-ish knob AutoCAD pairs with DIMLUNIT; clamp it to a readable
|
||||
/// the exponent-like fraction-format knob; clamp it to a readable
|
||||
/// range (16ths … 1024ths).
|
||||
fn arch_denom(dimfrac: i16) -> u64 {
|
||||
let exp = (dimfrac.clamp(0, 8) as u32).max(2) + 2; // 4..=10 → 16..=1024
|
||||
|
|
|
|||
|
|
@ -2982,6 +2982,188 @@ pub(super) fn message_id(source: &str) -> Option<&'static str> {
|
|||
"── Custom Overrides (SHORTCUTS SET) ──────────────────" => Some("catalog-custom-overrides-shortcuts-set-07be563dec"),
|
||||
"── Function Keys ──────────────────────────────────────" => Some("catalog-function-keys-b5a2df24e9"),
|
||||
"── Other Keys ──────────────────────────────────────────" => Some("catalog-other-keys-a882812cf2"),
|
||||
"Always keep text between extension lines" => Some("dimstyle-keep-text-between-extension-lines"),
|
||||
"Angular dimensions" => Some("dimstyle-angular-dimensions"),
|
||||
"Arc length symbol" => Some("dimstyle-arc-length-symbol"),
|
||||
"Arrowheads" => Some("dimstyle-arrowheads"),
|
||||
"Available style" => Some("dimstyle-available-style"),
|
||||
"Baseline spacing" => Some("dimstyle-baseline-spacing"),
|
||||
"Basic" => Some("dimstyle-basic"),
|
||||
"Both arrowheads" => Some("dimstyle-both-arrowheads"),
|
||||
"Center mark" => Some("dimstyle-center-mark"),
|
||||
"Center mark size" => Some("dimstyle-center-mark-size"),
|
||||
"Center marks" => Some("dimstyle-center-marks"),
|
||||
"Centerlines" => Some("dimstyle-centerlines"),
|
||||
"Compare with" => Some("dimstyle-compare-with"),
|
||||
"Current style" => Some("dimstyle-current-style"),
|
||||
"Deviation" => Some("dimstyle-deviation"),
|
||||
"Different sections" => Some("dimstyle-different-sections"),
|
||||
"Dimension line color" => Some("dimstyle-dimension-line-color"),
|
||||
"Dimension linetype" => Some("dimstyle-dimension-linetype"),
|
||||
"Dimension lineweight" => Some("dimstyle-dimension-lineweight"),
|
||||
"Display alternate units" => Some("dimstyle-display-alternate-units"),
|
||||
"Draw dimension line between extension lines" => Some("dimstyle-draw-dimension-line-between-extension-lines"),
|
||||
"Extend beyond dimension line" => Some("dimstyle-extend-beyond-dimension-line"),
|
||||
"Extend beyond ticks" => Some("dimstyle-extend-beyond-ticks"),
|
||||
"Extension line color" => Some("dimstyle-extension-line-color"),
|
||||
"Extension lineweight" => Some("dimstyle-extension-lineweight"),
|
||||
"Feet and inches" => Some("dimstyle-feet-and-inches"),
|
||||
"Fine tuning" => Some("dimstyle-fine-tuning"),
|
||||
"First arrowhead" => Some("dimstyle-first-arrowhead"),
|
||||
"First extension linetype" => Some("dimstyle-first-extension-linetype"),
|
||||
"Fit options" => Some("dimstyle-fit-options"),
|
||||
"Fixed length" => Some("dimstyle-fixed-length"),
|
||||
"Fraction format" => Some("dimstyle-fraction-format"),
|
||||
"Height scale" => Some("dimstyle-height-scale"),
|
||||
"Horizontal placement" => Some("dimstyle-horizontal-placement"),
|
||||
"Keep text horizontal when inside" => Some("dimstyle-keep-text-horizontal-inside"),
|
||||
"Keep text horizontal when outside" => Some("dimstyle-keep-text-horizontal-outside"),
|
||||
"Leader arrowhead" => Some("dimstyle-leader-arrowhead"),
|
||||
"Limits" => Some("dimstyle-limits"),
|
||||
"Linear dimensions" => Some("dimstyle-linear-dimensions"),
|
||||
"Lower value" => Some("dimstyle-lower-value"),
|
||||
"Measurement scale" => Some("dimstyle-measurement-scale"),
|
||||
"Measurement template" => Some("dimstyle-measurement-template"),
|
||||
"Method" => Some("dimstyle-method"),
|
||||
"Multiplier" => Some("dimstyle-multiplier"),
|
||||
"No differences" => Some("dimstyle-no-differences"),
|
||||
"Not applicable" => Some("dimstyle-not-applicable"),
|
||||
"Offset from measured point" => Some("dimstyle-offset-from-measured-point"),
|
||||
"Place text manually while creating dimensions" => Some("dimstyle-place-text-manually"),
|
||||
"Radius jog angle (°)" => Some("dimstyle-radius-jog-angle"),
|
||||
"Read left to right" => Some("dimstyle-read-left-to-right"),
|
||||
"Referenced style · Read only" => Some("dimstyle-referenced-read-only"),
|
||||
"Round off" => Some("dimstyle-round-off"),
|
||||
"Second arrowhead" => Some("dimstyle-second-arrowhead"),
|
||||
"Second extension linetype" => Some("dimstyle-second-extension-linetype"),
|
||||
"Show zero feet and zero inches" => Some("dimstyle-show-zero-feet-and-inches"),
|
||||
"Show zero feet; suppress zero inches" => Some("dimstyle-show-zero-feet-suppress-zero-inches"),
|
||||
"Suppress arrows when they do not fit" => Some("dimstyle-suppress-arrows-when-no-fit"),
|
||||
"Suppress first dimension line" => Some("dimstyle-suppress-first-dimension-line"),
|
||||
"Suppress first extension line" => Some("dimstyle-suppress-first-extension-line"),
|
||||
"Suppress second dimension line" => Some("dimstyle-suppress-second-dimension-line"),
|
||||
"Suppress second extension line" => Some("dimstyle-suppress-second-extension-line"),
|
||||
"Suppress zero feet and zero inches" => Some("dimstyle-suppress-zero-feet-and-inches"),
|
||||
"Suppress zero feet; show zero inches" => Some("dimstyle-suppress-zero-feet-show-zero-inches"),
|
||||
"Symbols and Arrows" => Some("dimstyle-symbols-and-arrows"),
|
||||
"Symmetrical" => Some("dimstyle-symmetrical"),
|
||||
"Text background" => Some("dimstyle-text-background"),
|
||||
"Text gap" => Some("dimstyle-text-gap"),
|
||||
"The selected text style fixes the height at %{height}." => Some("dimstyle-fixed-text-height-note"),
|
||||
"Tick size" => Some("dimstyle-tick-size"),
|
||||
"Tolerance zero suppression" => Some("dimstyle-tolerance-zero-suppression"),
|
||||
"Unit format" => Some("dimstyle-unit-format"),
|
||||
"Upper value" => Some("dimstyle-upper-value"),
|
||||
"Use <> as the measured value; text before and after it becomes the prefix and suffix." => Some("dimstyle-measurement-template-help"),
|
||||
"Use different first and second arrowheads" => Some("dimstyle-use-different-arrowheads"),
|
||||
"Use fixed-length extension lines" => Some("dimstyle-use-fixed-length-extension-lines"),
|
||||
"Used in drawing" => Some("dimstyle-used-in-drawing"),
|
||||
"Vertical offset" => Some("dimstyle-vertical-offset"),
|
||||
"Vertical placement" => Some("dimstyle-vertical-placement"),
|
||||
"Vertical position" => Some("dimstyle-vertical-position"),
|
||||
"When space is limited" => Some("dimstyle-when-space-is-limited"),
|
||||
"When text is moved" => Some("dimstyle-when-text-is-moved"),
|
||||
"Zero suppression" => Some("dimstyle-zero-suppression"),
|
||||
"Add a leader" => Some("dimstyle-add-a-leader"),
|
||||
"Automatic" => Some("dimstyle-automatic"),
|
||||
"By block" => Some("dimstyle-by-block"),
|
||||
"Comma" => Some("dimstyle-comma"),
|
||||
"Degrees, minutes, seconds" => Some("dimstyle-degrees-minutes-seconds"),
|
||||
"Keep dimension line with text" => Some("dimstyle-keep-dimension-line-with-text"),
|
||||
"Leading and trailing" => Some("dimstyle-leading-and-trailing"),
|
||||
"Move arrows outside first" => Some("dimstyle-move-arrows-outside-first"),
|
||||
"Move text and arrows outside" => Some("dimstyle-move-text-and-arrows-outside"),
|
||||
"Move text freely" => Some("dimstyle-move-text-freely"),
|
||||
"Move text outside first" => Some("dimstyle-move-text-outside-first"),
|
||||
"Period" => Some("dimstyle-period"),
|
||||
"Space" => Some("dimstyle-space"),
|
||||
"Alignment spacing" => Some("style-manager-alignment-spacing"),
|
||||
"Always left align" => Some("style-manager-always-left-align"),
|
||||
"Attachment direction" => Some("style-manager-attachment-direction"),
|
||||
"Background fill enabled" => Some("style-manager-background-fill-enabled"),
|
||||
"Big font" => Some("style-manager-big-font"),
|
||||
"Block scale X" => Some("style-manager-block-scale-x"),
|
||||
"Block scale Y" => Some("style-manager-block-scale-y"),
|
||||
"Block scale Z" => Some("style-manager-block-scale-z"),
|
||||
"Borders" => Some("style-manager-borders"),
|
||||
"Bottom attachment" => Some("style-manager-bottom-attachment"),
|
||||
"Break gap size" => Some("style-manager-break-gap-size"),
|
||||
"Caps and Fill" => Some("style-manager-caps-and-fill"),
|
||||
"Content type" => Some("style-manager-content-type"),
|
||||
"Data Row" => Some("style-manager-data-row"),
|
||||
"Data type" => Some("style-manager-data-type"),
|
||||
"Default text" => Some("style-manager-default-text"),
|
||||
"Different" => Some("style-manager-different"),
|
||||
"Display joints" => Some("style-manager-display-joints"),
|
||||
"Drawing height" => Some("style-manager-drawing-height"),
|
||||
"Drawing scale" => Some("style-manager-drawing-scale"),
|
||||
"Effects" => Some("style-manager-effects"),
|
||||
"Elements" => Some("style-manager-elements"),
|
||||
"End caps" => Some("style-manager-end-caps"),
|
||||
"Fill and joints" => Some("style-manager-fill-and-joints"),
|
||||
"Fill enabled" => Some("style-manager-fill-enabled"),
|
||||
"First segment angle" => Some("style-manager-first-segment-angle"),
|
||||
"Fixed height" => Some("style-manager-fixed-height"),
|
||||
"Flow direction" => Some("style-manager-flow-direction"),
|
||||
"Font file" => Some("style-manager-font-file"),
|
||||
"Fonts" => Some("style-manager-fonts"),
|
||||
"Format string" => Some("style-manager-format-string"),
|
||||
"Header" => Some("style-manager-header"),
|
||||
"Header Row" => Some("style-manager-header-row"),
|
||||
"Horizontal margin" => Some("style-manager-horizontal-margin"),
|
||||
"Inner arcs" => Some("style-manager-inner-arcs"),
|
||||
"Inside horizontal" => Some("style-manager-inside-horizontal"),
|
||||
"Inside vertical" => Some("style-manager-inside-vertical"),
|
||||
"Leader draw order" => Some("style-manager-leader-draw-order"),
|
||||
"Leader note" => Some("style-manager-leader-note"),
|
||||
"Left attachment" => Some("style-manager-left-attachment"),
|
||||
"Line color" => Some("style-manager-line-color"),
|
||||
"Line type" => Some("style-manager-line-type"),
|
||||
"Line weight" => Some("style-manager-line-weight"),
|
||||
"Maximum leader points" => Some("style-manager-maximum-leader-points"),
|
||||
"Multileader draw order" => Some("style-manager-multileader-draw-order"),
|
||||
"No preview" => Some("style-manager-no-preview"),
|
||||
"Oblique angle" => Some("style-manager-oblique-angle"),
|
||||
"Outer arc" => Some("style-manager-outer-arc"),
|
||||
"Paper height" => Some("style-manager-paper-height"),
|
||||
"Paper text height" => Some("style-manager-paper-text-height"),
|
||||
"Path type" => Some("style-manager-path-type"),
|
||||
"Right attachment" => Some("style-manager-right-attachment"),
|
||||
"Scale factor" => Some("style-manager-scale-factor"),
|
||||
"Second segment angle" => Some("style-manager-second-segment-angle"),
|
||||
"Size and Effects" => Some("style-manager-size-and-effects"),
|
||||
"Start caps" => Some("style-manager-start-caps"),
|
||||
"Stroke fonts" => Some("style-manager-stroke-fonts"),
|
||||
"Suppress header row" => Some("style-manager-suppress-header-row"),
|
||||
"Suppress title row" => Some("style-manager-suppress-title-row"),
|
||||
"System font" => Some("style-manager-system-font"),
|
||||
"System fonts" => Some("style-manager-system-fonts"),
|
||||
"Text alignment" => Some("style-manager-text-alignment"),
|
||||
"Text angle" => Some("style-manager-text-angle"),
|
||||
"Title Row" => Some("style-manager-title-row"),
|
||||
"Top attachment" => Some("style-manager-top-attachment"),
|
||||
"Unit type" => Some("style-manager-unit-type"),
|
||||
"Vertical margin" => Some("style-manager-vertical-margin"),
|
||||
"font family…" => Some("style-manager-font-family-placeholder"),
|
||||
"Bottom to top" => Some("style-manager-bottom-to-top"),
|
||||
"Arrowhead first" => Some("style-manager-arrowhead-first"),
|
||||
"Content first" => Some("style-manager-content-first"),
|
||||
"Leader first" => Some("style-manager-leader-first"),
|
||||
"Straight" => Some("style-manager-straight"),
|
||||
"Parallel to last segment" => Some("style-manager-parallel-last-segment"),
|
||||
"Top of top line" => Some("style-manager-top-of-top-line"),
|
||||
"Middle of top line" => Some("style-manager-middle-of-top-line"),
|
||||
"Middle of text" => Some("style-manager-middle-of-text"),
|
||||
"Middle of bottom line" => Some("style-manager-middle-of-bottom-line"),
|
||||
"Bottom of bottom line" => Some("style-manager-bottom-of-bottom-line"),
|
||||
"Bottom line" => Some("style-manager-bottom-line"),
|
||||
"Underline bottom line" => Some("style-manager-underline-bottom-line"),
|
||||
"Underline top line" => Some("style-manager-underline-top-line"),
|
||||
"Underline all text" => Some("style-manager-underline-all-text"),
|
||||
"Center of text" => Some("style-manager-center-of-text"),
|
||||
"Center of text with overline" => Some("style-manager-center-of-text-overline"),
|
||||
"Block extents" => Some("style-manager-block-extents"),
|
||||
"Base point" => Some("style-manager-base-point"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
119
src/scene/cache/block_cache.rs
vendored
119
src/scene/cache/block_cache.rs
vendored
|
|
@ -28,7 +28,7 @@ const MAX_NESTING_DEPTH: usize = 32;
|
|||
/// Skip wires whose world-AABB projects to fewer than this many pixels in
|
||||
/// the active view. Picks up tiny detail at zoom-out so the tessellator
|
||||
/// doesn't waste time on geometry that contributes a few sub-pixel marks
|
||||
/// to the final image. 2 px is the AutoCAD-default "small element" floor
|
||||
/// to the final image. Two pixels is a practical small-element floor:
|
||||
/// — visibly the same image, dramatically fewer wires.
|
||||
const MIN_PIXEL_SIZE: f32 = 2.0;
|
||||
|
||||
|
|
@ -426,66 +426,16 @@ fn build_defn(
|
|||
nested_ins, doc, bg_color, depth_map,
|
||||
)));
|
||||
}
|
||||
// A dimension nested in a block bakes its geometry (extension /
|
||||
// dim lines, arrows, text) into a per-instance `*D` block, exactly
|
||||
// like a top-level dimension. The top-level path expands that block
|
||||
// in `tessellate_entity`; the block-expand path calls the plain
|
||||
// `tessellate::tessellate`, which does NOT, so nested dimensions
|
||||
// drew nothing. Expand the `*D` block's entities here as block-local
|
||||
// subs so they transform with the parent insert. (Empty block_name
|
||||
// — a non-baked dimension — falls through to the default arm.)
|
||||
EntityType::Dimension(dim)
|
||||
if !dim.base().block_name.trim().is_empty()
|
||||
&& !crate::entities::dimension::uses_custom_arrow_blocks(doc, dim) =>
|
||||
{
|
||||
let dblk = doc
|
||||
.block_records
|
||||
.iter()
|
||||
.find(|br| br.name.eq_ignore_ascii_case(&dim.base().block_name));
|
||||
if let Some(dblk) = dblk {
|
||||
// The `*D` block content is baked in the coordinate space it
|
||||
// occupied when the dimension was created — for a dimension
|
||||
// inside a block that is often the ORIGINAL WCS, not the
|
||||
// block-local space. The dimension's insertion_point (DXF
|
||||
// 12) is the offset that maps the baked content into the
|
||||
// dimension's own (block-local) space; it is zero for
|
||||
// dimensions baked in place, so this is a no-op there.
|
||||
let ins = dim.base().insertion_point;
|
||||
for &deh in &dblk.entity_handles {
|
||||
let Some(dsub) = doc.get_entity(deh) else {
|
||||
continue;
|
||||
};
|
||||
// Definition points are baked as POINTs on Defpoints —
|
||||
// grip markers, never drawn (matches the top-level path).
|
||||
if matches!(dsub, EntityType::Point(_)) {
|
||||
continue;
|
||||
}
|
||||
if dsub.common().invisible || layer_hidden(doc, &dsub.common().layer) {
|
||||
continue;
|
||||
}
|
||||
let mut placed = dsub.clone();
|
||||
placed.as_entity_mut().translate(ins);
|
||||
// An arrowhead is baked as a nested INSERT of an arrow
|
||||
// block — route it through the nested-ref machinery so
|
||||
// the arrow block expands (tessellate_sub_local doesn't
|
||||
// expand inserts).
|
||||
if let EntityType::Insert(arrow) = &placed {
|
||||
subs.push(LocalSub::Nested(build_nested_ref(
|
||||
arrow, doc, bg_color, depth_map,
|
||||
)));
|
||||
} else {
|
||||
for lw in tessellate_sub_local(
|
||||
doc,
|
||||
&placed,
|
||||
anno_scale,
|
||||
annotation_scale_handle,
|
||||
bg_color,
|
||||
depth_map,
|
||||
) {
|
||||
subs.push(LocalSub::Wire(lw));
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityType::Dimension(_) => {
|
||||
for wire in tessellate_sub_local(
|
||||
doc,
|
||||
entity,
|
||||
anno_scale,
|
||||
annotation_scale_handle,
|
||||
bg_color,
|
||||
depth_map,
|
||||
) {
|
||||
subs.push(LocalSub::Wire(wire));
|
||||
}
|
||||
}
|
||||
// A table nested in a block bakes its geometry (gridlines, cell
|
||||
|
|
@ -706,21 +656,38 @@ fn tessellate_sub_local(
|
|||
// Pass `local_offset` as the f64 world-offset so tessellate subtracts it
|
||||
// before casting to f32 — same precision-preservation trick used for
|
||||
// top-level entities, applied per-defn.
|
||||
let wires_out = tessellate::tessellate(
|
||||
doc,
|
||||
h,
|
||||
sub,
|
||||
false,
|
||||
sub_color,
|
||||
pat_len,
|
||||
pat,
|
||||
lw_px,
|
||||
anno_scale,
|
||||
annotation_scale_handle,
|
||||
None,
|
||||
bg_color,
|
||||
false,
|
||||
);
|
||||
let wires_out = if let EntityType::Dimension(dimension) = sub {
|
||||
use crate::entities::dimension::DimensionTess;
|
||||
dimension.tessellate(
|
||||
doc,
|
||||
h,
|
||||
false,
|
||||
sub_color,
|
||||
lw_px,
|
||||
anno_scale,
|
||||
&HashSet::default(),
|
||||
None,
|
||||
bg_color,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
tessellate::tessellate(
|
||||
doc,
|
||||
h,
|
||||
sub,
|
||||
false,
|
||||
sub_color,
|
||||
pat_len,
|
||||
pat,
|
||||
lw_px,
|
||||
anno_scale,
|
||||
annotation_scale_handle,
|
||||
None,
|
||||
bg_color,
|
||||
false,
|
||||
)
|
||||
};
|
||||
if wires_out.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -543,8 +543,8 @@ pub(crate) fn tessellate_entity(
|
|||
// An entity from an application we have no reader for (e.g. an Autodesk
|
||||
// Raster Design embedded raster image) arrives as `Unknown`. Its own data is
|
||||
// a private format we cannot decode — but it usually ships a proxy-graphics
|
||||
// blob, the vector preview its author cached for exactly this case. AutoCAD
|
||||
// draws that when the object enabler is missing; draw it too, so the entity
|
||||
// blob, the vector preview its author cached for exactly this case. Draw it
|
||||
// when the object enabler is missing, so the entity
|
||||
// occupies its real place instead of silently disappearing.
|
||||
let proxy_blob: Option<std::borrow::Cow<'_, [u8]>> = match e {
|
||||
EntityType::Unknown(_) => e
|
||||
|
|
@ -665,7 +665,7 @@ pub(crate) fn tessellate_entity(
|
|||
//
|
||||
// The DWG reader decodes the two cut-line endpoints, the signed end ticks
|
||||
// and the identifier. Synthesize the end ticks + arrowheads + label glyphs
|
||||
// so the mark is visible on the layout, the way AutoCAD draws it. The raw
|
||||
// so the mark is visible on the layout. The raw
|
||||
// record is still preserved for lossless write-back.
|
||||
if let EntityType::SectionSymbol(s) = e {
|
||||
return section_symbol_wires(
|
||||
|
|
@ -736,118 +736,6 @@ pub(crate) fn tessellate_entity(
|
|||
}];
|
||||
}
|
||||
|
||||
// ── Dimension baked-block fast path ─────────────────────────────────────
|
||||
//
|
||||
// A saved dimension may carry final geometry (extension lines, dim line,
|
||||
// arrows and text) in a per-instance block — usually
|
||||
// `*D<n>`, but custom names like `DIMBLOCK###-4NP` also occur. When the
|
||||
// block exists we render its contents through `tessellate_entity` so
|
||||
// sub-Text/MText get the standard baseline/greek/full LOD ladder, and
|
||||
// DIMTXT × DIMSCALE isn't re-applied on already-baked geometry.
|
||||
if let EntityType::Dimension(dim) = e {
|
||||
let block_name = &dim.base().block_name;
|
||||
if !block_name.trim().is_empty()
|
||||
&& !crate::entities::dimension::uses_custom_arrow_blocks(document, dim)
|
||||
{
|
||||
if let Some(br) = document
|
||||
.block_records
|
||||
.iter()
|
||||
.find(|br| br.name.eq_ignore_ascii_case(block_name))
|
||||
{
|
||||
if !br.entity_handles.is_empty() {
|
||||
let mut wires: Vec<WireModel> = Vec::with_capacity(br.entity_handles.len());
|
||||
// The Dimension's own layer style — layer-0 inheritance
|
||||
// target for baked sub-entities on layer "0" (#221).
|
||||
let dim_l0_color = view::render::adapt_to_bg(
|
||||
view::render::layer_render_style(document, &e.common().layer).color,
|
||||
bg_color,
|
||||
);
|
||||
let dim_l0_aci = document
|
||||
.layers
|
||||
.get(&e.common().layer)
|
||||
.map(|l| match &l.color {
|
||||
acadrust::types::Color::Index(i) => *i,
|
||||
_ => 0,
|
||||
})
|
||||
.unwrap_or(0);
|
||||
for &eh in &br.entity_handles {
|
||||
let Some(sub) = document.get_entity(eh) else {
|
||||
continue;
|
||||
};
|
||||
// A dimension's definition points are baked into the
|
||||
// block as POINTs on the Defpoints layer. They are grip
|
||||
// markers rather than PDMODE display geometry, so
|
||||
// geometry — so rendering them adds a stray tick at each
|
||||
// measured point that makes the extension lines look like
|
||||
// they run past the geometry. Skip them.
|
||||
if matches!(sub, EntityType::Point(_)) {
|
||||
continue;
|
||||
}
|
||||
// Sub-entities inside *D### / DIMBLOCK## blocks
|
||||
// typically use ByBlock color/linetype/lineweight —
|
||||
// they should inherit from the Dimension entity.
|
||||
let has_book_color =
|
||||
view::render::has_resolved_book_color(document, sub);
|
||||
let sub_color_is_byblock = !has_book_color
|
||||
&& sub.common().color == acadrust::types::Color::ByBlock;
|
||||
let sub_is_l0_bylayer =
|
||||
!has_book_color
|
||||
&& view::render::is_effective_layer_zero(&sub.common().layer)
|
||||
&& sub.common().color == acadrust::types::Color::ByLayer;
|
||||
let sub_wires = tessellate_entity(
|
||||
document,
|
||||
selected,
|
||||
active_viewport,
|
||||
bg_color,
|
||||
// Block contents are baked at the final WCS size —
|
||||
// don't let downstream paths re-apply anno_scale.
|
||||
1.0,
|
||||
None,
|
||||
sub,
|
||||
block_cache,
|
||||
view_aabb,
|
||||
world_per_pixel,
|
||||
paper_space,
|
||||
);
|
||||
for mut w in sub_wires {
|
||||
w.name = h.value().to_string();
|
||||
// Override ByBlock colour with the dim's resolved
|
||||
// colour so text matches `DIMCLRT`-style behaviour
|
||||
// (or layer colour) instead of the raw ByBlock
|
||||
// fallback that render_style_for produces. A layer-0
|
||||
// sub inherits the dim's layer colour instead.
|
||||
if sub_color_is_byblock {
|
||||
w.color = if sel {
|
||||
WireModel::SELECTED
|
||||
} else {
|
||||
entity_color
|
||||
};
|
||||
w.aci = aci;
|
||||
} else if sub_is_l0_bylayer && !sel {
|
||||
w.color = dim_l0_color;
|
||||
w.aci = dim_l0_aci;
|
||||
}
|
||||
wires.push(w);
|
||||
}
|
||||
}
|
||||
if !wires.is_empty() {
|
||||
let aabb = entity_aabb(e);
|
||||
for w in &mut wires {
|
||||
// Empty SDF-text cells keep their tight glyph-box
|
||||
// AABB; only stroke/fill wires take the whole-block
|
||||
// box as a broad-phase pick hint.
|
||||
if !w.points.is_empty() || !w.fill_tris.is_empty() {
|
||||
set_wire_aabb(w, aabb);
|
||||
}
|
||||
}
|
||||
return wires;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fall through to the synthesis path below when no block is attached.
|
||||
}
|
||||
|
||||
if let EntityType::Dimension(dim) = e {
|
||||
let aabb = entity_aabb(e);
|
||||
use crate::entities::dimension::DimensionTess;
|
||||
|
|
@ -904,7 +792,7 @@ pub(crate) fn tessellate_entity(
|
|||
|
||||
// ── Table baked-block fast path ─────────────────────────────────────────
|
||||
//
|
||||
// AutoCAD bakes a Table's final rendered geometry (cell text, gridlines,
|
||||
// A table may store final rendered geometry (cell text, gridlines,
|
||||
// fill) into a per-instance block (usually `*T###`) referenced through
|
||||
// `table.block_record_handle`. The block's text uses the *displayed*
|
||||
// height; synthesising cells from `self.rows + TableStyle` instead would
|
||||
|
|
|
|||
|
|
@ -1538,28 +1538,6 @@ pub(crate) fn arrow_from_block(
|
|||
.unwrap_or_else(|| arrow_from_block_name(None, dimasz))
|
||||
}
|
||||
|
||||
pub(crate) fn arrow_block_is_custom(
|
||||
doc: &CadDocument,
|
||||
handle: acadrust::types::Handle,
|
||||
) -> bool {
|
||||
if handle.is_null() {
|
||||
return false;
|
||||
}
|
||||
doc.block_records
|
||||
.iter()
|
||||
.find(|record| record.handle == handle)
|
||||
.is_some_and(|record| {
|
||||
!record.entity_handles.is_empty()
|
||||
&& !record.is_layout()
|
||||
&& !record.is_model_space()
|
||||
&& !record.is_paper_space()
|
||||
&& !record.flags.is_xref
|
||||
&& !record.flags.is_xref_overlay
|
||||
&& !record.flags.is_external
|
||||
&& builtin_arrow_from_block_name(&record.name, 1.0).is_none()
|
||||
})
|
||||
}
|
||||
|
||||
fn arrow_from_block_name(name: Option<&str>, dimasz: f32) -> ArrowKind {
|
||||
name.and_then(|name| builtin_arrow_from_block_name(name, dimasz))
|
||||
.unwrap_or(ArrowKind::Triangle {
|
||||
|
|
@ -1742,6 +1720,10 @@ fn collect_custom_arrow_entity(
|
|||
stack.pop();
|
||||
return;
|
||||
}
|
||||
EntityType::Hatch(hatch) => {
|
||||
append_custom_hatch_fill(hatch, root_base, fill);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
|
@ -1766,6 +1748,69 @@ fn collect_custom_arrow_entity(
|
|||
}
|
||||
}
|
||||
|
||||
fn append_custom_hatch_fill(
|
||||
hatch: &acadrust::entities::Hatch,
|
||||
base: acadrust::types::Vector3,
|
||||
out: &mut Vec<[f32; 3]>,
|
||||
) {
|
||||
use lyon_tessellation::math::point;
|
||||
use lyon_tessellation::path::Path;
|
||||
use lyon_tessellation::{
|
||||
BuffersBuilder, FillOptions, FillRule, FillTessellator, FillVertex, VertexBuffers,
|
||||
};
|
||||
|
||||
let Some(model) = crate::scene::Scene::hatch_model_from_dxf(hatch, [1.0; 4]) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut builder = Path::builder();
|
||||
let mut ring: Vec<[f32; 2]> = Vec::new();
|
||||
let mut finish_ring = |ring: &mut Vec<[f32; 2]>| {
|
||||
if ring.len() >= 3 {
|
||||
builder.begin(point(ring[0][0], ring[0][1]));
|
||||
for p in &ring[1..] {
|
||||
builder.line_to(point(p[0], p[1]));
|
||||
}
|
||||
builder.end(true);
|
||||
}
|
||||
ring.clear();
|
||||
};
|
||||
for &[x, y] in model.boundary.iter() {
|
||||
if x.is_nan() || y.is_nan() {
|
||||
finish_ring(&mut ring);
|
||||
continue;
|
||||
}
|
||||
ring.push([
|
||||
(model.world_origin[0] + x as f64 - base.x) as f32,
|
||||
(model.world_origin[1] + y as f64 - base.y) as f32,
|
||||
]);
|
||||
}
|
||||
finish_ring(&mut ring);
|
||||
|
||||
let mut geometry: VertexBuffers<[f32; 2], u32> = VertexBuffers::new();
|
||||
let mut tessellator = FillTessellator::new();
|
||||
if tessellator
|
||||
.tessellate_path(
|
||||
&builder.build(),
|
||||
&FillOptions::default().with_fill_rule(FillRule::EvenOdd),
|
||||
&mut BuffersBuilder::new(&mut geometry, |vertex: FillVertex| {
|
||||
vertex.position().to_array()
|
||||
}),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return;
|
||||
}
|
||||
let z = -base.z as f32;
|
||||
out.extend(
|
||||
geometry
|
||||
.indices
|
||||
.iter()
|
||||
.filter_map(|&index| geometry.vertices.get(index as usize))
|
||||
.map(|&[x, y]| [x, y, z]),
|
||||
);
|
||||
}
|
||||
|
||||
fn append_custom_wire_points(
|
||||
points: &[[f32; 3]],
|
||||
points_low: &[[f32; 3]],
|
||||
|
|
@ -1928,7 +1973,7 @@ fn fallback_geometry(entity: &EntityType) -> Geometry {
|
|||
|
||||
/// Extract pre-computed edge-wire points from Solid3D / Region / Body entities.
|
||||
///
|
||||
/// AutoCAD stores explicit wire geometry (from SOLVIEW / 3DPLOT) alongside the
|
||||
/// Some drawings store explicit wire geometry alongside the
|
||||
/// ACIS data. We use this as a visible fallback when the SAT tessellator
|
||||
/// produces no mesh (e.g. binary SAB data or unsupported geometry).
|
||||
fn solid_wire_fallback(entity: &EntityType) -> Vec<[f64; 3]> {
|
||||
|
|
@ -2117,7 +2162,7 @@ pub(crate) fn add_polyline(points: &mut Vec<[f32; 3]>, polyline: &[Vec3]) {
|
|||
|
||||
/// Returns the text position of a dimension in DXF world-space (f64, no offset applied).
|
||||
/// Used when building a synthetic Text entity so tessellate() can apply world_offset itself.
|
||||
/// When the saved `text_middle_point` is zero (i.e. AutoCAD never wrote one),
|
||||
/// When the saved `text_middle_point` is zero (no explicit point was written),
|
||||
/// computes a fallback from the dim geometry and applies DIMTAD/DIMGAP.
|
||||
pub(crate) fn normalized_or(v: Vec3, fallback: Vec3) -> Vec3 {
|
||||
if v.length_squared() <= 1e-12 {
|
||||
|
|
|
|||
|
|
@ -1791,7 +1791,7 @@ impl Scene {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn hatch_model_from_dxf(
|
||||
pub(crate) fn hatch_model_from_dxf(
|
||||
dxf: &DxfHatch,
|
||||
color: [f32; 4],
|
||||
) -> Option<HatchModel> {
|
||||
|
|
@ -1814,9 +1814,9 @@ impl Scene {
|
|||
|
||||
for path in &dxf.paths {
|
||||
// Skip TEXTBOX boundary paths (flag bit 3). These are text
|
||||
// bounding-boxes AutoCAD derives for island detection; they are
|
||||
// derived bounding boxes used for island detection; they are
|
||||
// never drawn or filled. Treating one as a fill boundary paints its
|
||||
// rectangle solid — a phantom bar AutoCAD never shows.
|
||||
// rectangle solid and creates a phantom bar.
|
||||
if path.flags.bits() & 8 != 0 {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,103 +1,383 @@
|
|||
//! Multiline Style Manager window — fills the entire OS window.
|
||||
//! Multiline style manager.
|
||||
|
||||
use crate::app::Message;
|
||||
use iced::widget::{column, container, row, scrollable, text};
|
||||
use iced::{Element, Theme};
|
||||
use crate::t;
|
||||
use iced::widget::{button, canvas, checkbox, column, container, row, text, text_input};
|
||||
use iced::{mouse, Color, Element, Length, Point, Rectangle, Theme};
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct MlStyleView<'a> {
|
||||
pub styles: Vec<String>,
|
||||
pub selected: &'a str,
|
||||
pub style: Option<&'a acadrust::objects::MLineStyle>,
|
||||
pub current: String,
|
||||
pub tab: u8,
|
||||
pub compare_name: String,
|
||||
pub compare_opts: Vec<String>,
|
||||
pub comparison_sections: Vec<String>,
|
||||
pub in_use: bool,
|
||||
pub description: &'a str,
|
||||
pub start_angle: &'a str,
|
||||
pub end_angle: &'a str,
|
||||
pub fill_color: &'a str,
|
||||
pub elements: &'a [[String; 3]],
|
||||
pub rename_active: Option<&'a str>,
|
||||
pub rename_buf: &'a str,
|
||||
}
|
||||
|
||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
iced::widget::text::Style {
|
||||
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_window<'a>(
|
||||
styles: Vec<String>,
|
||||
selected: &'a str,
|
||||
selected_style: Option<&'a acadrust::objects::MLineStyle>,
|
||||
current_style: String,
|
||||
rename_active: Option<&'a str>,
|
||||
rename_buf: &'a str,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'a, Message> {
|
||||
// ── Right: Details panel ──────────────────────────────────────────────
|
||||
let info_row = |label: Cow<'static, str>, val: String| -> Element<'_, Message> {
|
||||
row![
|
||||
text(label).size(11).style(muted_style).width(120),
|
||||
text(val).size(11),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
iced::widget::text::Style {
|
||||
color: Some(theme.palette().primary.base.color),
|
||||
}
|
||||
}
|
||||
|
||||
let details: Element<'_, Message> = if let Some(s) = selected_style {
|
||||
let elem_rows: Vec<Element<'_, Message>> = s
|
||||
fn input_row<'a>(
|
||||
label: Cow<'static, str>,
|
||||
placeholder: &'static str,
|
||||
value: &'a str,
|
||||
field: &'static str,
|
||||
) -> Element<'a, Message> {
|
||||
row![
|
||||
text(label).size(11).style(muted_style).width(165),
|
||||
text_input(placeholder, value)
|
||||
.on_input(move |value| Message::MlStyleEdit { field, value })
|
||||
.size(11)
|
||||
.width(190),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn toggle<'a>(label: Cow<'static, str>, value: bool, field: &'static str) -> Element<'a, Message> {
|
||||
checkbox(value)
|
||||
.label(label)
|
||||
.on_toggle(move |_| Message::MlStyleToggle(field))
|
||||
.size(14)
|
||||
.text_size(11)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn aci_color(value: &str, fallback: Color) -> Color {
|
||||
crate::ui::color_select::aci_string_to_color(value)
|
||||
.rgb()
|
||||
.map(|(r, g, b)| Color::from_rgb8(r, g, b))
|
||||
.unwrap_or(fallback)
|
||||
}
|
||||
|
||||
struct MLinePreviewCanvas {
|
||||
description: String,
|
||||
start_angle: String,
|
||||
end_angle: String,
|
||||
fill_color: String,
|
||||
fill: bool,
|
||||
joints: bool,
|
||||
start_square: bool,
|
||||
start_inner: bool,
|
||||
start_round: bool,
|
||||
end_square: bool,
|
||||
end_inner: bool,
|
||||
end_round: bool,
|
||||
elements: Vec<[String; 3]>,
|
||||
}
|
||||
|
||||
fn element_points(offset: f32, bounds: Rectangle) -> [Point; 3] {
|
||||
let y = bounds.height * 0.48 - offset * 26.0;
|
||||
[
|
||||
Point::new(44.0, y),
|
||||
Point::new(bounds.width * 0.52, y - 16.0),
|
||||
Point::new(bounds.width - 44.0, y + 5.0),
|
||||
]
|
||||
}
|
||||
|
||||
fn draw_arc(frame: &mut canvas::Frame, center: Point, radius: f32, start_side: bool, color: Color) {
|
||||
let path = canvas::Path::new(|builder| {
|
||||
for step in 0..=18 {
|
||||
let t = step as f32 / 18.0;
|
||||
let angle = if start_side {
|
||||
std::f32::consts::FRAC_PI_2 + t * std::f32::consts::PI
|
||||
} else {
|
||||
-std::f32::consts::FRAC_PI_2 + t * std::f32::consts::PI
|
||||
};
|
||||
let point = Point::new(center.x + radius * angle.cos(), center.y + radius * angle.sin());
|
||||
if step == 0 {
|
||||
builder.move_to(point);
|
||||
} else {
|
||||
builder.line_to(point);
|
||||
}
|
||||
}
|
||||
});
|
||||
frame.stroke(&path, canvas::Stroke::default().with_color(color).with_width(1.1));
|
||||
}
|
||||
|
||||
impl canvas::Program<Message> for MLinePreviewCanvas {
|
||||
type State = ();
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
_state: &(),
|
||||
renderer: &iced::Renderer,
|
||||
theme: &Theme,
|
||||
bounds: Rectangle,
|
||||
_cursor: mouse::Cursor,
|
||||
) -> Vec<canvas::Geometry> {
|
||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||
let ink = theme.palette().background.base.text;
|
||||
let mut parsed = self
|
||||
.elements
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, e)| {
|
||||
let color_str = match &e.color {
|
||||
acadrust::types::Color::ByLayer => "ByLayer".into(),
|
||||
acadrust::types::Color::None => "None".into(),
|
||||
acadrust::types::Color::ByBlock => "ByBlock".into(),
|
||||
acadrust::types::Color::Index(i) => format!("ACI {i}"),
|
||||
acadrust::types::Color::Rgb { r, g, b } => format!("#{r:02X}{g:02X}{b:02X}"),
|
||||
};
|
||||
let lt = if e.linetype.is_empty() {
|
||||
"ByLayer"
|
||||
} else {
|
||||
&e.linetype
|
||||
};
|
||||
row![
|
||||
text(format!(" {idx}:")).size(10).style(muted_style).width(24),
|
||||
text(format!("{:+.3}", e.offset)).size(10).width(70),
|
||||
text(color_str).size(10).width(90),
|
||||
text(lt).size(10),
|
||||
]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
.map(|element| {
|
||||
(
|
||||
element[0].trim().parse::<f32>().unwrap_or(0.0),
|
||||
element[1].clone(),
|
||||
element[2].clone(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
.collect::<Vec<_>>();
|
||||
parsed.sort_by(|a, b| b.0.total_cmp(&a.0));
|
||||
if let (Some(top), Some(bottom)) = (parsed.first(), parsed.last()) {
|
||||
if self.fill {
|
||||
let upper = element_points(top.0, bounds);
|
||||
let lower = element_points(bottom.0, bounds);
|
||||
let fill = canvas::Path::new(|builder| {
|
||||
builder.move_to(upper[0]);
|
||||
builder.line_to(upper[1]);
|
||||
builder.line_to(upper[2]);
|
||||
builder.line_to(lower[2]);
|
||||
builder.line_to(lower[1]);
|
||||
builder.line_to(lower[0]);
|
||||
builder.close();
|
||||
});
|
||||
frame.fill(&fill, aci_color(&self.fill_color, theme.palette().background.weak.color));
|
||||
}
|
||||
}
|
||||
for (offset, color, linetype) in &parsed {
|
||||
let points = element_points(*offset, bounds);
|
||||
let dashed = !linetype.trim().is_empty()
|
||||
&& !linetype.eq_ignore_ascii_case("ByLayer")
|
||||
&& !linetype.to_ascii_lowercase().contains("continuous");
|
||||
let stroke = canvas::Stroke {
|
||||
style: canvas::Style::Solid(aci_color(color, ink)),
|
||||
width: 1.4,
|
||||
line_dash: if dashed {
|
||||
canvas::LineDash { segments: &[6.0, 4.0], offset: 0 }
|
||||
} else {
|
||||
canvas::LineDash::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
frame.stroke(
|
||||
&canvas::Path::new(|builder| {
|
||||
builder.move_to(points[0]);
|
||||
builder.line_to(points[1]);
|
||||
builder.line_to(points[2]);
|
||||
}),
|
||||
stroke,
|
||||
);
|
||||
}
|
||||
if let (Some(top), Some(bottom)) = (parsed.first(), parsed.last()) {
|
||||
let top_points = element_points(top.0, bounds);
|
||||
let bottom_points = element_points(bottom.0, bounds);
|
||||
let start_top = top_points[0];
|
||||
let start_bottom = bottom_points[0];
|
||||
let end_top = top_points[2];
|
||||
let end_bottom = bottom_points[2];
|
||||
let start_angle = self.start_angle.trim().parse::<f32>().unwrap_or(90.0).to_radians();
|
||||
let end_angle = self.end_angle.trim().parse::<f32>().unwrap_or(90.0).to_radians();
|
||||
let cap = |a: Point, b: Point, angle: f32| {
|
||||
let middle = Point::new((a.x + b.x) * 0.5, (a.y + b.y) * 0.5);
|
||||
let half = ((a.y - b.y).abs() * 0.5).max(2.0);
|
||||
let direction = Point::new(angle.cos() * half, angle.sin() * half);
|
||||
(Point::new(middle.x - direction.x, middle.y - direction.y), Point::new(middle.x + direction.x, middle.y + direction.y))
|
||||
};
|
||||
if self.start_square {
|
||||
let (a, b) = cap(start_top, start_bottom, start_angle);
|
||||
frame.stroke(&canvas::Path::line(a, b), canvas::Stroke::default().with_color(ink));
|
||||
}
|
||||
if self.end_square {
|
||||
let (a, b) = cap(end_top, end_bottom, end_angle);
|
||||
frame.stroke(&canvas::Path::line(a, b), canvas::Stroke::default().with_color(ink));
|
||||
}
|
||||
let start_center = Point::new((start_top.x + start_bottom.x) * 0.5, (start_top.y + start_bottom.y) * 0.5);
|
||||
let end_center = Point::new((end_top.x + end_bottom.x) * 0.5, (end_top.y + end_bottom.y) * 0.5);
|
||||
let outer_radius = ((start_top.y - start_bottom.y).abs() * 0.5).max(3.0);
|
||||
if self.start_round {
|
||||
draw_arc(&mut frame, start_center, outer_radius, true, ink);
|
||||
}
|
||||
if self.end_round {
|
||||
draw_arc(&mut frame, end_center, outer_radius, false, ink);
|
||||
}
|
||||
if self.start_inner && parsed.len() > 2 {
|
||||
draw_arc(&mut frame, start_center, outer_radius * 0.55, true, ink);
|
||||
}
|
||||
if self.end_inner && parsed.len() > 2 {
|
||||
draw_arc(&mut frame, end_center, outer_radius * 0.55, false, ink);
|
||||
}
|
||||
if self.joints {
|
||||
let joint_top = top_points[1];
|
||||
let joint_bottom = bottom_points[1];
|
||||
frame.stroke(&canvas::Path::line(joint_top, joint_bottom), canvas::Stroke::default().with_color(ink).with_width(1.0));
|
||||
}
|
||||
}
|
||||
frame.fill_text(canvas::Text {
|
||||
content: format!("{} · {} {}", self.description, t!("Elements"), self.elements.len()),
|
||||
position: Point::new(10.0, bounds.height - 9.0),
|
||||
color: ink.scale_alpha(0.62),
|
||||
size: iced::Pixels(10.0),
|
||||
align_y: iced::alignment::Vertical::Center,
|
||||
..Default::default()
|
||||
});
|
||||
vec![frame.into_geometry()]
|
||||
}
|
||||
}
|
||||
|
||||
let mut col_items: Vec<Element<'_, Message>> = vec![
|
||||
info_row(t!("Name:"), s.name.clone()),
|
||||
info_row(t!("Elements:"), s.elements.len().to_string()),
|
||||
text(t!(" Off Color Ltype"))
|
||||
.size(10)
|
||||
.style(muted_style)
|
||||
.into(),
|
||||
];
|
||||
col_items.extend(elem_rows);
|
||||
scrollable(column(col_items).spacing(6).padding([12, 12]))
|
||||
.height(sizing.height)
|
||||
.into()
|
||||
} else {
|
||||
container(text(t!("Select a style to view details.")).size(11).style(muted_style))
|
||||
.padding([12, 12])
|
||||
.into()
|
||||
pub fn view_window<'a>(
|
||||
v: MlStyleView<'a>,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'a, Message> {
|
||||
let style = v.style;
|
||||
let content: Element<'a, Message> = match (v.tab, style) {
|
||||
(_, None) => text(t!("Select a style to view details.")).size(11).into(),
|
||||
(0, Some(_)) => {
|
||||
let mut items = column![
|
||||
row![
|
||||
text(t!("Offset")).size(10).style(muted_style).width(110),
|
||||
text(t!("Color")).size(10).style(muted_style).width(100),
|
||||
text(t!("Line type")).size(10).style(muted_style).width(170),
|
||||
button(text(t!("Add")).size(10)).on_press(Message::MlStyleElementAdd).padding([4, 12]),
|
||||
]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center),
|
||||
]
|
||||
.spacing(6);
|
||||
for (index, element) in v.elements.iter().enumerate() {
|
||||
items = items.push(
|
||||
row![
|
||||
text_input("0.0", &element[0])
|
||||
.on_input(move |value| Message::MlStyleElementEdit { index, field: "offset", value })
|
||||
.size(11).width(110),
|
||||
text_input("256", &element[1])
|
||||
.on_input(move |value| Message::MlStyleElementEdit { index, field: "color", value })
|
||||
.size(11).width(100),
|
||||
text_input("ByLayer", &element[2])
|
||||
.on_input(move |value| Message::MlStyleElementEdit { index, field: "linetype", value })
|
||||
.size(11).width(170),
|
||||
button(text(t!("Delete")).size(10))
|
||||
.on_press(Message::MlStyleElementDelete(index))
|
||||
.padding([4, 10]),
|
||||
]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center),
|
||||
);
|
||||
}
|
||||
items.into()
|
||||
}
|
||||
(_, Some(style)) => column![
|
||||
input_row(t!("Description"), "", v.description, "description"),
|
||||
text(t!("Fill and joints")).size(11).style(primary_style),
|
||||
row![
|
||||
toggle(t!("Fill enabled"), style.flags.fill_on, "fill"),
|
||||
toggle(t!("Display joints"), style.flags.display_joints, "joints"),
|
||||
].spacing(18),
|
||||
input_row(t!("Fill color"), "256", v.fill_color, "fill_color"),
|
||||
text(t!("Start caps")).size(11).style(primary_style),
|
||||
row![
|
||||
toggle(t!("Line"), style.flags.start_square_cap, "start_square"),
|
||||
toggle(t!("Inner arcs"), style.flags.start_inner_arcs_cap, "start_inner"),
|
||||
toggle(t!("Outer arc"), style.flags.start_round_cap, "start_round"),
|
||||
].spacing(18),
|
||||
input_row(t!("Start angle"), "90", v.start_angle, "start_angle"),
|
||||
text(t!("End caps")).size(11).style(primary_style),
|
||||
row![
|
||||
toggle(t!("Line"), style.flags.end_square_cap, "end_square"),
|
||||
toggle(t!("Inner arcs"), style.flags.end_inner_arcs_cap, "end_inner"),
|
||||
toggle(t!("Outer arc"), style.flags.end_round_cap, "end_round"),
|
||||
].spacing(18),
|
||||
input_row(t!("End angle"), "90", v.end_angle, "end_angle"),
|
||||
].spacing(9).into(),
|
||||
};
|
||||
|
||||
let right_panel = container(details)
|
||||
.width(sizing.width)
|
||||
.height(sizing.height);
|
||||
|
||||
let preview: Element<'a, Message> = if let Some(style) = style {
|
||||
canvas(MLinePreviewCanvas {
|
||||
description: v.description.to_string(),
|
||||
start_angle: v.start_angle.to_string(),
|
||||
end_angle: v.end_angle.to_string(),
|
||||
fill_color: v.fill_color.to_string(),
|
||||
fill: style.flags.fill_on,
|
||||
joints: style.flags.display_joints,
|
||||
start_square: style.flags.start_square_cap,
|
||||
start_inner: style.flags.start_inner_arcs_cap,
|
||||
start_round: style.flags.start_round_cap,
|
||||
end_square: style.flags.end_square_cap,
|
||||
end_inner: style.flags.end_inner_arcs_cap,
|
||||
end_round: style.flags.end_round_cap,
|
||||
elements: v.elements.to_vec(),
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.height(150)
|
||||
.into()
|
||||
} else {
|
||||
container(text(t!("No preview"))).height(150).into()
|
||||
};
|
||||
let status = if v.selected.eq_ignore_ascii_case(&v.current) {
|
||||
t!("Current style")
|
||||
} else if v.in_use {
|
||||
t!("Used in drawing")
|
||||
} else {
|
||||
t!("Available style")
|
||||
};
|
||||
let summary = if v.comparison_sections.is_empty() {
|
||||
t!("No differences").into_owned()
|
||||
} else {
|
||||
format!("{}: {}", t!("Different"), v.comparison_sections.join(", "))
|
||||
};
|
||||
let editor = crate::ui::style::style_manager::editor_shell(
|
||||
crate::ui::style::style_manager::EditorShell {
|
||||
sizing,
|
||||
selected: v.selected.to_string(),
|
||||
status,
|
||||
preview,
|
||||
comparison: Some(crate::ui::style::style_manager::EditorComparison {
|
||||
selected: v.compare_name,
|
||||
options: v.compare_opts,
|
||||
summary,
|
||||
on_select: Message::MlStyleDialogCompare,
|
||||
}),
|
||||
tabs: vec![
|
||||
crate::ui::style::style_manager::EditorTab {
|
||||
label: t!("Elements"),
|
||||
active: v.tab == 0,
|
||||
on_press: Message::MlStyleDialogTab(0),
|
||||
},
|
||||
crate::ui::style::style_manager::EditorTab {
|
||||
label: t!("Caps and Fill"),
|
||||
active: v.tab == 1,
|
||||
on_press: Message::MlStyleDialogTab(1),
|
||||
},
|
||||
],
|
||||
content,
|
||||
},
|
||||
);
|
||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||
sizing,
|
||||
kind: crate::app::StyleKind::MLine,
|
||||
styles: &styles,
|
||||
selected,
|
||||
current: Some(current_style.as_str()),
|
||||
rename_active,
|
||||
rename_buf,
|
||||
styles: &v.styles,
|
||||
selected: v.selected,
|
||||
current: Some(v.current.as_str()),
|
||||
rename_active: v.rename_active,
|
||||
rename_buf: v.rename_buf,
|
||||
on_new: Message::MlStyleDialogNew,
|
||||
on_copy: Message::MlStyleDialogCopy,
|
||||
on_delete: Message::MlStyleDialogDelete,
|
||||
on_select: Message::MlStyleDialogSelect,
|
||||
on_set_current: Message::MlStyleDialogSetCurrent,
|
||||
on_apply: Message::MlStyleApply,
|
||||
editor: right_panel.into(),
|
||||
read_only: false,
|
||||
editor,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ pub fn item<'a>(
|
|||
on_select: Message,
|
||||
rename_active: Option<&str>,
|
||||
rename_buf: &'a str,
|
||||
can_rename: bool,
|
||||
) -> Element<'a, Message> {
|
||||
if rename_active == Some(name) {
|
||||
text_input("", rename_buf)
|
||||
|
|
@ -56,9 +57,12 @@ pub fn item<'a>(
|
|||
..Default::default()
|
||||
}
|
||||
});
|
||||
mouse_area(cell)
|
||||
.on_press(on_select)
|
||||
.on_double_click(Message::StyleRenameStart(kind, name.to_string()))
|
||||
.into()
|
||||
let area = mouse_area(cell).on_press(on_select);
|
||||
if can_rename {
|
||||
area.on_double_click(Message::StyleRenameStart(kind, name.to_string()))
|
||||
.into()
|
||||
} else {
|
||||
area.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
use crate::app::{Message, StyleKind};
|
||||
use iced::widget::button::{Status, Style};
|
||||
use iced::widget::{button, column, container, row, scrollable, text, Space};
|
||||
use iced::{Background, Border, Element, Theme};
|
||||
use iced::{Background, Border, Element, Length, Theme};
|
||||
use crate::t;
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
|
@ -45,6 +45,9 @@ pub struct Scaffold<'a, 'b> {
|
|||
pub on_set_current: Message,
|
||||
/// "Apply" action (right side, primary). Every manager has one.
|
||||
pub on_apply: Message,
|
||||
/// Referenced styles may be copied but not changed, renamed, deleted, or
|
||||
/// made current.
|
||||
pub read_only: bool,
|
||||
pub editor: Element<'a, Message>,
|
||||
}
|
||||
|
||||
|
|
@ -55,10 +58,10 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
|||
let bar = row![
|
||||
tb_button(t!("New"), s.on_new, false),
|
||||
tb_button(t!("Copy"), s.on_copy, false),
|
||||
tb_button(t!("Delete"), s.on_delete, false),
|
||||
tb_button_enabled(t!("Delete"), s.on_delete, false, !s.read_only),
|
||||
Space::new().width(width),
|
||||
tb_button(t!("Set Current"), s.on_set_current, false),
|
||||
tb_button(t!("Apply"), s.on_apply, true),
|
||||
tb_button_enabled(t!("Set Current"), s.on_set_current, false, !s.read_only),
|
||||
tb_button_enabled(t!("Apply"), s.on_apply, true, !s.read_only),
|
||||
]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center);
|
||||
|
|
@ -87,6 +90,7 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
|||
(s.on_select)(name.clone()),
|
||||
s.rename_active,
|
||||
s.rename_buf,
|
||||
!(s.read_only && is_sel),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
|
@ -137,6 +141,102 @@ pub fn view<'a, 'b>(s: Scaffold<'a, 'b>) -> Element<'a, Message> {
|
|||
.into()
|
||||
}
|
||||
|
||||
pub struct EditorTab {
|
||||
pub label: Cow<'static, str>,
|
||||
pub active: bool,
|
||||
pub on_press: Message,
|
||||
}
|
||||
|
||||
pub struct EditorComparison {
|
||||
pub selected: String,
|
||||
pub options: Vec<String>,
|
||||
pub summary: String,
|
||||
pub on_select: fn(String) -> Message,
|
||||
}
|
||||
|
||||
/// Shared right-hand editor composition used by every named style manager.
|
||||
/// The preview stays visible while the active property page scrolls.
|
||||
pub struct EditorShell<'a> {
|
||||
pub sizing: crate::ui::modal::ModalSizing,
|
||||
pub selected: String,
|
||||
pub status: Cow<'static, str>,
|
||||
pub preview: Element<'a, Message>,
|
||||
pub comparison: Option<EditorComparison>,
|
||||
pub tabs: Vec<EditorTab>,
|
||||
pub content: Element<'a, Message>,
|
||||
}
|
||||
|
||||
pub fn editor_shell<'a>(shell: EditorShell<'a>) -> Element<'a, Message> {
|
||||
let tabs: Vec<Element<'a, Message>> = shell
|
||||
.tabs
|
||||
.into_iter()
|
||||
.map(|tab| {
|
||||
button(text(tab.label).size(11))
|
||||
.on_press(tab.on_press)
|
||||
.style(tab_button_style(tab.active))
|
||||
.padding([4, 10])
|
||||
.into()
|
||||
})
|
||||
.collect();
|
||||
let comparison: Element<'a, Message> = match shell.comparison {
|
||||
Some(comparison) if !comparison.options.is_empty() => row![
|
||||
text(t!("Compare with")).size(10).style(muted_text_style),
|
||||
iced::widget::pick_list(
|
||||
Some(comparison.selected),
|
||||
comparison.options,
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(comparison.on_select)
|
||||
.text_size(11)
|
||||
.width(150),
|
||||
text(comparison.summary).size(10).style(muted_text_style),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into(),
|
||||
_ => Space::new().height(0).into(),
|
||||
};
|
||||
let preview = container(shell.preview)
|
||||
.width(Length::Fill)
|
||||
.style(|theme: &Theme| container::Style {
|
||||
background: Some(Background::Color(theme.palette().background.weak.color)),
|
||||
border: Border {
|
||||
color: theme.palette().background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 3.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
});
|
||||
container(
|
||||
column![
|
||||
row![
|
||||
text(shell.selected).size(13).style(primary_text_style),
|
||||
Space::new().width(Length::Fill),
|
||||
text(shell.status).size(10).style(muted_text_style),
|
||||
]
|
||||
.align_y(iced::Center),
|
||||
preview,
|
||||
comparison,
|
||||
row(tabs).spacing(2),
|
||||
hdivider(Length::Fill),
|
||||
scrollable(container(shell.content).padding([12, 12]).width(Length::Fill))
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill),
|
||||
]
|
||||
.spacing(6)
|
||||
.height(shell.sizing.height),
|
||||
)
|
||||
.height(shell.sizing.height)
|
||||
.width(Length::Fill)
|
||||
.padding(iced::Padding {
|
||||
top: 12.0,
|
||||
right: 0.0,
|
||||
bottom: 12.0,
|
||||
left: 0.0,
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
// ── Shared chrome ──────────────────────────────────────────────────────────
|
||||
|
||||
pub(crate) fn tb_button(
|
||||
|
|
@ -152,10 +252,55 @@ pub(crate) fn tb_button(
|
|||
.into()
|
||||
}
|
||||
|
||||
pub(crate) fn tb_button_enabled(
|
||||
label: impl Into<Cow<'static, str>>,
|
||||
msg: Message,
|
||||
accent: bool,
|
||||
enabled: bool,
|
||||
) -> Element<'static, Message> {
|
||||
let pad = if accent { [4, 14] } else { [4, 10] };
|
||||
let button = button(text(label.into()).size(11))
|
||||
.style(btn_s(accent))
|
||||
.padding(pad);
|
||||
if enabled {
|
||||
button.on_press(msg).into()
|
||||
} else {
|
||||
button.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn tab_button_style(active: bool) -> impl Fn(&Theme, Status) -> Style {
|
||||
move |theme: &Theme, status| {
|
||||
let palette = theme.palette();
|
||||
let pair = match (active, status) {
|
||||
(true, _) => palette.primary.strong,
|
||||
(false, Status::Hovered | Status::Pressed) => palette.background.strong,
|
||||
_ => palette.background.weak,
|
||||
};
|
||||
Style {
|
||||
background: Some(Background::Color(pair.color)),
|
||||
text_color: pair.text,
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 3.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn primary_text_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
iced::widget::text::Style {
|
||||
color: Some(theme.palette().primary.base.color),
|
||||
}
|
||||
}
|
||||
|
||||
fn btn_s(accent: bool) -> impl Fn(&Theme, Status) -> Style {
|
||||
move |theme: &Theme, st| {
|
||||
let palette = theme.palette();
|
||||
let pair = match (accent, st) {
|
||||
(_, Status::Disabled) => palette.background.weak,
|
||||
(true, Status::Hovered | Status::Pressed) => palette.primary.strong,
|
||||
(false, Status::Hovered | Status::Pressed) => palette.background.strong,
|
||||
(true, _) => palette.primary.base,
|
||||
|
|
@ -163,7 +308,11 @@ fn btn_s(accent: bool) -> impl Fn(&Theme, Status) -> Style {
|
|||
};
|
||||
Style {
|
||||
background: Some(Background::Color(pair.color)),
|
||||
text_color: pair.text,
|
||||
text_color: if st == Status::Disabled {
|
||||
pair.text.scale_alpha(0.45)
|
||||
} else {
|
||||
pair.text
|
||||
},
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
|
|
|
|||
|
|
@ -1,49 +1,60 @@
|
|||
//! Table Style Manager window — fills the entire OS window.
|
||||
//! Table style manager.
|
||||
|
||||
use crate::app::Message;
|
||||
use iced::widget::{
|
||||
button, checkbox, column, container, row, scrollable, text, text_input, Column,
|
||||
};
|
||||
use iced::{Background, Border, Element, Theme};
|
||||
use crate::t;
|
||||
use iced::widget::{canvas, checkbox, column, row, text, text_input, Column};
|
||||
use iced::{mouse, Color, Element, Length, Point, Rectangle, Size, Theme};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
struct EnumChoice(String);
|
||||
struct EnumChoice {
|
||||
code: String,
|
||||
label: Cow<'static, str>,
|
||||
}
|
||||
|
||||
impl fmt::Display for EnumChoice {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
formatter.write_str(crate::i18n::translate(&self.0).as_ref())
|
||||
formatter.write_str(self.label.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_choices(values: &[&str]) -> Vec<EnumChoice> {
|
||||
values.iter().map(|value| EnumChoice((*value).to_string())).collect()
|
||||
fn choices(values: &[(&str, &str)]) -> Vec<EnumChoice> {
|
||||
values
|
||||
.iter()
|
||||
.map(|(code, label)| EnumChoice {
|
||||
code: (*code).to_string(),
|
||||
label: crate::i18n::translate(label),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn btn_s(accent: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
move |theme: &Theme, st| {
|
||||
let palette = theme.palette();
|
||||
let pair = match (accent, st) {
|
||||
(true, button::Status::Hovered | button::Status::Pressed) => palette.primary.strong,
|
||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||
palette.background.strong
|
||||
}
|
||||
(true, _) => palette.primary.base,
|
||||
_ => palette.background.weak,
|
||||
};
|
||||
button::Style {
|
||||
background: Some(Background::Color(pair.color)),
|
||||
text_color: pair.text,
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 4.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
pub struct TableStyleView<'a> {
|
||||
pub styles: Vec<String>,
|
||||
pub selected: &'a str,
|
||||
pub current: &'a str,
|
||||
pub style: Option<&'a acadrust::objects::TableStyle>,
|
||||
pub tab: u8,
|
||||
pub compare_name: String,
|
||||
pub compare_opts: Vec<String>,
|
||||
pub comparison_sections: Vec<String>,
|
||||
pub in_use: bool,
|
||||
pub hmargin: &'a str,
|
||||
pub vmargin: &'a str,
|
||||
pub description: &'a str,
|
||||
pub cell_textstyle: &'a [String; 3],
|
||||
pub cell_height: &'a [String; 3],
|
||||
pub cell_textcolor: &'a [String; 3],
|
||||
pub cell_fillcolor: &'a [String; 3],
|
||||
pub cell_datatype: &'a [String; 3],
|
||||
pub cell_unittype: &'a [String; 3],
|
||||
pub cell_format: &'a [String; 3],
|
||||
pub border_lw: &'a [[String; 6]; 3],
|
||||
pub border_color: &'a [[String; 6]; 3],
|
||||
pub border_spacing: &'a [[String; 6]; 3],
|
||||
pub rename_active: Option<&'a str>,
|
||||
pub rename_buf: &'a str,
|
||||
pub color_open: Option<(u8, &'static str)>,
|
||||
}
|
||||
|
||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
|
|
@ -58,323 +69,492 @@ fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn view_window<'a>(
|
||||
styles: Vec<String>,
|
||||
selected: &'a str,
|
||||
current: &'a str,
|
||||
selected_style: Option<&'a acadrust::objects::TableStyle>,
|
||||
hmargin_buf: &'a str,
|
||||
vmargin_buf: &'a str,
|
||||
description_buf: &'a str,
|
||||
cell_textstyle: &'a [String; 3],
|
||||
cell_height: &'a [String; 3],
|
||||
cell_textcolor: &'a [String; 3],
|
||||
cell_fillcolor: &'a [String; 3],
|
||||
cell_datatype: &'a [String; 3],
|
||||
cell_unittype: &'a [String; 3],
|
||||
cell_format: &'a [String; 3],
|
||||
border_lw: &'a [[String; 6]; 3],
|
||||
border_color: &'a [[String; 6]; 3],
|
||||
border_spacing: &'a [[String; 6]; 3],
|
||||
rename_active: Option<&'a str>,
|
||||
rename_buf: &'a str,
|
||||
color_open: Option<(u8, &'static str)>,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'a, Message> {
|
||||
// ── Right: Details panel ──────────────────────────────────────────────
|
||||
let info_row = |label: Cow<'static, str>, val: String| -> Element<'_, Message> {
|
||||
row![
|
||||
text(label).size(11).style(muted_style).width(160),
|
||||
text(val).size(11),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
#[derive(Clone)]
|
||||
struct PreviewBorder {
|
||||
color: String,
|
||||
weight: String,
|
||||
spacing: String,
|
||||
double: bool,
|
||||
hidden: bool,
|
||||
}
|
||||
|
||||
let cell_editor = |row_label: Cow<'static, str>,
|
||||
row: u8,
|
||||
rs: &acadrust::objects::RowCellStyle|
|
||||
-> Element<'a, Message> {
|
||||
let r = row as usize;
|
||||
let cell_in = |label: Cow<'static, str>,
|
||||
placeholder: &'static str,
|
||||
value: &'a str,
|
||||
field: &'static str|
|
||||
-> Element<'a, Message> {
|
||||
row![
|
||||
text(label).size(11).style(muted_style).width(150),
|
||||
text_input(placeholder, value)
|
||||
.on_input(move |v| Message::TableStyleCellEdit {
|
||||
row,
|
||||
field,
|
||||
value: v
|
||||
})
|
||||
.size(11)
|
||||
.width(100),
|
||||
]
|
||||
#[derive(Clone)]
|
||||
struct PreviewRow {
|
||||
label: String,
|
||||
text_style: String,
|
||||
text_height: String,
|
||||
text_color: String,
|
||||
fill_color: String,
|
||||
fill: bool,
|
||||
alignment: String,
|
||||
data_type: String,
|
||||
unit_type: String,
|
||||
format: String,
|
||||
borders: [PreviewBorder; 6],
|
||||
}
|
||||
|
||||
struct TablePreviewCanvas {
|
||||
rows: [PreviewRow; 3],
|
||||
active_row: usize,
|
||||
hmargin: String,
|
||||
vmargin: String,
|
||||
description: String,
|
||||
flow_up: bool,
|
||||
title_suppressed: bool,
|
||||
header_suppressed: bool,
|
||||
annotative: bool,
|
||||
}
|
||||
|
||||
fn aci_color(value: &str, fallback: Color) -> Color {
|
||||
crate::ui::color_select::aci_string_to_color(value)
|
||||
.rgb()
|
||||
.map(|(r, g, b)| Color::from_rgb8(r, g, b))
|
||||
.unwrap_or(fallback)
|
||||
}
|
||||
|
||||
fn border_width(value: &str) -> f32 {
|
||||
value
|
||||
.trim()
|
||||
.parse::<f32>()
|
||||
.map(|value| (value.abs() / 35.0).clamp(0.7, 4.5))
|
||||
.unwrap_or(1.0)
|
||||
}
|
||||
|
||||
fn draw_line(
|
||||
frame: &mut canvas::Frame,
|
||||
a: Point,
|
||||
b: Point,
|
||||
border: &PreviewBorder,
|
||||
fallback: Color,
|
||||
) {
|
||||
if border.hidden {
|
||||
return;
|
||||
}
|
||||
let stroke = canvas::Stroke::default()
|
||||
.with_color(aci_color(&border.color, fallback))
|
||||
.with_width(border_width(&border.weight));
|
||||
frame.stroke(&canvas::Path::line(a, b), stroke.clone());
|
||||
if border.double {
|
||||
let spacing = border
|
||||
.spacing
|
||||
.trim()
|
||||
.parse::<f32>()
|
||||
.unwrap_or(1.0)
|
||||
.abs()
|
||||
.clamp(1.0, 5.0);
|
||||
let dx = b.x - a.x;
|
||||
let dy = b.y - a.y;
|
||||
let length = (dx * dx + dy * dy).sqrt().max(1.0);
|
||||
let offset = Point::new(-dy / length * spacing, dx / length * spacing);
|
||||
frame.stroke(
|
||||
&canvas::Path::line(
|
||||
Point::new(a.x + offset.x, a.y + offset.y),
|
||||
Point::new(b.x + offset.x, b.y + offset.y),
|
||||
),
|
||||
stroke,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl canvas::Program<Message> for TablePreviewCanvas {
|
||||
type State = ();
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
_state: &(),
|
||||
renderer: &iced::Renderer,
|
||||
theme: &Theme,
|
||||
bounds: Rectangle,
|
||||
_cursor: mouse::Cursor,
|
||||
) -> Vec<canvas::Geometry> {
|
||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||
let ink = theme.palette().background.base.text;
|
||||
let mut order = vec![2usize, 1, 0];
|
||||
if self.title_suppressed {
|
||||
order.retain(|row| *row != 2);
|
||||
}
|
||||
if self.header_suppressed {
|
||||
order.retain(|row| *row != 1);
|
||||
}
|
||||
if self.flow_up {
|
||||
order.reverse();
|
||||
}
|
||||
let hmargin = self.hmargin.trim().parse::<f32>().unwrap_or(1.5).abs();
|
||||
let vmargin = self.vmargin.trim().parse::<f32>().unwrap_or(1.5).abs();
|
||||
let left = 18.0 + (hmargin * 1.2).clamp(0.0, 18.0);
|
||||
let right = bounds.width - left;
|
||||
let top = 9.0 + (vmargin * 0.8).clamp(0.0, 12.0);
|
||||
let bottom = bounds.height - 24.0;
|
||||
let row_height = ((bottom - top) / order.len().max(1) as f32).max(18.0);
|
||||
let col_width = (right - left) / 3.0;
|
||||
for (display_row, row_index) in order.iter().copied().enumerate() {
|
||||
let row = &self.rows[row_index];
|
||||
let y0 = top + display_row as f32 * row_height;
|
||||
let y1 = y0 + row_height;
|
||||
let fallback_fill = theme.palette().background.weak.color;
|
||||
if row.fill {
|
||||
frame.fill(
|
||||
&canvas::Path::rectangle(
|
||||
Point::new(left, y0),
|
||||
Size::new(right - left, row_height),
|
||||
),
|
||||
aci_color(&row.fill_color, fallback_fill),
|
||||
);
|
||||
}
|
||||
let borders = &row.borders;
|
||||
draw_line(&mut frame, Point::new(left, y0), Point::new(left, y1), &borders[0], ink);
|
||||
draw_line(&mut frame, Point::new(right, y0), Point::new(right, y1), &borders[1], ink);
|
||||
draw_line(&mut frame, Point::new(left, y0), Point::new(right, y0), &borders[2], ink);
|
||||
draw_line(&mut frame, Point::new(left, y1), Point::new(right, y1), &borders[3], ink);
|
||||
for column in 1..3 {
|
||||
let x = left + column as f32 * col_width;
|
||||
draw_line(&mut frame, Point::new(x, y0), Point::new(x, y1), &borders[5], ink);
|
||||
}
|
||||
if display_row + 1 < order.len() {
|
||||
draw_line(&mut frame, Point::new(left, y1), Point::new(right, y1), &borders[4], ink);
|
||||
}
|
||||
for column in 0..3 {
|
||||
let label = if row.format.trim().is_empty() {
|
||||
format!("{} {}", row.label, column + 1)
|
||||
} else {
|
||||
row.format.replace("{}", &(column + 1).to_string())
|
||||
};
|
||||
let horizontal = if row.alignment.ends_with("Left") {
|
||||
iced::advanced::text::Alignment::Left
|
||||
} else if row.alignment.ends_with("Right") {
|
||||
iced::advanced::text::Alignment::Right
|
||||
} else {
|
||||
iced::advanced::text::Alignment::Center
|
||||
};
|
||||
let x = match horizontal {
|
||||
iced::advanced::text::Alignment::Left => left + column as f32 * col_width + 5.0,
|
||||
iced::advanced::text::Alignment::Right => left + (column + 1) as f32 * col_width - 5.0,
|
||||
iced::advanced::text::Alignment::Center => left + (column as f32 + 0.5) * col_width,
|
||||
_ => left + (column as f32 + 0.5) * col_width,
|
||||
};
|
||||
let y = if row.alignment.starts_with("Top") {
|
||||
y0 + 7.0
|
||||
} else if row.alignment.starts_with("Bottom") {
|
||||
y1 - 7.0
|
||||
} else {
|
||||
(y0 + y1) * 0.5
|
||||
};
|
||||
frame.fill_text(canvas::Text {
|
||||
content: label,
|
||||
position: Point::new(x, y),
|
||||
color: aci_color(&row.text_color, ink),
|
||||
size: iced::Pixels(
|
||||
row.text_height
|
||||
.trim()
|
||||
.parse::<f32>()
|
||||
.map(|height| (height * 34.0).clamp(7.0, 16.0))
|
||||
.unwrap_or(10.0),
|
||||
),
|
||||
align_x: horizontal,
|
||||
align_y: iced::alignment::Vertical::Center,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
let active = &self.rows[self.active_row.min(2)];
|
||||
frame.fill_text(canvas::Text {
|
||||
content: format!(
|
||||
"{} · {} · type {} / unit {}{}{}",
|
||||
active.text_style,
|
||||
if self.annotative { t!("Annotative") } else { t!("Drawing units") },
|
||||
active.data_type,
|
||||
active.unit_type,
|
||||
if self.description.trim().is_empty() { "" } else { " · " },
|
||||
self.description,
|
||||
),
|
||||
position: Point::new(10.0, bounds.height - 9.0),
|
||||
color: ink.scale_alpha(0.65),
|
||||
size: iced::Pixels(10.0),
|
||||
align_y: iced::alignment::Vertical::Center,
|
||||
..Default::default()
|
||||
});
|
||||
vec![frame.into_geometry()]
|
||||
}
|
||||
}
|
||||
|
||||
fn input_row<'a>(
|
||||
label: Cow<'static, str>,
|
||||
placeholder: &'static str,
|
||||
value: &'a str,
|
||||
message: impl Fn(String) -> Message + 'a,
|
||||
) -> Element<'a, Message> {
|
||||
row![
|
||||
text(label).size(11).style(muted_style).width(155),
|
||||
text_input(placeholder, value)
|
||||
.on_input(message)
|
||||
.size(11)
|
||||
.width(170),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn cell_editor<'a>(v: &TableStyleView<'a>, row_index: u8) -> Element<'a, Message> {
|
||||
let Some(style) = v.style else {
|
||||
return text(t!("Select a style to view details.")).into();
|
||||
};
|
||||
let row_style = match row_index {
|
||||
0 => &style.data_row_style,
|
||||
1 => &style.header_row_style,
|
||||
_ => &style.title_row_style,
|
||||
};
|
||||
let index = row_index as usize;
|
||||
let cell_input = |label, placeholder, value: &'a str, field| {
|
||||
input_row(label, placeholder, value, move |value| Message::TableStyleCellEdit {
|
||||
row: row_index,
|
||||
field,
|
||||
value,
|
||||
})
|
||||
};
|
||||
let cell_color = |label: Cow<'static, str>, value: &'a str, field: &'static str| {
|
||||
let current = crate::ui::color_select::aci_string_to_color(value);
|
||||
let selector = crate::ui::color_select::color_selector(
|
||||
current,
|
||||
v.color_open == Some((row_index, field)),
|
||||
crate::ui::color_select::ColorExtras { by_layer: true, by_block: true },
|
||||
move |color| Message::TableStyleCellEdit {
|
||||
row: row_index,
|
||||
field,
|
||||
value: crate::ui::color_select::color_to_aci_string(color),
|
||||
},
|
||||
Message::TableColorMore(row_index, field),
|
||||
Message::OpenColorWindow(crate::app::ColorPickTarget::Table(row_index, field), current),
|
||||
);
|
||||
row![text(label).size(11).style(muted_style).width(155), selector]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
// Shared colour selector — sends the chosen colour through the same
|
||||
// cell edit as an ACI string.
|
||||
let cell_color = |label: Cow<'static, str>, value: &'a str, field: &'static str| -> Element<'a, Message> {
|
||||
let cur = crate::ui::color_select::aci_string_to_color(value);
|
||||
let open = color_open == Some((row, field));
|
||||
let selector = crate::ui::color_select::color_selector(
|
||||
cur,
|
||||
open,
|
||||
crate::ui::color_select::ColorExtras {
|
||||
by_layer: true,
|
||||
by_block: true,
|
||||
},
|
||||
move |c| Message::TableStyleCellEdit {
|
||||
row,
|
||||
field,
|
||||
value: crate::ui::color_select::color_to_aci_string(c),
|
||||
},
|
||||
Message::TableColorMore(row, field),
|
||||
Message::OpenColorWindow(
|
||||
crate::app::ColorPickTarget::Table(row, field),
|
||||
cur,
|
||||
),
|
||||
);
|
||||
row![text(label).size(11).style(muted_style).width(150), selector]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
let mut col = Column::new()
|
||||
.spacing(3)
|
||||
.push(text(row_label).size(11).style(primary_style))
|
||||
.push(cell_in(
|
||||
t!(" Text style:"),
|
||||
"Standard",
|
||||
&cell_textstyle[r],
|
||||
"textstyle",
|
||||
))
|
||||
.push(cell_in(t!(" Text height:"), "0.18", &cell_height[r], "height"))
|
||||
.push(cell_color(t!(" Text color:"), &cell_textcolor[r], "textcolor"))
|
||||
.push(cell_color(t!(" Fill color:"), &cell_fillcolor[r], "fillcolor"))
|
||||
.push(
|
||||
row![
|
||||
text(t!(" Alignment:")).size(11).style(muted_style).width(150),
|
||||
iced::widget::pick_list(
|
||||
Some(EnumChoice(format!("{:?}", rs.alignment))),
|
||||
enum_choices(&[
|
||||
"TopLeft",
|
||||
"TopCenter",
|
||||
"TopRight",
|
||||
"MiddleLeft",
|
||||
"MiddleCenter",
|
||||
"MiddleRight",
|
||||
"BottomLeft",
|
||||
"BottomCenter",
|
||||
"BottomRight",
|
||||
]),
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(move |choice| Message::TableStyleCellSetAlign {
|
||||
row,
|
||||
value: choice.0,
|
||||
})
|
||||
.text_size(11)
|
||||
.width(140),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.push(
|
||||
checkbox(rs.fill_enabled)
|
||||
.label(t!(" Background fill enabled"))
|
||||
.on_toggle(move |_| Message::TableStyleCellToggleFill(row))
|
||||
.size(14)
|
||||
.text_size(11),
|
||||
)
|
||||
.push(cell_in(t!(" Data type:"), "0", &cell_datatype[r], "datatype"))
|
||||
.push(cell_in(t!(" Unit type:"), "0", &cell_unittype[r], "unittype"))
|
||||
.push(cell_in(t!(" Format string:"), "", &cell_format[r], "format"))
|
||||
.push(
|
||||
text(t!(" Borders (type / weight / color / spacing / hidden)"))
|
||||
.size(10)
|
||||
.style(muted_style),
|
||||
);
|
||||
|
||||
let borders: [(&'static str, &acadrust::objects::TableCellBorder); 6] = [
|
||||
("L", &rs.left_border),
|
||||
("R", &rs.right_border),
|
||||
("T", &rs.top_border),
|
||||
("B", &rs.bottom_border),
|
||||
("H", &rs.horizontal_inside_border),
|
||||
("V", &rs.vertical_inside_border),
|
||||
];
|
||||
for (b, (bname, bd)) in borders.into_iter().enumerate() {
|
||||
let bu = b as u8;
|
||||
col = col.push(
|
||||
row![
|
||||
text(format!(" {bname}")).size(11).style(muted_style).width(28),
|
||||
iced::widget::pick_list(
|
||||
Some(EnumChoice(format!("{:?}", bd.border_type))),
|
||||
enum_choices(&["Single", "Double"]),
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(move |choice| Message::TableStyleBorderSetType {
|
||||
cell: row,
|
||||
border: bu,
|
||||
value: choice.0,
|
||||
})
|
||||
.text_size(10)
|
||||
.width(74),
|
||||
text_input("", &border_lw[r][b])
|
||||
.on_input(move |v| Message::TableStyleBorderEdit {
|
||||
cell: row,
|
||||
border: bu,
|
||||
field: "lw",
|
||||
value: v
|
||||
})
|
||||
.size(10)
|
||||
.width(46),
|
||||
text_input("", &border_color[r][b])
|
||||
.on_input(move |v| Message::TableStyleBorderEdit {
|
||||
cell: row,
|
||||
border: bu,
|
||||
field: "color",
|
||||
value: v
|
||||
})
|
||||
.size(10)
|
||||
.width(46),
|
||||
text_input("", &border_spacing[r][b])
|
||||
.on_input(move |v| Message::TableStyleBorderEdit {
|
||||
cell: row,
|
||||
border: bu,
|
||||
field: "spacing",
|
||||
value: v
|
||||
})
|
||||
.size(10)
|
||||
.width(46),
|
||||
checkbox(bd.is_invisible)
|
||||
.on_toggle(move |_| Message::TableStyleBorderToggleInvisible {
|
||||
cell: row,
|
||||
border: bu
|
||||
})
|
||||
.size(13),
|
||||
]
|
||||
.spacing(5)
|
||||
.align_y(iced::Center),
|
||||
);
|
||||
}
|
||||
|
||||
col.push(
|
||||
button(text(t!("Apply cell")).size(11))
|
||||
.on_press(Message::TableStyleCellApply(row))
|
||||
.style(btn_s(true))
|
||||
.padding([4, 12]),
|
||||
)
|
||||
.into()
|
||||
};
|
||||
|
||||
let details: Element<'_, Message> = if let Some(s) = selected_style {
|
||||
scrollable(
|
||||
column![
|
||||
info_row(t!("Name:"), s.name.clone()),
|
||||
row![
|
||||
text(t!("Description:")).size(11).style(muted_style).width(160),
|
||||
text_input("", description_buf)
|
||||
.on_input(|v| Message::TableStyleEdit {
|
||||
field: "description",
|
||||
value: v
|
||||
})
|
||||
.size(11)
|
||||
.width(160),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
text(t!("Flow direction:")).size(11).style(muted_style).width(160),
|
||||
iced::widget::pick_list(
|
||||
Some(EnumChoice(format!("{:?}", s.flow_direction))),
|
||||
enum_choices(&["Down", "Up"]),
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(|choice| Message::TableStyleSetFlow(choice.0))
|
||||
.text_size(11)
|
||||
.width(100),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
text(t!("H Margin:")).size(11).style(muted_style).width(160),
|
||||
text_input("1.5", hmargin_buf)
|
||||
.on_input(|v| Message::TableStyleEdit {
|
||||
field: "hmargin",
|
||||
value: v
|
||||
})
|
||||
.size(11)
|
||||
.width(100),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
row![
|
||||
text(t!("V Margin:")).size(11).style(muted_style).width(160),
|
||||
text_input("1.5", vmargin_buf)
|
||||
.on_input(|v| Message::TableStyleEdit {
|
||||
field: "vmargin",
|
||||
value: v
|
||||
})
|
||||
.size(11)
|
||||
.width(100),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
checkbox(s.title_suppressed)
|
||||
.label(t!("Title row suppressed"))
|
||||
.on_toggle(|_| Message::TableStyleToggle("title_sup"))
|
||||
.size(14)
|
||||
.text_size(11),
|
||||
checkbox(s.header_suppressed)
|
||||
.label(t!("Header row suppressed"))
|
||||
.on_toggle(|_| Message::TableStyleToggle("header_sup"))
|
||||
.size(14)
|
||||
.text_size(11),
|
||||
button(text(t!("Apply margins")).size(11))
|
||||
.on_press(Message::TableStyleApply)
|
||||
.style(btn_s(true))
|
||||
.padding([4, 12]),
|
||||
cell_editor(t!("Data Row:"), 0, &s.data_row_style),
|
||||
cell_editor(t!("Header Row:"), 1, &s.header_row_style),
|
||||
cell_editor(t!("Title Row:"), 2, &s.title_row_style),
|
||||
let selected_alignment = format!("{:?}", row_style.alignment);
|
||||
let mut content = Column::new()
|
||||
.spacing(7)
|
||||
.push(cell_input(t!("Text style"), "Standard", &v.cell_textstyle[index], "textstyle"))
|
||||
.push(cell_input(t!("Text height"), "0.18", &v.cell_height[index], "height"))
|
||||
.push(cell_color(t!("Text color"), &v.cell_textcolor[index], "textcolor"))
|
||||
.push(cell_color(t!("Fill color"), &v.cell_fillcolor[index], "fillcolor"))
|
||||
.push(
|
||||
row![
|
||||
text(t!("Alignment")).size(11).style(muted_style).width(155),
|
||||
iced::widget::pick_list(
|
||||
Some(EnumChoice { code: selected_alignment.clone(), label: crate::i18n::translate(&selected_alignment) }),
|
||||
choices(&[
|
||||
("TopLeft", "Top left"), ("TopCenter", "Top center"), ("TopRight", "Top right"),
|
||||
("MiddleLeft", "Middle left"), ("MiddleCenter", "Middle center"), ("MiddleRight", "Middle right"),
|
||||
("BottomLeft", "Bottom left"), ("BottomCenter", "Bottom center"), ("BottomRight", "Bottom right"),
|
||||
]),
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(move |choice| Message::TableStyleCellSetAlign { row: row_index, value: choice.code })
|
||||
.text_size(11)
|
||||
.width(170),
|
||||
]
|
||||
.spacing(6)
|
||||
.padding([12, 12]),
|
||||
.spacing(8)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.width(sizing.width)
|
||||
.height(sizing.height)
|
||||
.into()
|
||||
} else {
|
||||
container(text(t!("Select a style to view details.")).size(11).style(muted_style))
|
||||
.padding([12, 12])
|
||||
.into()
|
||||
.push(
|
||||
checkbox(row_style.fill_enabled)
|
||||
.label(t!("Background fill enabled"))
|
||||
.on_toggle(move |_| Message::TableStyleCellToggleFill(row_index))
|
||||
.size(14)
|
||||
.text_size(11),
|
||||
)
|
||||
.push(cell_input(t!("Data type"), "0", &v.cell_datatype[index], "datatype"))
|
||||
.push(cell_input(t!("Unit type"), "0", &v.cell_unittype[index], "unittype"))
|
||||
.push(cell_input(t!("Format string"), "", &v.cell_format[index], "format"))
|
||||
.push(text(t!("Borders")).size(11).style(primary_style));
|
||||
let borders = [
|
||||
(t!("Left"), &row_style.left_border),
|
||||
(t!("Right"), &row_style.right_border),
|
||||
(t!("Top"), &row_style.top_border),
|
||||
(t!("Bottom"), &row_style.bottom_border),
|
||||
(t!("Inside horizontal"), &row_style.horizontal_inside_border),
|
||||
(t!("Inside vertical"), &row_style.vertical_inside_border),
|
||||
];
|
||||
for (border_index, (label, border)) in borders.into_iter().enumerate() {
|
||||
let border_index = border_index as u8;
|
||||
let border_type = format!("{:?}", border.border_type);
|
||||
content = content.push(
|
||||
row![
|
||||
text(label).size(10).style(muted_style).width(96),
|
||||
iced::widget::pick_list(
|
||||
Some(EnumChoice { code: border_type.clone(), label: crate::i18n::translate(&border_type) }),
|
||||
choices(&[("Single", "Single"), ("Double", "Double")]),
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(move |choice| Message::TableStyleBorderSetType { cell: row_index, border: border_index, value: choice.code })
|
||||
.text_size(10)
|
||||
.width(82),
|
||||
text_input(t!("Weight").as_ref(), &v.border_lw[index][border_index as usize])
|
||||
.on_input(move |value| Message::TableStyleBorderEdit { cell: row_index, border: border_index, field: "lw", value })
|
||||
.size(10).width(68),
|
||||
text_input(t!("Color").as_ref(), &v.border_color[index][border_index as usize])
|
||||
.on_input(move |value| Message::TableStyleBorderEdit { cell: row_index, border: border_index, field: "color", value })
|
||||
.size(10).width(62),
|
||||
text_input(t!("Spacing").as_ref(), &v.border_spacing[index][border_index as usize])
|
||||
.on_input(move |value| Message::TableStyleBorderEdit { cell: row_index, border: border_index, field: "spacing", value })
|
||||
.size(10).width(68),
|
||||
checkbox(border.is_invisible)
|
||||
.label(t!("Hidden"))
|
||||
.on_toggle(move |_| Message::TableStyleBorderToggleInvisible { cell: row_index, border: border_index })
|
||||
.size(13).text_size(10),
|
||||
]
|
||||
.spacing(5)
|
||||
.align_y(iced::Center),
|
||||
);
|
||||
}
|
||||
content.into()
|
||||
}
|
||||
|
||||
fn preview_rows(v: &TableStyleView<'_>) -> Option<[PreviewRow; 3]> {
|
||||
let style = v.style?;
|
||||
let source = [&style.data_row_style, &style.header_row_style, &style.title_row_style];
|
||||
Some(std::array::from_fn(|row| {
|
||||
let borders = [
|
||||
&source[row].left_border,
|
||||
&source[row].right_border,
|
||||
&source[row].top_border,
|
||||
&source[row].bottom_border,
|
||||
&source[row].horizontal_inside_border,
|
||||
&source[row].vertical_inside_border,
|
||||
];
|
||||
PreviewRow {
|
||||
label: [t!("Data"), t!("Header"), t!("Title")][row].to_string(),
|
||||
text_style: v.cell_textstyle[row].clone(),
|
||||
text_height: v.cell_height[row].clone(),
|
||||
text_color: v.cell_textcolor[row].clone(),
|
||||
fill_color: v.cell_fillcolor[row].clone(),
|
||||
fill: source[row].fill_enabled,
|
||||
alignment: format!("{:?}", source[row].alignment),
|
||||
data_type: v.cell_datatype[row].clone(),
|
||||
unit_type: v.cell_unittype[row].clone(),
|
||||
format: v.cell_format[row].clone(),
|
||||
borders: std::array::from_fn(|border| PreviewBorder {
|
||||
color: v.border_color[row][border].clone(),
|
||||
weight: v.border_lw[row][border].clone(),
|
||||
spacing: v.border_spacing[row][border].clone(),
|
||||
double: format!("{:?}", borders[border].border_type) == "Double",
|
||||
hidden: borders[border].is_invisible,
|
||||
}),
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn view_window<'a>(
|
||||
v: TableStyleView<'a>,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'a, Message> {
|
||||
let style = v.style;
|
||||
let content: Element<'a, Message> = match (v.tab, style) {
|
||||
(_, None) => text(t!("Select a style to view details.")).size(11).into(),
|
||||
(0, Some(style)) => column![
|
||||
input_row(t!("Description"), "", v.description, |value| Message::TableStyleEdit { field: "description", value }),
|
||||
row![
|
||||
text(t!("Flow direction")).size(11).style(muted_style).width(155),
|
||||
iced::widget::pick_list(
|
||||
Some(EnumChoice { code: format!("{:?}", style.flow_direction), label: crate::i18n::translate(&format!("{:?}", style.flow_direction)) }),
|
||||
choices(&[("Down", "Top to bottom"), ("Up", "Bottom to top")]),
|
||||
|value| value.to_string(),
|
||||
)
|
||||
.on_select(|choice| Message::TableStyleSetFlow(choice.code))
|
||||
.text_size(11).width(170),
|
||||
]
|
||||
.spacing(8).align_y(iced::Center),
|
||||
input_row(t!("Horizontal margin"), "1.5", v.hmargin, |value| Message::TableStyleEdit { field: "hmargin", value }),
|
||||
input_row(t!("Vertical margin"), "1.5", v.vmargin, |value| Message::TableStyleEdit { field: "vmargin", value }),
|
||||
checkbox(style.title_suppressed).label(t!("Suppress title row")).on_toggle(|_| Message::TableStyleToggle("title_sup")).size(14).text_size(11),
|
||||
checkbox(style.header_suppressed).label(t!("Suppress header row")).on_toggle(|_| Message::TableStyleToggle("header_sup")).size(14).text_size(11),
|
||||
checkbox(style.annotative).label(t!("Annotative")).on_toggle(|_| Message::TableStyleToggleAnnotative).size(14).text_size(11),
|
||||
]
|
||||
.spacing(9)
|
||||
.into(),
|
||||
(tab, Some(_)) => cell_editor(&v, tab.saturating_sub(1).min(2)),
|
||||
};
|
||||
|
||||
let right_panel = container(details)
|
||||
.width(sizing.width)
|
||||
.height(sizing.height);
|
||||
|
||||
let rows = preview_rows(&v).unwrap_or_else(|| {
|
||||
std::array::from_fn(|row| PreviewRow {
|
||||
label: ["Data", "Header", "Title"][row].to_string(),
|
||||
text_style: String::new(),
|
||||
text_height: String::new(),
|
||||
text_color: String::new(),
|
||||
fill_color: String::new(),
|
||||
fill: false,
|
||||
alignment: "MiddleCenter".to_string(),
|
||||
data_type: String::new(),
|
||||
unit_type: String::new(),
|
||||
format: String::new(),
|
||||
borders: std::array::from_fn(|_| PreviewBorder {
|
||||
color: String::new(), weight: String::new(), spacing: String::new(), double: false, hidden: false,
|
||||
}),
|
||||
})
|
||||
});
|
||||
let preview = canvas(TablePreviewCanvas {
|
||||
rows,
|
||||
active_row: v.tab.saturating_sub(1).min(2) as usize,
|
||||
hmargin: v.hmargin.to_string(),
|
||||
vmargin: v.vmargin.to_string(),
|
||||
description: v.description.to_string(),
|
||||
flow_up: style.is_some_and(|style| format!("{:?}", style.flow_direction) == "Up"),
|
||||
title_suppressed: style.is_some_and(|style| style.title_suppressed),
|
||||
header_suppressed: style.is_some_and(|style| style.header_suppressed),
|
||||
annotative: style.is_some_and(|style| style.annotative),
|
||||
})
|
||||
.width(Length::Fill)
|
||||
.height(150);
|
||||
let status = if v.selected.eq_ignore_ascii_case(v.current) {
|
||||
t!("Current style")
|
||||
} else if v.in_use {
|
||||
t!("Used in drawing")
|
||||
} else {
|
||||
t!("Available style")
|
||||
};
|
||||
let summary = if v.comparison_sections.is_empty() {
|
||||
t!("No differences").into_owned()
|
||||
} else {
|
||||
format!("{}: {}", t!("Different"), v.comparison_sections.join(", "))
|
||||
};
|
||||
let editor = crate::ui::style::style_manager::editor_shell(
|
||||
crate::ui::style::style_manager::EditorShell {
|
||||
sizing,
|
||||
selected: v.selected.to_string(),
|
||||
status,
|
||||
preview: preview.into(),
|
||||
comparison: Some(crate::ui::style::style_manager::EditorComparison {
|
||||
selected: v.compare_name,
|
||||
options: v.compare_opts,
|
||||
summary,
|
||||
on_select: Message::TableStyleDialogCompare,
|
||||
}),
|
||||
tabs: [t!("General"), t!("Data Row"), t!("Header Row"), t!("Title Row")]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(tab, label)| crate::ui::style::style_manager::EditorTab {
|
||||
label,
|
||||
active: v.tab == tab as u8,
|
||||
on_press: Message::TableStyleDialogTab(tab as u8),
|
||||
})
|
||||
.collect(),
|
||||
content,
|
||||
},
|
||||
);
|
||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||
sizing,
|
||||
kind: crate::app::StyleKind::Table,
|
||||
styles: &styles,
|
||||
selected,
|
||||
current: Some(current),
|
||||
rename_active,
|
||||
rename_buf,
|
||||
styles: &v.styles,
|
||||
selected: v.selected,
|
||||
current: Some(v.current),
|
||||
rename_active: v.rename_active,
|
||||
rename_buf: v.rename_buf,
|
||||
on_new: Message::TableStyleDialogNew,
|
||||
on_copy: Message::TableStyleDialogCopy,
|
||||
on_delete: Message::TableStyleDialogDelete,
|
||||
on_select: Message::TableStyleDialogSelect,
|
||||
on_set_current: Message::TableStyleDialogSetCurrent,
|
||||
on_apply: Message::TableStyleApply,
|
||||
editor: right_panel.into(),
|
||||
read_only: false,
|
||||
editor,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
//! Text Style Font Browser window — fills the entire OS window.
|
||||
//! Text style manager.
|
||||
|
||||
use crate::app::Message;
|
||||
use crate::app::StyleKind;
|
||||
use iced::widget::{
|
||||
button, canvas, checkbox, column, container, row, scrollable, text, text_input, Space,
|
||||
};
|
||||
use iced::{mouse, Background, Border, Element, Length, Point, Rectangle, Theme};
|
||||
use crate::app::{Message, StyleKind};
|
||||
use crate::t;
|
||||
use iced::widget::{button, canvas, checkbox, column, container, row, scrollable, text, text_input};
|
||||
use iced::{mouse, Background, Border, Element, Length, Point, Rectangle, Theme};
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// View-model for the Text Style editor window.
|
||||
pub struct TextStyleView<'a> {
|
||||
pub styles: Vec<String>,
|
||||
pub selected: &'a str,
|
||||
/// Name of the current text style (marked with ✓ in the list).
|
||||
pub current: &'a str,
|
||||
pub tab: u8,
|
||||
pub compare_name: String,
|
||||
pub compare_opts: Vec<String>,
|
||||
pub comparison_sections: Vec<String>,
|
||||
pub read_only: bool,
|
||||
pub in_use: bool,
|
||||
pub font_buf: &'a str,
|
||||
pub width_buf: &'a str,
|
||||
pub oblique_buf: &'a str,
|
||||
|
|
@ -23,57 +24,18 @@ pub struct TextStyleView<'a> {
|
|||
pub ttf_buf: &'a str,
|
||||
pub backward: bool,
|
||||
pub upside_down: bool,
|
||||
pub vertical: bool,
|
||||
pub annotative: bool,
|
||||
/// Name of the style being renamed inline (double-clicked), if any.
|
||||
pub rename_active: Option<&'a str>,
|
||||
/// Edit buffer for the inline rename text input.
|
||||
pub rename_buf: &'a str,
|
||||
}
|
||||
|
||||
const BUILTIN_FONTS: &[&str] = &[
|
||||
"Standard", "ISO", "Simplex", "RomanS", "RomanD", "RomanC", "RomanT", "ItalicC", "ItalicT",
|
||||
"ScriptS", "ScriptC", "GothGBT", "GothGRT", "GothITT", "GreekC", "Symbol",
|
||||
"ISO3098", "Unicode",
|
||||
"Standard", "ISO", "Simplex", "RomanS", "RomanD", "RomanC", "RomanT", "ItalicC",
|
||||
"ItalicT", "ScriptS", "ScriptC", "GothGBT", "GothGRT", "GothITT", "GreekC",
|
||||
"Symbol", "ISO3098", "Unicode",
|
||||
];
|
||||
|
||||
fn list_item(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
move |theme: &Theme, st| {
|
||||
let palette = theme.palette();
|
||||
let pair = match (active, st) {
|
||||
(true, _) => Some(palette.primary.strong),
|
||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||
Some(palette.background.strong)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
button::Style {
|
||||
background: pair.map(|p| Background::Color(p.color)),
|
||||
text_color: pair.map(|p| p.text).unwrap_or(palette.background.base.text),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||
let palette = theme.palette();
|
||||
let border = match status {
|
||||
text_input::Status::Focused { .. } => palette.primary.base.color,
|
||||
_ => palette.background.neutral.color,
|
||||
};
|
||||
text_input::Style {
|
||||
background: Background::Color(palette.background.base.color),
|
||||
border: Border {
|
||||
color: border,
|
||||
width: 1.0,
|
||||
radius: 3.0.into(),
|
||||
},
|
||||
icon: palette.background.base.text,
|
||||
placeholder: palette.background.base.text.scale_alpha(0.48),
|
||||
value: palette.background.base.text,
|
||||
selection: palette.primary.base.color.scale_alpha(0.5),
|
||||
}
|
||||
}
|
||||
|
||||
fn muted_style(theme: &Theme) -> iced::widget::text::Style {
|
||||
iced::widget::text::Style {
|
||||
color: Some(theme.palette().background.base.text.scale_alpha(0.68)),
|
||||
|
|
@ -86,33 +48,55 @@ fn primary_style(theme: &Theme) -> iced::widget::text::Style {
|
|||
}
|
||||
}
|
||||
|
||||
fn vsep<'a>(height: Length) -> Element<'a, Message> {
|
||||
container(Space::new().width(1).height(height))
|
||||
.width(1)
|
||||
.height(height)
|
||||
.style(|theme: &Theme| container::Style {
|
||||
background: Some(Background::Color(
|
||||
theme.palette().background.neutral.color
|
||||
)),
|
||||
..Default::default()
|
||||
})
|
||||
.into()
|
||||
fn field_style(theme: &Theme, status: text_input::Status) -> text_input::Style {
|
||||
let palette = theme.palette();
|
||||
text_input::Style {
|
||||
background: Background::Color(palette.background.base.color),
|
||||
border: Border {
|
||||
color: if matches!(status, text_input::Status::Focused { .. }) {
|
||||
palette.primary.base.color
|
||||
} else {
|
||||
palette.background.neutral.color
|
||||
},
|
||||
width: 1.0,
|
||||
radius: 3.0.into(),
|
||||
},
|
||||
icon: palette.background.base.text,
|
||||
placeholder: palette.background.base.text.scale_alpha(0.48),
|
||||
value: palette.background.base.text,
|
||||
selection: palette.primary.base.color.scale_alpha(0.5),
|
||||
}
|
||||
}
|
||||
|
||||
fn list_item(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
move |theme: &Theme, status| {
|
||||
let palette = theme.palette();
|
||||
let pair = match (active, status) {
|
||||
(true, _) => Some(palette.primary.strong),
|
||||
(false, button::Status::Hovered | button::Status::Pressed) => {
|
||||
Some(palette.background.strong)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
button::Style {
|
||||
background: pair.map(|value| Background::Color(value.color)),
|
||||
text_color: pair
|
||||
.map(|value| value.text)
|
||||
.unwrap_or(palette.background.base.text),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Live sample-text preview. Tessellates a fixed sample string through the same
|
||||
/// stroke path the text entities use (`lff::tessellate_text_ex`), so the chosen
|
||||
/// font, width factor, oblique angle and backward/upside-down flags all show up,
|
||||
/// then scales the result to fit the preview box (Y flipped: glyph space is
|
||||
/// Y-up, screen is Y-down). Height is not bound — it only scales uniformly and
|
||||
/// the fit cancels it.
|
||||
struct TextPreviewCanvas {
|
||||
font: String,
|
||||
/// Negative mirrors left-right (backward).
|
||||
big_font: String,
|
||||
width_factor: f32,
|
||||
/// Radians.
|
||||
oblique: f32,
|
||||
/// 0 or π (upside-down rotates 180° about the origin).
|
||||
rotation: f32,
|
||||
height: f32,
|
||||
upside_down: bool,
|
||||
vertical: bool,
|
||||
annotative: bool,
|
||||
}
|
||||
|
||||
impl canvas::Program<Message> for TextPreviewCanvas {
|
||||
|
|
@ -127,314 +111,311 @@ impl canvas::Program<Message> for TextPreviewCanvas {
|
|||
_cursor: mouse::Cursor,
|
||||
) -> Vec<canvas::Geometry> {
|
||||
let mut frame = canvas::Frame::new(renderer, bounds.size());
|
||||
let (strokes, _) = crate::scene::text::lff::tessellate_text_ex(
|
||||
[0.0, 0.0],
|
||||
9.0,
|
||||
self.rotation,
|
||||
self.width_factor,
|
||||
self.oblique,
|
||||
&self.font,
|
||||
"AaBbCc 0123",
|
||||
);
|
||||
let ink = theme.palette().background.base.text;
|
||||
let glyph_height = if self.height <= 0.0 {
|
||||
18.0
|
||||
} else {
|
||||
(self.height * 7.0).clamp(6.0, 52.0)
|
||||
};
|
||||
let rotation = if self.upside_down {
|
||||
std::f32::consts::PI
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let strokes = if self.vertical {
|
||||
let mut result = Vec::new();
|
||||
for (index, character) in "Ab3".chars().enumerate() {
|
||||
let (mut glyph, _) = crate::scene::text::lff::tessellate_text_ex(
|
||||
[0.0, -(index as f32) * glyph_height * 1.25],
|
||||
glyph_height,
|
||||
rotation,
|
||||
self.width_factor,
|
||||
self.oblique,
|
||||
&self.font,
|
||||
&character.to_string(),
|
||||
);
|
||||
result.append(&mut glyph);
|
||||
}
|
||||
result
|
||||
} else {
|
||||
crate::scene::text::lff::tessellate_text_ex(
|
||||
[0.0, 0.0],
|
||||
glyph_height,
|
||||
rotation,
|
||||
self.width_factor,
|
||||
self.oblique,
|
||||
&self.font,
|
||||
"AaBbCc 0123",
|
||||
)
|
||||
.0
|
||||
};
|
||||
let mut min = [f32::MAX; 2];
|
||||
let mut max = [f32::MIN; 2];
|
||||
for s in &strokes {
|
||||
for &[x, y] in s {
|
||||
for stroke in &strokes {
|
||||
for &[x, y] in stroke {
|
||||
min[0] = min[0].min(x);
|
||||
min[1] = min[1].min(y);
|
||||
max[0] = max[0].max(x);
|
||||
max[1] = max[1].max(y);
|
||||
}
|
||||
}
|
||||
if min[0] > max[0] {
|
||||
return vec![frame.into_geometry()];
|
||||
}
|
||||
let pad = 10.0;
|
||||
let span = [(max[0] - min[0]).max(1e-3), (max[1] - min[1]).max(1e-3)];
|
||||
let scale = ((bounds.width - 2.0 * pad) / span[0])
|
||||
.min((bounds.height - 2.0 * pad) / span[1])
|
||||
.max(0.0);
|
||||
let mid = [(min[0] + max[0]) * 0.5, (min[1] + max[1]) * 0.5];
|
||||
let center = [bounds.width * 0.5, bounds.height * 0.5];
|
||||
let map = |x: f32, y: f32| {
|
||||
Point::new(
|
||||
center[0] + (x - mid[0]) * scale,
|
||||
center[1] - (y - mid[1]) * scale,
|
||||
)
|
||||
};
|
||||
let stroke = canvas::Stroke {
|
||||
width: 1.4,
|
||||
style: canvas::Style::Solid(theme.palette().background.base.text),
|
||||
..Default::default()
|
||||
};
|
||||
for s in &strokes {
|
||||
if s.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
let path = canvas::Path::new(|p| {
|
||||
p.move_to(map(s[0][0], s[0][1]));
|
||||
for &[x, y] in &s[1..] {
|
||||
p.line_to(map(x, y));
|
||||
if min[0] <= max[0] {
|
||||
let span = [(max[0] - min[0]).max(1.0), (max[1] - min[1]).max(1.0)];
|
||||
let available = [bounds.width - 24.0, bounds.height - 34.0];
|
||||
let scale = (available[0] / span[0])
|
||||
.min(available[1] / span[1])
|
||||
.min(1.0)
|
||||
.max(0.0);
|
||||
let middle = [(min[0] + max[0]) * 0.5, (min[1] + max[1]) * 0.5];
|
||||
let center = [bounds.width * 0.5, (bounds.height - 18.0) * 0.5];
|
||||
let map = |x: f32, y: f32| {
|
||||
Point::new(
|
||||
center[0] + (x - middle[0]) * scale,
|
||||
center[1] - (y - middle[1]) * scale,
|
||||
)
|
||||
};
|
||||
for stroke in &strokes {
|
||||
if stroke.len() < 2 {
|
||||
continue;
|
||||
}
|
||||
});
|
||||
frame.stroke(&path, stroke.clone());
|
||||
let path = canvas::Path::new(|builder| {
|
||||
builder.move_to(map(stroke[0][0], stroke[0][1]));
|
||||
for &[x, y] in &stroke[1..] {
|
||||
builder.line_to(map(x, y));
|
||||
}
|
||||
});
|
||||
frame.stroke(
|
||||
&path,
|
||||
canvas::Stroke::default().with_color(ink).with_width(1.35),
|
||||
);
|
||||
}
|
||||
}
|
||||
let font_label = if self.big_font.trim().is_empty() {
|
||||
self.font.clone()
|
||||
} else {
|
||||
format!("{} + {}", self.font, self.big_font)
|
||||
};
|
||||
let mode = if self.annotative {
|
||||
t!("Paper height")
|
||||
} else {
|
||||
t!("Drawing height")
|
||||
};
|
||||
frame.fill_text(canvas::Text {
|
||||
content: format!("{} · {} {:.3}", font_label, mode, self.height),
|
||||
position: Point::new(10.0, bounds.height - 9.0),
|
||||
color: ink.scale_alpha(0.65),
|
||||
size: iced::Pixels(10.0),
|
||||
align_y: iced::alignment::Vertical::Center,
|
||||
..Default::default()
|
||||
});
|
||||
vec![frame.into_geometry()]
|
||||
}
|
||||
}
|
||||
|
||||
fn input_row<'a>(
|
||||
label: Cow<'static, str>,
|
||||
placeholder: Cow<'static, str>,
|
||||
value: &'a str,
|
||||
field: &'static str,
|
||||
read_only: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let control: Element<'a, Message> = if read_only {
|
||||
container(text(value).size(11)).padding([5, 7]).width(180).into()
|
||||
} else {
|
||||
text_input(placeholder.as_ref(), value)
|
||||
.on_input(move |value| Message::TextStyleEdit { field, value })
|
||||
.style(field_style)
|
||||
.size(11)
|
||||
.width(180)
|
||||
.into()
|
||||
};
|
||||
row![text(label).size(11).style(muted_style).width(150), control]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn toggle<'a>(
|
||||
label: Cow<'static, str>,
|
||||
value: bool,
|
||||
field: &'static str,
|
||||
read_only: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let checkbox = checkbox(value).label(label).size(14).text_size(11);
|
||||
if read_only {
|
||||
checkbox.into()
|
||||
} else {
|
||||
checkbox
|
||||
.on_toggle(move |_| Message::TextStyleToggle(field))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn font_list<'a>(
|
||||
title: Cow<'static, str>,
|
||||
values: Vec<String>,
|
||||
selected: &'a str,
|
||||
system: bool,
|
||||
read_only: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let items: Vec<Element<'a, Message>> = values
|
||||
.into_iter()
|
||||
.map(|font| {
|
||||
let active = selected.eq_ignore_ascii_case(&font);
|
||||
let button = button(text(font.clone()).size(10))
|
||||
.style(list_item(active))
|
||||
.padding([3, 8])
|
||||
.width(Length::Fill);
|
||||
if read_only {
|
||||
button.into()
|
||||
} else if system {
|
||||
button
|
||||
.on_press(Message::TextStyleEdit {
|
||||
field: "ttf",
|
||||
value: font,
|
||||
})
|
||||
.into()
|
||||
} else {
|
||||
button.on_press(Message::TextStyleFontPick(font)).into()
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
container(column![text(title).size(10).style(muted_style), scrollable(column(items).spacing(1)).height(250)].spacing(5))
|
||||
.width(Length::FillPortion(1))
|
||||
.padding(4)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn view_window<'a>(
|
||||
v: TextStyleView<'a>,
|
||||
sizing: crate::ui::modal::ModalSizing,
|
||||
) -> Element<'a, Message> {
|
||||
let TextStyleView {
|
||||
styles,
|
||||
selected,
|
||||
current,
|
||||
font_buf,
|
||||
width_buf,
|
||||
oblique_buf,
|
||||
height_buf,
|
||||
bigfont_buf,
|
||||
ttf_buf,
|
||||
backward,
|
||||
upside_down,
|
||||
annotative,
|
||||
rename_active,
|
||||
rename_buf,
|
||||
} = v;
|
||||
// ── Middle: Font browser ──────────────────────────────────────────────
|
||||
let font_items: Vec<Element<'_, Message>> = BUILTIN_FONTS
|
||||
.iter()
|
||||
.map(|&f| {
|
||||
let is_sel = font_buf == f;
|
||||
button(text(f).size(10))
|
||||
.on_press(Message::TextStyleFontPick(f.to_string()))
|
||||
.style(list_item(is_sel))
|
||||
.padding([3, 8])
|
||||
.width(sizing.width)
|
||||
.into()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let font_panel = container(
|
||||
column![
|
||||
text(t!("Font File")).size(10).style(muted_style),
|
||||
container(scrollable(column(font_items).spacing(1)).height(sizing.height))
|
||||
.style(|theme: &Theme| {
|
||||
let palette = theme.palette();
|
||||
container::Style {
|
||||
background: Some(Background::Color(palette.background.weak.color)),
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 3.0.into()
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
.width(sizing.width)
|
||||
.height(sizing.height)
|
||||
.padding(2),
|
||||
text_input(t!("font file…").as_ref(), font_buf)
|
||||
.on_input(|v| Message::TextStyleEdit {
|
||||
field: "font",
|
||||
value: v
|
||||
})
|
||||
.style(field_style)
|
||||
.size(11)
|
||||
.width(sizing.width),
|
||||
]
|
||||
.spacing(6)
|
||||
.height(sizing.height),
|
||||
)
|
||||
.width(190)
|
||||
.height(sizing.height)
|
||||
.padding([12, 8]);
|
||||
|
||||
// Labeled numeric/text field row → TextStyleEdit { field, value }.
|
||||
fn frow<'a>(
|
||||
label: impl Into<Cow<'static, str>>,
|
||||
ph: impl Into<Cow<'static, str>>,
|
||||
buf: &'a str,
|
||||
field: &'static str,
|
||||
) -> Element<'a, Message> {
|
||||
row![
|
||||
text(label.into()).size(11).style(muted_style).width(120),
|
||||
text_input(ph.into().as_ref(), buf)
|
||||
.on_input(move |v| Message::TextStyleEdit { field, value: v })
|
||||
.style(field_style)
|
||||
.size(11)
|
||||
.width(140),
|
||||
]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
// Live preview reflecting the in-progress edits. Effective font follows the
|
||||
// entity rule: TrueType name wins when set, else the stroke font file.
|
||||
let eff_font = if !ttf_buf.trim().is_empty() {
|
||||
ttf_buf
|
||||
let effective_font = if v.ttf_buf.trim().is_empty() {
|
||||
v.font_buf
|
||||
} else {
|
||||
font_buf
|
||||
v.ttf_buf
|
||||
};
|
||||
let prev_base_wf = width_buf
|
||||
let width = v
|
||||
.width_buf
|
||||
.trim()
|
||||
.parse::<f32>()
|
||||
.unwrap_or(1.0)
|
||||
.abs()
|
||||
.clamp(0.01, 100.0);
|
||||
let preview = canvas(TextPreviewCanvas {
|
||||
font: eff_font.to_string(),
|
||||
width_factor: if backward { -prev_base_wf } else { prev_base_wf },
|
||||
oblique: oblique_buf.trim().parse::<f32>().unwrap_or(0.0).to_radians(),
|
||||
rotation: if upside_down { std::f32::consts::PI } else { 0.0 },
|
||||
font: effective_font.to_string(),
|
||||
big_font: v.bigfont_buf.to_string(),
|
||||
width_factor: if v.backward { -width } else { width },
|
||||
oblique: v.oblique_buf.trim().parse::<f32>().unwrap_or(0.0).to_radians(),
|
||||
height: v.height_buf.trim().parse::<f32>().unwrap_or(0.0).max(0.0),
|
||||
upside_down: v.upside_down,
|
||||
vertical: v.vertical,
|
||||
annotative: v.annotative,
|
||||
})
|
||||
.width(sizing.width)
|
||||
.height(Length::Fixed(56.0));
|
||||
.width(Length::Fill)
|
||||
.height(112);
|
||||
|
||||
// ── Right: Properties ─────────────────────────────────────────────────
|
||||
let props_panel = container(
|
||||
column![
|
||||
text(t!("Properties")).size(11).style(primary_style),
|
||||
frow(t!("Big Font:"), t!("big-font file…"), bigfont_buf, "bigfont"),
|
||||
frow(t!("TrueType Font:"), t!("e.g. Arial"), ttf_buf, "ttf"),
|
||||
frow(
|
||||
if annotative {
|
||||
t!("Paper Text Height:")
|
||||
} else {
|
||||
t!("Fixed Height:")
|
||||
},
|
||||
t!("0 = variable"),
|
||||
height_buf,
|
||||
"height",
|
||||
),
|
||||
frow(t!("Width Factor:"), "1.0", width_buf, "width"),
|
||||
frow(t!("Oblique (°):"), "0.0", oblique_buf, "oblique"),
|
||||
row![
|
||||
checkbox(backward)
|
||||
.label(t!("Backward"))
|
||||
.on_toggle(|_| Message::TextStyleToggle("backward"))
|
||||
.size(15)
|
||||
.text_size(11),
|
||||
checkbox(upside_down)
|
||||
.label(t!("Upside down"))
|
||||
.on_toggle(|_| Message::TextStyleToggle("upside_down"))
|
||||
.size(15)
|
||||
.text_size(11),
|
||||
let content: Element<'a, Message> = match v.tab {
|
||||
0 => {
|
||||
let built_in = BUILTIN_FONTS.iter().map(|value| (*value).to_string()).collect();
|
||||
let system = crate::scene::text::sysfont::families().to_vec();
|
||||
column![
|
||||
row![
|
||||
font_list(t!("Stroke fonts"), built_in, v.font_buf, false, v.read_only),
|
||||
font_list(t!("System fonts"), system, v.ttf_buf, true, v.read_only),
|
||||
]
|
||||
.spacing(10),
|
||||
input_row(t!("Font file"), t!("font file…"), v.font_buf, "font", v.read_only),
|
||||
input_row(t!("Big font"), t!("big-font file…"), v.bigfont_buf, "bigfont", v.read_only),
|
||||
input_row(t!("System font"), t!("font family…"), v.ttf_buf, "ttf", v.read_only),
|
||||
]
|
||||
.spacing(16),
|
||||
checkbox(annotative)
|
||||
.label(t!("Annotative"))
|
||||
.on_toggle(|_| Message::TextStyleToggle("annotative"))
|
||||
.size(15)
|
||||
.text_size(11),
|
||||
Space::new().height(8),
|
||||
text(t!("Preview")).size(10).style(muted_style),
|
||||
container(preview)
|
||||
.style(|theme: &Theme| {
|
||||
let palette = theme.palette();
|
||||
container::Style {
|
||||
background: Some(Background::Color(palette.background.base.color)),
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 4.0.into()
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
.padding(8)
|
||||
.width(sizing.width),
|
||||
.spacing(8)
|
||||
.into()
|
||||
}
|
||||
_ => column![
|
||||
text(t!("Size")).size(11).style(primary_style),
|
||||
input_row(
|
||||
if v.annotative { t!("Paper text height") } else { t!("Fixed height") },
|
||||
t!("0 = variable"),
|
||||
v.height_buf,
|
||||
"height",
|
||||
v.read_only,
|
||||
),
|
||||
text(t!("Effects")).size(11).style(primary_style),
|
||||
input_row(t!("Width factor"), "1.0".into(), v.width_buf, "width", v.read_only),
|
||||
input_row(t!("Oblique angle"), "0.0".into(), v.oblique_buf, "oblique", v.read_only),
|
||||
row![
|
||||
toggle(t!("Backward"), v.backward, "backward", v.read_only),
|
||||
toggle(t!("Upside down"), v.upside_down, "upside_down", v.read_only),
|
||||
toggle(
|
||||
t!("Vertical"),
|
||||
v.vertical,
|
||||
"vertical",
|
||||
v.read_only || !v.ttf_buf.trim().is_empty(),
|
||||
),
|
||||
]
|
||||
.spacing(18),
|
||||
toggle(t!("Annotative"), v.annotative, "annotative", v.read_only),
|
||||
]
|
||||
.spacing(10)
|
||||
.height(sizing.height),
|
||||
)
|
||||
.width(sizing.width)
|
||||
.height(sizing.height)
|
||||
.padding(iced::Padding {
|
||||
top: 12.0,
|
||||
right: 12.0,
|
||||
bottom: 12.0,
|
||||
left: 8.0,
|
||||
});
|
||||
|
||||
// ── System TrueType fonts (read from the user's machine via fontdb) ──
|
||||
let ttf_items: Vec<Element<'_, Message>> = crate::scene::text::sysfont::families()
|
||||
.iter()
|
||||
.map(|fam| {
|
||||
let is_sel = ttf_buf.eq_ignore_ascii_case(fam);
|
||||
button(text(fam).size(10))
|
||||
.on_press(Message::TextStyleEdit {
|
||||
field: "ttf",
|
||||
value: fam.clone(),
|
||||
})
|
||||
.style(list_item(is_sel))
|
||||
.padding([3, 8])
|
||||
.width(sizing.width)
|
||||
.into()
|
||||
})
|
||||
.collect();
|
||||
|
||||
let ttf_panel = container(
|
||||
column![
|
||||
text(t!("TrueType (system)")).size(10).style(muted_style),
|
||||
container(scrollable(column(ttf_items).spacing(1)).height(sizing.height))
|
||||
.style(|theme: &Theme| {
|
||||
let palette = theme.palette();
|
||||
container::Style {
|
||||
background: Some(Background::Color(palette.background.weak.color)),
|
||||
border: Border {
|
||||
color: palette.background.neutral.color,
|
||||
width: 1.0,
|
||||
radius: 3.0.into()
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
})
|
||||
.width(sizing.width)
|
||||
.height(sizing.height)
|
||||
.padding(2),
|
||||
text_input(t!("TrueType font…").as_ref(), ttf_buf)
|
||||
.on_input(|v| Message::TextStyleEdit {
|
||||
field: "ttf",
|
||||
value: v
|
||||
})
|
||||
.style(field_style)
|
||||
.size(11)
|
||||
.width(sizing.width),
|
||||
]
|
||||
.spacing(6)
|
||||
.height(sizing.height),
|
||||
)
|
||||
.width(190)
|
||||
.height(sizing.height)
|
||||
.padding([12, 8]);
|
||||
|
||||
let editor = row![
|
||||
font_panel,
|
||||
vsep(sizing.height),
|
||||
ttf_panel,
|
||||
vsep(sizing.height),
|
||||
props_panel
|
||||
]
|
||||
.height(sizing.height);
|
||||
|
||||
.spacing(9)
|
||||
.into(),
|
||||
};
|
||||
let status = if v.read_only {
|
||||
t!("Referenced style · Read only")
|
||||
} else if v.selected.eq_ignore_ascii_case(v.current) {
|
||||
t!("Current style")
|
||||
} else if v.in_use {
|
||||
t!("Used in drawing")
|
||||
} else {
|
||||
t!("Available style")
|
||||
};
|
||||
let summary = if v.comparison_sections.is_empty() {
|
||||
t!("No differences").into_owned()
|
||||
} else {
|
||||
format!("{}: {}", t!("Different"), v.comparison_sections.join(", "))
|
||||
};
|
||||
let editor = crate::ui::style::style_manager::editor_shell(
|
||||
crate::ui::style::style_manager::EditorShell {
|
||||
sizing,
|
||||
selected: v.selected.to_string(),
|
||||
status,
|
||||
preview: preview.into(),
|
||||
comparison: Some(crate::ui::style::style_manager::EditorComparison {
|
||||
selected: v.compare_name,
|
||||
options: v.compare_opts,
|
||||
summary,
|
||||
on_select: Message::TextStyleDialogCompare,
|
||||
}),
|
||||
tabs: vec![
|
||||
crate::ui::style::style_manager::EditorTab {
|
||||
label: t!("Fonts"),
|
||||
active: v.tab == 0,
|
||||
on_press: Message::TextStyleDialogTab(0),
|
||||
},
|
||||
crate::ui::style::style_manager::EditorTab {
|
||||
label: t!("Size and Effects"),
|
||||
active: v.tab == 1,
|
||||
on_press: Message::TextStyleDialogTab(1),
|
||||
},
|
||||
],
|
||||
content,
|
||||
},
|
||||
);
|
||||
crate::ui::style::style_manager::view(crate::ui::style::style_manager::Scaffold {
|
||||
sizing,
|
||||
kind: StyleKind::Text,
|
||||
styles: &styles,
|
||||
selected,
|
||||
current: Some(current),
|
||||
rename_active,
|
||||
rename_buf,
|
||||
styles: &v.styles,
|
||||
selected: v.selected,
|
||||
current: Some(v.current),
|
||||
rename_active: v.rename_active,
|
||||
rename_buf: v.rename_buf,
|
||||
on_new: Message::TextStyleDialogNew,
|
||||
on_copy: Message::TextStyleDialogCopy,
|
||||
on_delete: Message::TextStyleDialogDelete,
|
||||
on_select: Message::TextStyleDialogSelect,
|
||||
on_set_current: Message::TextStyleDialogSetCurrent,
|
||||
on_apply: Message::TextStyleApply,
|
||||
editor: editor.into(),
|
||||
read_only: v.read_only,
|
||||
editor,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue