implements PLN-0070

This commit is contained in:
bQUARKz 2026-05-06 13:49:58 +01:00
parent 41bcd8c52a
commit ed2070c5a4
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
3 changed files with 95 additions and 0 deletions

View File

@ -14,6 +14,7 @@ dependencies {
implementation(libs.javafx.controls)
implementation(libs.javafx.fxml)
implementation(libs.richtextfx)
testImplementation(project(":prometeu-compiler:frontends:prometeu-frontend-pbs"))
testImplementation(project(":prometeu-packer:prometeu-packer-v1"))
}

View File

@ -0,0 +1,69 @@
package p.studio.utilities;
import p.studio.compiler.models.FrontendSemanticPresentationSpec;
import p.studio.compiler.models.FrontendTokenStyleSpec;
import p.studio.compiler.models.FrontendVisualThemeSpec;
import java.util.Objects;
public final class FrontendVisualThemeCssRenderer {
public String renderDefaultTheme(
final String languageId,
final FrontendSemanticPresentationSpec presentation) {
Objects.requireNonNull(presentation, "presentation");
return renderTheme(languageId, presentation.defaultTheme());
}
public String renderTheme(
final String languageId,
final FrontendVisualThemeSpec theme) {
final String normalizedLanguageId = requireText(languageId, "languageId");
final FrontendVisualThemeSpec resolvedTheme = Objects.requireNonNull(theme, "theme");
final String editorSelector = ".editor-workspace-code-area-type-" + normalizedLanguageId;
final String statusChipSelector = ".editor-workspace-status-chip-type-" + normalizedLanguageId;
final StringBuilder css = new StringBuilder();
css.append(editorSelector).append(" {\n")
.append(" -fx-highlight-fill: ").append(resolvedTheme.editorPalette().activeHighlightBackground()).append(";\n")
.append("}\n\n")
.append(editorSelector).append(" .text {\n")
.append(" -fx-fill: ").append(resolvedTheme.editorPalette().baseForeground()).append(";\n")
.append("}\n\n")
.append(editorSelector).append(" .lineno {\n")
.append(" -fx-text-fill: ").append(resolvedTheme.editorPalette().lineNumberForeground()).append(";\n")
.append("}\n\n");
for (final FrontendTokenStyleSpec tokenStyle : resolvedTheme.tokenStyles()) {
css.append(editorSelector).append(" .text.editor-semantic-").append(tokenStyle.semanticKey()).append(" {\n")
.append(" -fx-fill: ").append(tokenStyle.foreground()).append(";\n");
if (tokenStyle.italic()) {
css.append(" -fx-font-style: italic;\n");
}
if (tokenStyle.bold()) {
css.append(" -fx-font-weight: bold;\n");
}
if (tokenStyle.underline()) {
css.append(" -fx-underline: true;\n");
}
css.append("}\n\n");
}
css.append(statusChipSelector).append(" {\n")
.append(" -fx-background-color: ").append(resolvedTheme.editorPalette().statusChipBackground()).append(";\n")
.append(" -fx-border-color: ").append(resolvedTheme.editorPalette().statusChipBorder()).append(";\n")
.append(" -fx-text-fill: ").append(resolvedTheme.editorPalette().statusChipForeground()).append(";\n")
.append("}\n");
return css.toString();
}
private static String requireText(
final String value,
final String field) {
final String candidate = Objects.requireNonNull(value, field).trim();
if (candidate.isEmpty()) {
throw new IllegalArgumentException(field + " must not be blank");
}
return candidate;
}
}

View File

@ -0,0 +1,25 @@
package p.studio.utilities;
import org.junit.jupiter.api.Test;
import p.studio.compiler.PBSDefinitions;
import static org.junit.jupiter.api.Assertions.assertTrue;
class FrontendVisualThemeCssRendererTest {
@Test
void rendersLegacyCompatibleCssFromStructuredFrontendTheme() {
final FrontendVisualThemeCssRenderer renderer = new FrontendVisualThemeCssRenderer();
final String css = renderer.renderDefaultTheme(
PBSDefinitions.PBS.getLanguageId(),
PBSDefinitions.PBS.getSemanticPresentation());
assertTrue(css.contains(".editor-workspace-code-area-type-pbs"));
assertTrue(css.contains(".text.editor-semantic-pbs-keyword"));
assertTrue(css.contains("-fx-fill: #569cd6;"));
assertTrue(css.contains("-fx-font-style: italic;"));
assertTrue(css.contains(".editor-workspace-status-chip-type-pbs"));
assertTrue(css.contains("-fx-border-color: #a47dff;"));
}
}