Skip to content

Fix text box orientation in right to left translation mode#12256

Merged
niksedk merged 9 commits into
SubtitleEdit:mainfrom
muaz978:fix/rtl-translation-textbox-orientation
Jul 8, 2026
Merged

Fix text box orientation in right to left translation mode#12256
niksedk merged 9 commits into
SubtitleEdit:mainfrom
muaz978:fix/rtl-translation-textbox-orientation

Conversation

@muaz978

@muaz978 muaz978 commented Jul 7, 2026

Copy link
Copy Markdown

Fixes #12249.

Problem

With right to left mode enabled in translation mode, the subtitle grid and the text boxes below it no longer correspond. The right to left helper sets FlowDirection on the DataGrid, which mirrors the whole list, so the Original column renders on the left. The text edit area below is a plain grid (current text in the first column, original text in the second) that the helper never touched, so the two text boxes kept their left to right positions: Original column on the left, original text box on the right. Subtitle Edit 4 mirrored both together.

Fix

Two parts, developed and verified iteratively on macOS with a Turkish and Arabic subtitle pair:

  1. Box positions follow the mirrored grid. Setting FlowDirection on a plain grid turned out not to rearrange its children (only the DataGrid honors it for column order), so the text edit grid now carries a name and the right to left helper mirrors its columns for real: the column definitions are reversed (the original column's width binding travels with its definition object, so the collapse when no original is loaded keeps working) and every child is remapped to the mirrored column index. Idempotent through the grid's Tag, so repeated passes from the window open and toggle paths cannot double swap.

  2. Text direction follows the content; the layout follows the mode. Right to left mode used to force every text control right to left (pushing a Turkish original under an Arabic working language to the wrong side of its box), and left to right mode forced everything left to right (pushing an Arabic original under a Turkish working language to the wrong side). The two edit text boxes (both the plain and the color tags variants) and the Text and Original text grid columns now detect their content through LanguageAutoDetect.ContainsRightToLeftLetter in either mode, so each language reads from its own side whatever the mode is; empty controls follow the active mode so typing starts on the expected side. The layout itself (column order, box positions) still changes only with the mode toggle, exactly like Subtitle Edit 4. Subtitle Edit 4 resolved box direction per file and only in right to left mode (FixRightToLeftDependingOnLanguage); resolving per line and in both modes came out of testing all four language arrangements. The boxes re-evaluate on every text change, the grid cells bind through a converter (producing explicit directions, since a binding that yields UnsetValue falls back to the property default rather than the inherited direction), and toggling the mode rebinds the grid so the cells update immediately.

  3. The mode is applied after every layout build. The window level right to left pass runs when the window opens, but the main layout is built later (posted to the dispatcher after the view attaches), so starting the app with right to left mode already enabled walked a tree that did not contain the subtitle grid or the text boxes yet: the layout came up left to right and only looked correct after toggling the mode by hand. Switching layouts had the same effect, since the rebuilt controls start left to right. The pass is now re-applied after the deferred startup layout build, after a layout switch, and after the undocked video layout rebuild; it is idempotent (the grid mirror tracks its state, directions are recomputed from content), so repeated application is safe. Toggling the mode also rebinds the subtitle grid's items source so the per line converter picks up the new mode immediately.

Scope

  • Applies on toggle and on window open (both call sites share the helper).
  • The right to left UI language path (whole window flow direction) is unchanged.
  • Other windows are unaffected by the mirroring; the helper matches the edit grid by name. Text boxes elsewhere pick up content aware direction only through the existing recursive pass, which already touched them.
  • In left to right mode the layout never changes; only text direction inside cells and boxes follows the content.

Testing

Verified on macOS (Apple Silicon) with a Turkish and an Arabic subtitle in all four arrangements (each language as the working and as the original subtitle, in each mode), including starting the app with right to left mode already enabled from the previous session:

  • Right to left mode: the original text box sits under the Original column exactly as in Subtitle Edit 4, the Turkish side reads from the left, the Arabic side from the right, in the grid and in the boxes.
  • Left to right mode: layout unchanged; a right to left original next to a left to right working language reads from the right in its column and box, and files with only left to right content look exactly as before.
  • Toggling back and forth restores each arrangement with no double swap; other windows are unchanged.

Screenshots for both cases are in the comments.

With right to left enabled and an original subtitle loaded, the subtitle grid
is mirrored (the helper sets FlowDirection on the DataGrid), so the Original
column renders on the left. The text edit area below is a plain grid that the
helper never touched, so the current and original text boxes kept their left
to right positions and no longer lined up with the grid columns above them.
Subtitle Edit 4 mirrored both, with the original text box under the original
column.

The text edit grid now carries a name and the right to left helper mirrors it
together with the subtitle grid, so the text boxes, their labels, and the
length indicators follow the same orientation. Windows without that grid are
unaffected, and the pure right to left UI language path (whole window flow
direction) already mirrored everything consistently.
@niksedk

niksedk commented Jul 8, 2026

Copy link
Copy Markdown
Member

Could you add a screenshot or two?

Muaz added 2 commits July 8, 2026 08:53
Testing the first version on macOS showed that setting FlowDirection on the
edit grid does not rearrange its children; only the DataGrid honors the
property for column order, so the subtitle grid mirrored while the text boxes
stayed put and the mismatch from the issue remained.

The helper now swaps the columns physically: the column definitions are
reversed (the original column's width binding travels with its definition
object, so the collapse when no original subtitle is loaded keeps working) and
every child is remapped to the mirrored column index. The operation is
idempotent through the grid's Tag, so repeated passes from the window open and
toggle paths cannot double swap.
Right to left mode used to force every text box right to left, so with a left
to right original subtitle loaded (for example Turkish under an Arabic working
language) the original text was pushed to the wrong side of its box and read
awkwardly. The list and the boxes now follow the text itself: a control whose
content contains right to left letters stays right to left, content in a left
to right script aligns left to right, and empty controls keep the right to
left direction so typing in a right to left language starts on the correct
side. The edit text boxes re-evaluate on every text change, so the direction
tracks the selected line while navigating a mixed language subtitle.
@muaz978

muaz978 commented Jul 8, 2026

Copy link
Copy Markdown
Author

Please see the photo below:
image
The problem was solved but we need to adjust it to make auto detect languages and accordingly align the text.

@muaz978

muaz978 commented Jul 8, 2026

Copy link
Copy Markdown
Author

I will compile again, test and attach a screenshot for after polish.

Muaz added 2 commits July 8, 2026 13:14
The previous commit only covered the color tags editor, but right to left mode
forces that editor off, so the boxes in actual right to left sessions are
plain text boxes that received their direction once, while still empty, from
the recursive pass at window open. They now follow their content through a
property observer attached at creation, and the Text and Original text grid
columns get the same treatment through a converter bound per cell: in right to
left mode a cell whose content is in a left to right script flows left to
right, and in every other case the binding stays unset so the cell keeps the
inherited direction. A Turkish original next to an Arabic working language now
reads from the left in both the grid and its text box while the Arabic side
keeps reading from the right.
The auto detection used to engage only while right to left mode was on. With a
left to right working language and a right to left original (for example a
Turkish subtitle with an Arabic original), the Arabic column and text box were
forced left to right and read from the wrong side. The detection is now
symmetric: content with right to left letters flows right to left in either
mode, content in a left to right script flows left to right in either mode,
and empty controls follow the active mode so typing starts on the expected
side.
@muaz978

muaz978 commented Jul 8, 2026

Copy link
Copy Markdown
Author
image image Please check these dear, @niksedk, and tell me if there is any adjustment you want. The Screenshots are for both cases; working on translating RTL or LTR languages.

Muaz added 4 commits July 8, 2026 14:59
This reverts the change that applied content based text direction in both
modes. Checking how Subtitle Edit 4 handles this (Main.cs,
FixRightToLeftDependingOnLanguage and the right to left mode menu handler):
outside right to left mode nothing is direction adjusted at all, in the list
or in the text boxes, whatever the content language. Applying content
direction in left to right mode changed the appearance of plain single
subtitle files compared to both Subtitle Edit 4 and current Subtitle Edit 5,
which is out of scope here.

Right to left mode keeps the content aware direction from the previous
commits (Subtitle Edit 4 does the same per file through
FixRightToLeftDependingOnLanguage; per line is a refinement of that), and
left to right mode is again untouched.
…n toggle

The per line flow direction converter returned UnsetValue for right to left
content, expecting the cell to inherit the mirrored grid's direction. A
binding that yields UnsetValue does not fall back to the inherited value but
to the property default (left to right), so in right to left mode every right
to left cell rendered left to right. The converter now always produces an
explicit direction: content based in right to left mode, left to right
otherwise.

Since the converter reads the mode setting and bindings do not re-evaluate
when a setting changes, toggling the mode also rebinds the subtitle grid's
items source (restoring selection and scroll position), so the cells pick up
the new mode immediately instead of only after a reload.
Testing all four arrangements showed one remaining gap: with a left to right
working language and a right to left original (for example Turkish plus an
Arabic original) in left to right mode, the original column and text box
rendered the right to left text left aligned.

Text direction now follows the content in either mode, in the grid cells and
in the text boxes, while the layout itself (column order, box positions)
still follows only the mode toggle exactly like Subtitle Edit 4. Empty
controls follow the active mode so typing starts on the expected side. The
earlier attempt at this was reverted because the converter still returned
UnsetValue for right to left content; with the converter producing explicit
directions and the grid rebinding on toggle, the content based behavior is
correct in all four arrangements: each language reads from its own side
whatever the mode, and the mode only decides the layout.
@niksedk niksedk merged commit ec405e0 into SubtitleEdit:main Jul 8, 2026
2 checks passed
@muaz978

muaz978 commented Jul 8, 2026

Copy link
Copy Markdown
Author

Final state after full testing of all four language arrangements. Three follow up commits since the last screenshots:

  1. The flow direction converter now always produces an explicit direction. It returned UnsetValue for right to left content expecting inheritance from the mirrored grid, but a binding that yields UnsetValue falls back to the property default (left to right), which misaligned right to left cells in right to left mode.
  2. Text direction follows the content in both modes: a right to left original next to a left to right working language now reads from the right also in left to right mode. The layout itself still changes only with the mode toggle.
  3. The right to left pass is re-applied after every layout build. It used to run only at window open, which is before the deferred layout build, so starting the app with the mode already enabled came up left to right until the mode was toggled by hand. Layout switches had the same problem.

Verified on macOS in all four arrangements, screenshots follow: Turkish working subtitle in left to right mode, Arabic working subtitle in right to left mode (mirrored layout), Turkish plus Arabic original in left to right mode (Arabic reads from the right in its column and box), and Arabic plus Turkish original in right to left mode (mirrored, Turkish reads from the left in its column and box). Startup with the mode already enabled and layout switching keep the correct arrangement in every case.

@muaz978

muaz978 commented Jul 8, 2026

Copy link
Copy Markdown
Author
image image image image

@muaz978

muaz978 commented Jul 8, 2026

Copy link
Copy Markdown
Author

One note for completeness: the last commit of this work was pushed shortly after the merge, so it did not make it into this PR. It is now open as #12276 and finishes the polishing of this feature and fix: it re-applies the right to left pass after every layout build, so starting the app with right to left mode already enabled (and switching layouts) comes up in the correct arrangement without toggling the mode by hand. The four screenshots above were taken with that commit included, so #12276 is the version they show.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RTL mode orientation when translating

2 participants