Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions scripts/initializr/common/src/main/css/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,26 @@ InitializrFieldDark, InitializrFieldHintDark {
margin: 0 0 1.4mm 0;
}

InitializrCssEditor {
color: #0f172a;
font-family: "native:MainRegular";
font-size: 2.6mm;
background-color: #ffffff;
border: 1px solid #9fb6d5;
padding: 1.1mm;
margin: 0 0 1.4mm 0;
}

InitializrCssEditorDark {
color: #f8fafc;
font-family: "native:MainRegular";
font-size: 2.6mm;
background-color: #0b1220;
border: 1px solid #64748b;
padding: 1.1mm;
margin: 0 0 1.4mm 0;
}

InitializrChoicesGrid {
margin: 0 0 1.2mm 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.codename1.ui.Label;
import com.codename1.ui.RadioButton;
import com.codename1.ui.TextField;
import com.codename1.ui.TextArea;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.GridLayout;
Expand All @@ -46,14 +47,16 @@ public void runApp() {
final Template[] selectedTemplate = new Template[]{Template.BAREBONES};
final IDE[] selectedIde = new IDE[]{IDE.INTELLIJ};
final ProjectOptions.ThemeMode[] selectedThemeMode = new ProjectOptions.ThemeMode[]{ProjectOptions.ThemeMode.LIGHT};
final ProjectOptions.ThemeEditorMode[] selectedThemeEditorMode = new ProjectOptions.ThemeEditorMode[]{ProjectOptions.ThemeEditorMode.SIMPLE};
final ProjectOptions.Accent[] selectedAccent = new ProjectOptions.Accent[]{ProjectOptions.Accent.DEFAULT};
final boolean[] roundedButtons = new boolean[]{true};
final String[] customThemeCss = new String[]{defaultAdvancedCss()};
final boolean[] includeLocalizationBundles = new boolean[]{true};
final ProjectOptions.PreviewLanguage[] previewLanguage = new ProjectOptions.PreviewLanguage[]{ProjectOptions.PreviewLanguage.ENGLISH};
final RadioButton[] templateButtons = new RadioButton[Template.values().length];
final SpanLabel summaryLabel = new SpanLabel();
final TemplatePreviewPanel previewPanel = new TemplatePreviewPanel(selectedTemplate[0]);
final Container[] themePanelRef = new Container[1];
final UITimer[] cssRefreshTimer = new UITimer[1];

appNameField.setUIID("InitializrField");
packageField.setUIID("InitializrField");
Expand All @@ -69,14 +72,11 @@ public void runApp() {
public void run() {
ProjectOptions options = new ProjectOptions(
selectedThemeMode[0], selectedAccent[0], roundedButtons[0],
includeLocalizationBundles[0], previewLanguage[0]
includeLocalizationBundles[0], previewLanguage[0],
selectedThemeEditorMode[0], customThemeCss[0]
);
previewPanel.setTemplate(selectedTemplate[0]);
previewPanel.setOptions(options);
boolean canCustomizeTheme = supportsLivePreview(selectedTemplate[0]);
if (themePanelRef[0] != null) {
setEnabledRecursive(themePanelRef[0], canCustomizeTheme);
}
summaryLabel.setText(createSummary(
appNameField.getText(),
packageField.getText(),
Expand All @@ -88,6 +88,15 @@ public void run() {
form.revalidate();
}
};
final Runnable scheduleCssRefresh = () -> {
if (cssRefreshTimer[0] != null) {
cssRefreshTimer[0].cancel();
}
cssRefreshTimer[0] = UITimer.timer(500, false, form, () -> {
cssRefreshTimer[0] = null;
refresh.run();
});
};

final Container essentialsCard = createEssentialsCard(
appNameField,
Expand All @@ -97,9 +106,9 @@ public void run() {
createTemplateSelector(selectedTemplate, templateButtons, refresh)
);
final Container idePanel = createIdeSelectorPanel(selectedIde, refresh);
final Container themePanel = createThemeOptionsPanel(selectedThemeMode, selectedAccent, roundedButtons, refresh);
final Container themePanel = createThemeOptionsPanel(selectedThemeMode, selectedThemeEditorMode,
selectedAccent, roundedButtons, customThemeCss, refresh, scheduleCssRefresh);
final Container localizationPanel = createLocalizationPanel(includeLocalizationBundles, previewLanguage, refresh, previewPanel);
themePanelRef[0] = themePanel;
final Container settingsPanel = BoxLayout.encloseY(summaryLabel);

Accordion advancedAccordion = new Accordion();
Expand Down Expand Up @@ -133,7 +142,8 @@ public void run() {
String packageName = packageField.getText() == null ? "" : packageField.getText().trim();
ProjectOptions options = new ProjectOptions(
selectedThemeMode[0], selectedAccent[0], roundedButtons[0],
includeLocalizationBundles[0], previewLanguage[0]
includeLocalizationBundles[0], previewLanguage[0],
selectedThemeEditorMode[0], customThemeCss[0]
);
GeneratorModel.create(selectedIde[0], selectedTemplate[0], appName, packageName, options).generate();
});
Expand Down Expand Up @@ -256,9 +266,32 @@ private Container createIdeSelectorPanel(IDE[] selectedIde, Runnable onSelection
}

private Container createThemeOptionsPanel(ProjectOptions.ThemeMode[] selectedThemeMode,
ProjectOptions.ThemeEditorMode[] selectedThemeEditorMode,
ProjectOptions.Accent[] selectedAccent,
boolean[] roundedButtons,
Runnable onSelectionChanged) {
String[] customThemeCss,
Runnable onSelectionChanged,
Runnable onCssChanged) {
Container editorModeRow = new Container(new GridLayout(1, 2));
editorModeRow.setUIID("InitializrChoicesGrid");
ButtonGroup editorModeGroup = new ButtonGroup();
for (ProjectOptions.ThemeEditorMode editorMode : ProjectOptions.ThemeEditorMode.values()) {
RadioButton rb = new RadioButton(formatEnumLabel(editorMode.name()));
rb.setToggle(true);
rb.setUIID("InitializrChoice");
editorModeGroup.add(rb);
editorModeRow.add(rb);
if (editorMode == selectedThemeEditorMode[0]) {
rb.setSelected(true);
}
rb.addActionListener(e -> {
if (rb.isSelected()) {
selectedThemeEditorMode[0] = editorMode;
onSelectionChanged.run();
}
});
}

Container modeRow = new Container(new GridLayout(1, 2));
modeRow.setUIID("InitializrChoicesGrid");
ButtonGroup modeGroup = new ButtonGroup();
Expand Down Expand Up @@ -307,11 +340,69 @@ private Container createThemeOptionsPanel(ProjectOptions.ThemeMode[] selectedThe
onSelectionChanged.run();
});

return BoxLayout.encloseY(
TextArea cssEditor = new TextArea(customThemeCss[0], 8, 30);
cssEditor.setUIID("InitializrCssEditor");
cssEditor.setEditable(true);
cssEditor.setGrowByContent(false);
cssEditor.addDataChangedListener((type, index) -> {
customThemeCss[0] = cssEditor.getText();
onCssChanged.run();
});

Container simpleControls = BoxLayout.encloseY(
labeledField("Mode", modeRow),
labeledField("Accent", accentRow),
rounded
);
Container advancedControls = labeledField("Theme CSS", cssEditor);

Runnable updateThemeEditorVisibility = () -> {
boolean advanced = selectedThemeEditorMode[0] == ProjectOptions.ThemeEditorMode.ADVANCED;
simpleControls.setHidden(advanced);
simpleControls.setVisible(!advanced);
advancedControls.setHidden(!advanced);
advancedControls.setVisible(advanced);
};
updateThemeEditorVisibility.run();
for (int i = 0; i < editorModeRow.getComponentCount(); i++) {
Component c = editorModeRow.getComponentAt(i);
if (c instanceof RadioButton) {
((RadioButton)c).addActionListener(e -> updateThemeEditorVisibility.run());
}
}

return BoxLayout.encloseY(
labeledField("Editor", editorModeRow),
simpleControls,
advancedControls
);
}

private String defaultAdvancedCss() {
return "@constants {\n"
+ " includeNativeBool: true;\n"
+ " defaultSourceDPIInt: \"0\";\n"
+ "}\n\n"
+ ":root {\n"
+ " --primary: #1976d2;\n"
+ " --surface: #f3f6fb;\n"
+ " --text: #1f2937;\n"
+ "}\n\n"
+ "Container {\n"
+ " background-color: var(--surface);\n"
+ "}\n\n"
+ "Toolbar {\n"
+ " background-color: #eaf2ff;\n"
+ " color: var(--text);\n"
+ "}\n\n"
+ "Title {\n"
+ " color: var(--text);\n"
+ "}\n\n"
+ "Button {\n"
+ " background-color: var(--primary);\n"
+ " color: #ffffff;\n"
+ " padding: 2px 4px;\n"
+ "}\n";
}

private Container createTemplateSelector(Template[] selectedTemplate, RadioButton[] templateButtons, Runnable onSelectionChanged) {
Expand Down Expand Up @@ -388,10 +479,6 @@ private String formatEnumLabel(String text) {
return StringUtil.replaceAll(text, "_", " ");
}

private boolean supportsLivePreview(Template template) {
return template == Template.BAREBONES || template == Template.KOTLIN;
}

private void initWebsiteThemeSync(Form form) {
WebsiteThemeNative websiteThemeNative = NativeLookup.create(WebsiteThemeNative.class);
if (websiteThemeNative == null || !websiteThemeNative.isSupported()) {
Expand Down Expand Up @@ -443,6 +530,7 @@ private String themedUiid(String uiid, boolean dark) {
case "InitializrFieldLabel":
case "InitializrField":
case "InitializrFieldHint":
case "InitializrCssEditor":
case "InitializrChoice":
case "InitializrSummary":
case "InitializrTip":
Expand Down Expand Up @@ -472,6 +560,7 @@ private String themedUiid(String uiid, boolean dark) {
case "InitializrFieldLabel":
case "InitializrField":
case "InitializrFieldHint":
case "InitializrCssEditor":
case "InitializrChoice":
case "InitializrSummary":
case "InitializrTip":
Expand All @@ -487,16 +576,6 @@ private String themedUiid(String uiid, boolean dark) {
}
}

private void setEnabledRecursive(Component component, boolean enabled) {
component.setEnabled(enabled);
if (component instanceof Container) {
Container cnt = (Container) component;
for (int i = 0; i < cnt.getComponentCount(); i++) {
setEnabledRecursive(cnt.getComponentAt(i), enabled);
}
}
}

private String createSummary(String appName, String packageName, Template template, IDE ide, ProjectOptions options) {
String safeApp = appName == null ? "" : appName.trim();
String safePackage = packageName == null ? "" : packageName.trim();
Expand All @@ -505,6 +584,7 @@ private String createSummary(String appName, String packageName, Template templa
+ "Template: " + template.name() + "\n"
+ "IDE: " + ide.name() + "\n"
+ "Theme: " + options.themeMode.name() + "\n"
+ "Theme Editor: " + options.themeEditorMode.name() + "\n"
+ "Accent: " + options.accent.name() + "\n"
+ "Rounded Buttons: " + (options.roundedButtons ? "Yes" : "No") + "\n"
+ "Localization Bundles: " + (options.includeLocalizationBundles ? "Yes" : "No") + "\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public enum ThemeMode {
DARK
}

public enum ThemeEditorMode {
SIMPLE,
ADVANCED
}

public enum Accent {
DEFAULT,
TEAL,
Expand All @@ -48,14 +53,25 @@ public enum Accent {
public final boolean roundedButtons;
public final boolean includeLocalizationBundles;
public final PreviewLanguage previewLanguage;
public final ThemeEditorMode themeEditorMode;
public final String customCss;

public ProjectOptions(ThemeMode themeMode, Accent accent, boolean roundedButtons,
boolean includeLocalizationBundles, PreviewLanguage previewLanguage) {
this(themeMode, accent, roundedButtons, includeLocalizationBundles, previewLanguage,
ThemeEditorMode.SIMPLE, null);
}

public ProjectOptions(ThemeMode themeMode, Accent accent, boolean roundedButtons,
boolean includeLocalizationBundles, PreviewLanguage previewLanguage,
ThemeEditorMode themeEditorMode, String customCss) {
this.themeMode = themeMode;
this.accent = accent;
this.roundedButtons = roundedButtons;
this.includeLocalizationBundles = includeLocalizationBundles;
this.previewLanguage = previewLanguage == null ? PreviewLanguage.ENGLISH : previewLanguage;
this.themeEditorMode = themeEditorMode == null ? ThemeEditorMode.SIMPLE : themeEditorMode;
this.customCss = customCss;
}

public static ProjectOptions defaults() {
Expand Down
Loading
Loading