diff --git a/livesplit-core b/livesplit-core index d6411401..c4a2068b 160000 --- a/livesplit-core +++ b/livesplit-core @@ -1 +1 @@ -Subproject commit d64114013d140b1b6fb581d7d640136af162a43a +Subproject commit c4a2068b71586d92d3864de00249226c88edf774 diff --git a/src/css/LayoutEditor.module.css b/src/css/LayoutEditor.module.css index 388c49a4..2f7e7c01 100644 --- a/src/css/LayoutEditor.module.css +++ b/src/css/LayoutEditor.module.css @@ -56,6 +56,11 @@ cursor: pointer; } +.placeholder { + font-style: italic; + opacity: 0.5; +} + .layoutContainer { margin-left: var(--ui-large-margin); diff --git a/src/localization/chinese-simplified.ts b/src/localization/chinese-simplified.ts index a5f91fff..0052a86e 100644 --- a/src/localization/chinese-simplified.ts +++ b/src/localization/chinese-simplified.ts @@ -247,6 +247,10 @@ export function resolveChineseSimplified(text: Label): string { case Label.ComponentBlankSpaceDescription: return "仅显示背景的空组件,用作间距。"; case Label.ComponentSeparator: return "分隔线"; case Label.ComponentSeparatorDescription: return "在组件之间渲染分隔线。"; + case Label.Row: return "行"; + case Label.RowDescription: return "一行水平排列的组件,改变内部组件的布局方向。"; + case Label.Column: return "列"; + case Label.ColumnDescription: return "一列垂直排列的组件,改变内部组件的布局方向。"; case Label.AccuracySeconds: return "秒"; case Label.AccuracyTenths: return "十分之一秒"; case Label.AccuracyHundredths: return "百分之一秒"; diff --git a/src/localization/dutch.ts b/src/localization/dutch.ts index e931ccae..64392682 100644 --- a/src/localization/dutch.ts +++ b/src/localization/dutch.ts @@ -247,6 +247,10 @@ export function resolveDutch(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Leeg component voor padding tussen onderdelen."; case Label.ComponentSeparator: return "Scheiding"; case Label.ComponentSeparatorDescription: return "Tekent een scheidingslijn tussen componenten."; + case Label.Row: return "Rij"; + case Label.RowDescription: return "Een rij componenten die horizontaal zijn ingedeeld, waardoor de lay-outrichting voor de componenten binnenin verandert."; + case Label.Column: return "Kolom"; + case Label.ColumnDescription: return "Een kolom componenten die verticaal zijn ingedeeld, waardoor de lay-outrichting voor de componenten binnenin verandert."; case Label.AccuracySeconds: return "Seconden"; case Label.AccuracyTenths: return "Tienden"; case Label.AccuracyHundredths: return "Honderdsten"; diff --git a/src/localization/english.ts b/src/localization/english.ts index 6dcd0be4..3dabb293 100644 --- a/src/localization/english.ts +++ b/src/localization/english.ts @@ -247,6 +247,10 @@ export function resolveEnglish(text: Label): string { case Label.ComponentBlankSpaceDescription: return "An empty component that doesn't show anything other than a background. It mostly serves as padding between other components."; case Label.ComponentSeparator: return "Separator"; case Label.ComponentSeparatorDescription: return "A simple component that just renders a separator between components."; + case Label.Row: return "Row"; + case Label.RowDescription: return "A row of components laid out horizontally, changing the layout direction for the components inside."; + case Label.Column: return "Column"; + case Label.ColumnDescription: return "A column of components laid out vertically, changing the layout direction for the components inside."; case Label.AccuracySeconds: return "Seconds"; case Label.AccuracyTenths: return "Tenths"; case Label.AccuracyHundredths: return "Hundredths"; diff --git a/src/localization/french.ts b/src/localization/french.ts index 3fd1595b..105b4574 100644 --- a/src/localization/french.ts +++ b/src/localization/french.ts @@ -247,6 +247,10 @@ export function resolveFrench(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Composant vide servant d’espacement."; case Label.ComponentSeparator: return "Séparateur"; case Label.ComponentSeparatorDescription: return "Affiche un séparateur entre les composants."; + case Label.Row: return "Ligne"; + case Label.RowDescription: return "Une ligne de composants disposés horizontalement, changeant la direction du layout pour les composants à l'intérieur."; + case Label.Column: return "Colonne"; + case Label.ColumnDescription: return "Une colonne de composants disposés verticalement, changeant la direction du layout pour les composants à l'intérieur."; case Label.AccuracySeconds: return "Secondes"; case Label.AccuracyTenths: return "Dixièmes"; case Label.AccuracyHundredths: return "Centièmes"; diff --git a/src/localization/german.ts b/src/localization/german.ts index 069bc53d..668099bf 100644 --- a/src/localization/german.ts +++ b/src/localization/german.ts @@ -247,6 +247,10 @@ export function resolveGerman(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Leere Komponente als Abstand zwischen anderen."; case Label.ComponentSeparator: return "Trenner"; case Label.ComponentSeparatorDescription: return "Zeichnet einen Trenner zwischen Komponenten."; + case Label.Row: return "Zeile"; + case Label.RowDescription: return "Eine Zeile von Komponenten, die horizontal angeordnet sind und die Layoutrichtung für die enthaltenen Komponenten ändern."; + case Label.Column: return "Spalte"; + case Label.ColumnDescription: return "Eine Spalte von Komponenten, die vertikal angeordnet sind und die Layoutrichtung für die enthaltenen Komponenten ändern."; case Label.AccuracySeconds: return "Sekunden"; case Label.AccuracyTenths: return "Zehntel"; case Label.AccuracyHundredths: return "Hundertstel"; diff --git a/src/localization/index.ts b/src/localization/index.ts index 1e804ea7..4ad9ddd6 100644 --- a/src/localization/index.ts +++ b/src/localization/index.ts @@ -260,6 +260,10 @@ export enum Label { ComponentBlankSpaceDescription, ComponentSeparator, ComponentSeparatorDescription, + Row, + RowDescription, + Column, + ColumnDescription, AccuracySeconds, AccuracyTenths, AccuracyHundredths, diff --git a/src/localization/italian.ts b/src/localization/italian.ts index 099e1aee..45b51aeb 100644 --- a/src/localization/italian.ts +++ b/src/localization/italian.ts @@ -247,6 +247,10 @@ export function resolveItalian(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Componente vuoto usato come spaziatura."; case Label.ComponentSeparator: return "Separatore"; case Label.ComponentSeparatorDescription: return "Rende un separatore tra componenti."; + case Label.Row: return "Riga"; + case Label.RowDescription: return "Una riga di componenti disposti orizzontalmente, che cambia la direzione del layout per i componenti al suo interno."; + case Label.Column: return "Colonna"; + case Label.ColumnDescription: return "Una colonna di componenti disposti verticalmente, che cambia la direzione del layout per i componenti al suo interno."; case Label.AccuracySeconds: return "Secondi"; case Label.AccuracyTenths: return "Decimi"; case Label.AccuracyHundredths: return "Centesimi"; diff --git a/src/localization/japanese.ts b/src/localization/japanese.ts index c2b68b98..8b7b2493 100644 --- a/src/localization/japanese.ts +++ b/src/localization/japanese.ts @@ -247,6 +247,10 @@ export function resolveJapanese(text: Label): string { case Label.ComponentBlankSpaceDescription: return "背景のみの空コンポーネントです。コンポーネント間の余白として使います。"; case Label.ComponentSeparator: return "区切り"; case Label.ComponentSeparatorDescription: return "コンポーネント間の区切り線を表示します。"; + case Label.Row: return "行"; + case Label.RowDescription: return "水平に配置されたコンポーネントの行で、内部のコンポーネントのレイアウト方向を変更します。"; + case Label.Column: return "列"; + case Label.ColumnDescription: return "垂直に配置されたコンポーネントの列で、内部のコンポーネントのレイアウト方向を変更します。"; case Label.AccuracySeconds: return "秒"; case Label.AccuracyTenths: return "1/10 秒"; case Label.AccuracyHundredths: return "1/100 秒"; diff --git a/src/localization/korean.ts b/src/localization/korean.ts index bf333fed..e7f46a2b 100644 --- a/src/localization/korean.ts +++ b/src/localization/korean.ts @@ -247,6 +247,10 @@ export function resolveKorean(text: Label): string { case Label.ComponentBlankSpaceDescription: return "배경만 있는 빈 컴포넌트입니다."; case Label.ComponentSeparator: return "구분선"; case Label.ComponentSeparatorDescription: return "컴포넌트 사이의 구분선을 표시합니다."; + case Label.Row: return "행"; + case Label.RowDescription: return "수평으로 배치된 구성 요소의 행으로, 내부 구성 요소의 레이아웃 방향을 변경합니다."; + case Label.Column: return "열"; + case Label.ColumnDescription: return "수직으로 배치된 구성 요소의 열로, 내부 구성 요소의 레이아웃 방향을 변경합니다."; case Label.AccuracySeconds: return "초"; case Label.AccuracyTenths: return "0.1초"; case Label.AccuracyHundredths: return "0.01초"; diff --git a/src/localization/polish.ts b/src/localization/polish.ts index b2e08c4a..39b810a0 100644 --- a/src/localization/polish.ts +++ b/src/localization/polish.ts @@ -247,6 +247,10 @@ export function resolvePolish(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Pusty komponent, który nie pokazuje nic poza tłem. Służy głównie jako odstęp między innymi komponentami."; case Label.ComponentSeparator: return "Separator"; case Label.ComponentSeparatorDescription: return "Prosty komponent, który renderuje separator między komponentami."; + case Label.Row: return "Wiersz"; + case Label.RowDescription: return "Wiersz komponentów ułożonych poziomo, zmieniający kierunek układu dla komponentów wewnątrz."; + case Label.Column: return "Kolumna"; + case Label.ColumnDescription: return "Kolumna komponentów ułożonych pionowo, zmieniająca kierunek układu dla komponentów wewnątrz."; case Label.AccuracySeconds: return "Sekundy"; case Label.AccuracyTenths: return "Dziesiąte"; case Label.AccuracyHundredths: return "Setne"; diff --git a/src/localization/portuguese-brazil.ts b/src/localization/portuguese-brazil.ts index 78df60b7..ecd6dc92 100644 --- a/src/localization/portuguese-brazil.ts +++ b/src/localization/portuguese-brazil.ts @@ -247,6 +247,10 @@ export function resolveBrazilianPortuguese(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Componente vazio com apenas o fundo."; case Label.ComponentSeparator: return "Separador"; case Label.ComponentSeparatorDescription: return "Mostra uma linha separadora entre componentes."; + case Label.Row: return "Linha"; + case Label.RowDescription: return "Uma linha de componentes dispostos horizontalmente, alterando a direção do layout para os componentes internos."; + case Label.Column: return "Coluna"; + case Label.ColumnDescription: return "Uma coluna de componentes dispostos verticalmente, alterando a direção do layout para os componentes internos."; case Label.AccuracySeconds: return "Segundos"; case Label.AccuracyTenths: return "Décimos"; case Label.AccuracyHundredths: return "Centésimos"; diff --git a/src/localization/portuguese.ts b/src/localization/portuguese.ts index b5d5ef52..72aee779 100644 --- a/src/localization/portuguese.ts +++ b/src/localization/portuguese.ts @@ -247,6 +247,10 @@ export function resolvePortuguese(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Componente vazio com apenas o fundo."; case Label.ComponentSeparator: return "Separador"; case Label.ComponentSeparatorDescription: return "Mostra uma linha separadora entre componentes."; + case Label.Row: return "Linha"; + case Label.RowDescription: return "Uma linha de componentes dispostos horizontalmente, alterando a direção do layout para os componentes no interior."; + case Label.Column: return "Coluna"; + case Label.ColumnDescription: return "Uma coluna de componentes dispostos verticalmente, alterando a direção do layout para os componentes no interior."; case Label.AccuracySeconds: return "Segundos"; case Label.AccuracyTenths: return "Décimos"; case Label.AccuracyHundredths: return "Centésimos"; diff --git a/src/localization/russian.ts b/src/localization/russian.ts index a9db57bb..bd553ba8 100644 --- a/src/localization/russian.ts +++ b/src/localization/russian.ts @@ -247,6 +247,10 @@ export function resolveRussian(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Пустой компонент только с фоном."; case Label.ComponentSeparator: return "Разделитель"; case Label.ComponentSeparatorDescription: return "Показывает разделительную линию между компонентами."; + case Label.Row: return "Строка"; + case Label.RowDescription: return "Строка компонентов, расположенных горизонтально, изменяющая направление разметки для компонентов внутри."; + case Label.Column: return "Столбец"; + case Label.ColumnDescription: return "Столбец компонентов, расположенных вертикально, изменяющий направление разметки для компонентов внутри."; case Label.AccuracySeconds: return "Секунды"; case Label.AccuracyTenths: return "Десятые"; case Label.AccuracyHundredths: return "Сотые"; diff --git a/src/localization/spanish.ts b/src/localization/spanish.ts index 33a588cd..9c1d983b 100644 --- a/src/localization/spanish.ts +++ b/src/localization/spanish.ts @@ -247,6 +247,10 @@ export function resolveSpanish(text: Label): string { case Label.ComponentBlankSpaceDescription: return "Componente vacío con solo el fondo."; case Label.ComponentSeparator: return "Separador"; case Label.ComponentSeparatorDescription: return "Muestra una línea separadora entre componentes."; + case Label.Row: return "Fila"; + case Label.RowDescription: return "Una fila de componentes dispuestos horizontalmente, cambiando la dirección del diseño para los componentes interiores."; + case Label.Column: return "Columna"; + case Label.ColumnDescription: return "Una columna de componentes dispuestos verticalmente, cambiando la dirección del diseño para los componentes interiores."; case Label.AccuracySeconds: return "Segundos"; case Label.AccuracyTenths: return "Décimas"; case Label.AccuracyHundredths: return "Centésimas"; diff --git a/src/ui/components/Settings/index.tsx b/src/ui/components/Settings/index.tsx index fb20e659..97b77d90 100644 --- a/src/ui/components/Settings/index.tsx +++ b/src/ui/components/Settings/index.tsx @@ -73,6 +73,8 @@ export type ExtendedSettingsDescriptionValueJson = export interface SettingValueFactory { fromBool(v: boolean): T; fromUint(value: number): T; + fromOptionalUint(value: number): T; + fromOptionalEmptyUint(): T; fromInt(value: number): T; fromString(value: string): T; fromOptionalString(value: string): T; @@ -146,6 +148,12 @@ export class JsonSettingValueFactory implements SettingValueFactory extends React.Component> { /> ); + } else if ("OptionalUInt" in value) { + const children = [ + { + if (checked) { + this.props.setValue( + valueIndex, + factory.fromOptionalUint(1), + ); + } else { + this.props.setValue( + valueIndex, + factory.fromOptionalEmptyUint(), + ); + } + }} + />, + ]; + + if (value.OptionalUInt !== null) { + children.push( + { + this.props.setValue( + valueIndex, + factory.fromOptionalUint( + e.target.valueAsNumber, + ), + ); + }} + />, + ); + } + + component = ( +
+ {children} +
+ ); } else if ("Int" in value) { component = (
diff --git a/src/ui/views/LayoutEditor.tsx b/src/ui/views/LayoutEditor.tsx index bb5a044e..2560d0ce 100644 --- a/src/ui/views/LayoutEditor.tsx +++ b/src/ui/views/LayoutEditor.tsx @@ -134,6 +134,8 @@ export function View({ if (i === state.selected_component) { className += " " + tableClasses.selected; } + const indent = state.indent_levels[i]; + const isPlaceholder = state.is_placeholder[i]; return ( - {c} + + + {c} + + ); }); @@ -207,6 +220,7 @@ export function View({ allVariables={allVariables} addVariable={(v) => addVariable(v)} addComponent={(v) => addComponent(v)} + layoutDirection={state.layout_direction} lang={lang} /> @@ -324,11 +339,13 @@ function AddComponentButton({ allVariables, addVariable, addComponent, + layoutDirection, lang, }: { allVariables: Set; addVariable: (name: string) => void; addComponent: (componentClass: ComponentClass) => void; + layoutDirection: LiveSplit.LayoutDirection; lang?: LiveSplit.Language; }) { const [position, setPosition] = useState(null); @@ -583,6 +600,26 @@ function AddComponentButton({ )} + addComponent(LiveSplit.GroupComponent)} + lang={lang} + > + {resolve( + layoutDirection === "Vertical" + ? Label.Row + : Label.Column, + lang, + )} + + {resolve( + layoutDirection === "Vertical" + ? Label.RowDescription + : Label.ColumnDescription, + lang, + )} + +