diff --git a/.github/workflows/developer-guide-docs.yml b/.github/workflows/developer-guide-docs.yml index 8d191704e42..1a0e199ca61 100644 --- a/.github/workflows/developer-guide-docs.yml +++ b/.github/workflows/developer-guide-docs.yml @@ -71,6 +71,51 @@ jobs: cp maven/CodeNameOneBuildClient.jar "$HOME/.codenameone/CodeNameOneBuildClient.jar" xvfb-run -a mvn -B -ntp -Dgenerate-gui-sources-done=true -Dcodename1.platform=javase -f docs/demos/pom.xml process-classes + - name: Install demo common module for screenshot generation + if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true' + run: | + set -euo pipefail + mvn -B -ntp \ + -Dgenerate-gui-sources-done=true \ + -Dcodename1.platform=javase \ + -f docs/demos/pom.xml \ + -pl common \ + -am \ + install \ + -DskipTests + + - name: Verify pre-Advanced Theming screenshots are current + if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true' + run: | + set -euo pipefail + GENERATED_DIR="$RUNNER_TEMP/pre-advanced-theming-screenshots" + rm -rf "$GENERATED_DIR" + mkdir -p "$GENERATED_DIR" + xvfb-run -a mvn -B -ntp \ + -Dgenerate-gui-sources-done=true \ + -Dcodename1.platform=javase \ + -f docs/demos/javase/pom.xml \ + -P guide-screenshot-generator \ + -Dguide.screenshot.output="$GENERATED_DIR" \ + verify + COUNT="$(find "$GENERATED_DIR" -maxdepth 1 -type f -name '*.png' | wc -l | tr -d ' ')" + if [ "$COUNT" != "24" ]; then + echo "::error::Expected 24 generated pre-Advanced Theming screenshots, found $COUNT" + exit 1 + fi + for generated in "$GENERATED_DIR"/*.png; do + name="$(basename "$generated")" + committed="docs/developer-guide/img/$name" + if [ ! -f "$committed" ]; then + echo "::error::Generated screenshot has no committed counterpart: $name" + exit 1 + fi + if ! cmp -s "$generated" "$committed"; then + echo "::error::Committed screenshot is stale: $name" + exit 1 + fi + done + - name: Verify developer guide images are referenced if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true' run: | diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/PreAdvancedThemingScreenshots.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/PreAdvancedThemingScreenshots.java new file mode 100644 index 00000000000..b168677eabf --- /dev/null +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/screenshots/PreAdvancedThemingScreenshots.java @@ -0,0 +1,350 @@ +package com.codenameone.developerguide.screenshots; + +import com.codename1.components.SpanLabel; +import com.codenameone.developerguide.snippets.generated.BasicsJava034Snippet; +import com.codename1.ui.Button; +import com.codename1.ui.Component; +import com.codename1.ui.Container; +import com.codename1.ui.CN; +import com.codename1.ui.FontImage; +import com.codename1.ui.Font; +import com.codename1.ui.Form; +import com.codename1.ui.Graphics; +import com.codename1.ui.Image; +import com.codename1.ui.Label; +import com.codename1.ui.TextField; +import com.codename1.ui.layouts.BorderLayout; +import com.codename1.ui.layouts.BoxLayout; +import com.codename1.ui.layouts.FlowLayout; +import com.codename1.ui.layouts.GridBagConstraints; +import com.codename1.ui.layouts.GridBagLayout; +import com.codename1.ui.layouts.GridLayout; +import com.codename1.ui.layouts.LayeredLayout; +import com.codename1.ui.layouts.mig.MigLayout; +import com.codename1.ui.plaf.Border; +import com.codename1.ui.plaf.Style; +import com.codename1.ui.table.TableLayout; +import com.codename1.ui.util.ImageIO; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Generates the app screenshots used before the Advanced Theming chapter. + */ +public final class PreAdvancedThemingScreenshots { + private static final int PORTRAIT_WIDTH = 320; + private static final int PORTRAIT_HEIGHT = 480; + private static final int LANDSCAPE_WIDTH = 480; + private static final int LANDSCAPE_HEIGHT = 320; + private static final int BLUE = 0x0b57d0; + private static final int GREEN = 0x06a806; + private static final int WHITE = 0xffffff; + private static final Font TITLE_FONT = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_LARGE) + .derive(35, Font.STYLE_PLAIN); + private static final Font BLOCK_FONT = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_LARGE) + .derive(24, Font.STYLE_PLAIN); + + private PreAdvancedThemingScreenshots() { + } + + public interface ScreenshotSink { + OutputStream open(String fileName) throws IOException; + } + + public static void generate(ScreenshotSink sink) throws IOException { + write(sink, "flow-layout.png", flow("Flow Layout", Component.LEFT, Component.TOP), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "flow-layout-center.png", flow("Flow Layout", Component.CENTER, Component.TOP), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "flow-layout-right.png", flow("Flow Layout", Component.RIGHT, Component.TOP), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "flow-layout-center-middle.png", flow("Flow Layout", Component.CENTER, Component.CENTER), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "box-layout-y.png", boxY(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "box-layout-x.png", boxX(true), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "box-layout-x-no-grow.png", boxX(false), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "border-layout.png", border(false, false), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "border-layout-center.png", border(true, false), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "border-layout-RTL.png", border(false, true), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "grid-layout-2x2.png", grid(2, 2, "Grid 2x2 Layout"), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "grid-layout-2x4.png", grid(2, 4, "Grid 2x4 Layout"), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "grid-layout-autofit-portrait.png", gridAutofit("Grid Layout AutoFit"), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "grid-layout-autofit-landscape.png", gridAutofit("Grid Layout AutoFit"), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "table-layout-2x2.png", table2x2(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "table-layout-enclose.png", tableEnclose(), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "table-layout-constraints.png", tableConstraints(), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "layered-layout.png", layeredCloseButton(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "guibuilder-2-insets-1.png", insetsLowerRight(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "guibuilder-2-insets-2.png", insetsCenterLeft(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "guibuilder-2-insets-3.png", insetsReference(), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "gridbag-layout.png", gridBag(), LANDSCAPE_WIDTH, LANDSCAPE_HEIGHT); + write(sink, "group-layout.png", groupLayout(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + write(sink, "mig-layout.png", migLayout(), PORTRAIT_WIDTH, PORTRAIT_HEIGHT); + } + + private static Form flow(String title, int align, int valign) { + Form hi = new Form(title, new FlowLayout(align, valign)); + addDemoLabels(hi); + return hi; + } + + private static Form boxY() { + Form hi = new Form("Box Y Layout", BoxLayout.y()); + addDemoLabels(hi); + return hi; + } + + private static Form boxX(boolean grow) { + int axis = grow ? BoxLayout.X_AXIS : BoxLayout.X_AXIS_NO_GROW; + Form hi = new Form(grow ? "Box X Layout" : "Box X No Grow", new BoxLayout(axis)); + addDemoLabels(hi); + return hi; + } + + private static Form border(boolean centerBehavior, boolean rtl) { + Form hi = new Form("Border Layout", new BorderLayout()); + if (centerBehavior) { + ((BorderLayout) hi.getLayout()).setCenterBehavior(BorderLayout.CENTER_BEHAVIOR_CENTER); + } + hi.add(BorderLayout.CENTER, demoLabel("Center")) + .add(BorderLayout.SOUTH, demoLabel("South")) + .add(BorderLayout.NORTH, demoLabel("North")) + .add(BorderLayout.EAST, demoLabel(rtl ? "West" : "East")) + .add(BorderLayout.WEST, demoLabel(rtl ? "East" : "West")); + return hi; + } + + private static Form grid(int rows, int columns, String title) { + Form hi = new Form(title, new GridLayout(rows, columns)); + addDemoLabels(hi); + return hi; + } + + private static Form gridAutofit(String title) { + Form hi = new Form(title, GridLayout.autoFit()); + addDemoLabels(hi); + return hi; + } + + private static Form table2x2() { + Form hi = new Form("Table Layout 2x2", new TableLayout(2, 2)); + addDemoLabels(hi); + return hi; + } + + private static Form tableEnclose() { + Form hi = new Form("TableLayout Enclose 2", new BorderLayout()); + Container table = TableLayout.encloseIn(2, + demoLabel("First"), + demoLabel("Second"), + demoLabel("Third"), + demoLabel("Fourth"), + demoLabel("Fifth")); + hi.add(BorderLayout.CENTER, table); + return hi; + } + + private static Form tableConstraints() { + TableLayout layout = new TableLayout(4, 3); + layout.setGrowHorizontally(true); + Form hi = new Form("Table Layout", layout); + + TableLayout.Constraint title = layout.createConstraint(); + title.setHorizontalSpan(3); + title.setHorizontalAlign(Component.CENTER); + hi.add(title, demoLabel("Invoice")); + + hi.add(demoLabel("Item")); + hi.add(demoLabel("Qty")); + hi.add(demoLabel("Total")); + hi.add(demoLabel("Design")); + hi.add(demoLabel("2")); + hi.add(demoLabel("$120")); + + TableLayout.Constraint notes = layout.createConstraint(); + notes.setHorizontalSpan(2); + notes.setHeightPercentage(40); + hi.add(notes, demoSpanLabel("Notes span two columns")); + hi.add(demoButton("Pay")); + return hi; + } + + private static Form layeredCloseButton() { + Form hi = new Form("Layered Layout"); + Label settingsLabel = demoLabel("Settings"); + settingsLabel.setIcon(FontImage.createMaterial(FontImage.MATERIAL_SETTINGS, settingsLabel.getUnselectedStyle())); + Button close = new Button("X"); + close.setUIID("Container"); + close.getAllStyles().setFgColor(0xd32f2f); + close.getAllStyles().setAlignment(Component.CENTER); + hi.add(LayeredLayout.encloseIn(settingsLabel, FlowLayout.encloseRight(close))); + return hi; + } + + private static Form insetsLowerRight() { + Form f = new Form("Layered Insets", new BorderLayout()); + Container cnt = new Container(new LayeredLayout()); + cnt.add(demoButton("Submit")); + ((LayeredLayout) cnt.getLayout()).setInsets(cnt.getComponentAt(0), "auto 0 0 auto"); + f.add(BorderLayout.CENTER, cnt); + return f; + } + + private static Form insetsCenterLeft() { + Form f = new Form("Layered Insets", new BorderLayout()); + Container cnt = new Container(new LayeredLayout()); + cnt.add(demoButton("Submit")); + ((LayeredLayout) cnt.getLayout()).setInsets(cnt.getComponentAt(0), "auto auto auto 5mm"); + f.add(BorderLayout.CENTER, cnt); + return f; + } + + private static Form insetsReference() { + Form f = new Form("Layered References", new BorderLayout()); + Container cnt = new Container(new LayeredLayout()); + LayeredLayout ll = (LayeredLayout) cnt.getLayout(); + Button btn = demoButton("Submit"); + TextField tf = new TextField(); + tf.setHint("Name"); + cnt.add(tf).add(btn); + ll.setInsets(tf, "auto") + .setInsets(btn, "auto auto auto 0") + .setReferenceComponentLeft(btn, tf, 1f); + f.add(BorderLayout.CENTER, cnt); + return f; + } + + private static Form gridBag() { + Form hi = new Form("GridBagLayout", new BorderLayout()); + Container grid = new Container(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.weightx = 0.5; + c.gridx = 0; + c.gridy = 0; + grid.addComponent(c, demoButton("Button 1")); + c.gridx = 1; + grid.addComponent(c, demoButton("Button 2")); + c.gridx = 2; + grid.addComponent(c, demoButton("Button 3")); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 3; + grid.addComponent(c, demoButton("Long-Named Button 4")); + + c.ipady = 40; + c.weighty = 1.0; + c.gridx = 1; + c.gridy = 2; + c.gridwidth = 2; + grid.addComponent(c, demoButton("5")); + hi.add(BorderLayout.CENTER, grid); + return hi; + } + + private static Form groupLayout() { + return BasicsJava034Snippet.createForm(); + } + + private static Form migLayout() { + Form hi = new Form("MigLayout", new MigLayout("wrap 3", "[grow][grow][grow]", "")); + hi.add(demoLabel("First")); + hi.add("span 1 2,grow", demoLabel("Second")); + hi.add(demoLabel("Third")); + hi.add(demoLabel("Fourth")); + hi.add(demoLabel("Fifth")); + hi.add(demoLabel("Sixth")); + hi.add("span 2", demoLabel("Seventh")); + return hi; + } + + private static void addDemoLabels(Container container) { + container.add(demoLabel("First")) + .add(demoLabel("Second")) + .add(demoLabel("Third")) + .add(demoLabel("Fourth")) + .add(demoLabel("Fifth")); + } + + private static Label demoLabel(String text) { + Label label = new Label(text); + styleBlock(label); + return label; + } + + private static SpanLabel demoSpanLabel(String text) { + SpanLabel label = new SpanLabel(text); + styleBlock(label); + return label; + } + + private static Button demoButton(String text) { + Button button = new Button(text); + styleBlock(button); + return button; + } + + private static void styleBlock(Component component) { + Style style = component.getAllStyles(); + style.setBgTransparency(255); + style.setBgColor(GREEN); + style.setFgColor(WHITE); + style.setAlignment(Component.CENTER); + style.setFont(BLOCK_FONT); + style.setPaddingUnit(Style.UNIT_TYPE_DIPS); + style.setPadding(1, 1, 2, 2); + style.setMarginUnit(Style.UNIT_TYPE_PIXELS); + style.setMargin(1, 1, 1, 1); + style.setBorder(Border.createLineBorder(1, WHITE)); + } + + private static void prepare(Form form, int width, int height) { + CN.setWindowSize(width, height); + applyScreenshotStyle(form); + form.setScrollable(false); + form.show(); + form.setWidth(width); + form.setHeight(height); + form.getContentPane().setWidth(width); + form.getContentPane().setHeight(Math.max(0, height - form.getTitleArea().getHeight())); + form.revalidate(); + } + + private static void applyScreenshotStyle(Form form) { + Style titleArea = form.getTitleArea().getAllStyles(); + titleArea.setBgTransparency(255); + titleArea.setBgColor(BLUE); + titleArea.setPaddingUnit(Style.UNIT_TYPE_PIXELS); + titleArea.setPadding(0, 0, 0, 0); + + Style title = form.getTitleStyle(); + title.setFgColor(WHITE); + title.setBgTransparency(0); + title.setFont(TITLE_FONT); + title.setPaddingUnit(Style.UNIT_TYPE_PIXELS); + title.setPadding(4, 5, 0, 0); + + applyBlockStyleToContent(form.getContentPane()); + } + + private static void applyBlockStyleToContent(Container container) { + for (int i = 0; i < container.getComponentCount(); i++) { + Component component = container.getComponentAt(i); + if (component instanceof Label || component instanceof Button) { + styleBlock(component); + } + if (component instanceof Container) { + applyBlockStyleToContent((Container) component); + } + } + } + + private static void write(ScreenshotSink sink, String fileName, Form form, int width, int height) throws IOException { + prepare(form, width, height); + Image screenshot = Image.createImage(width, height, 0xffffff); + Graphics graphics = screenshot.getGraphics(); + form.paintComponent(graphics, true); + try (OutputStream out = sink.open(fileName)) { + ImageIO.getImageIO().save(screenshot, out, ImageIO.FORMAT_PNG, 1); + } + } + +} diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/BasicsJava021Snippet.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/BasicsJava021Snippet.java index 783f2424e24..67e9b755ba4 100644 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/BasicsJava021Snippet.java +++ b/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/BasicsJava021Snippet.java @@ -2,17 +2,20 @@ import com.codename1.components.*; import com.codename1.ui.*; +import com.codename1.ui.layouts.BorderLayout; import com.codename1.ui.table.TableLayout; class BasicsJava021Snippet { void snippet() { // tag::basics-java-021[] - Container table = TableLayout.encloseIn(3, - new Label("One"), - new Label("Two"), - new Label("Grows")); - Form hi = new Form("TableLayout.encloseIn()"); - hi.add(table); + Container table = TableLayout.encloseIn(2, + new Label("First"), + new Label("Second"), + new Label("Third"), + new Label("Fourth"), + new Label("Fifth")); + Form hi = new Form("TableLayout Enclose 2", new BorderLayout()); + hi.add(BorderLayout.CENTER, table); hi.show(); // end::basics-java-021[] } diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava002Snippet.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava002Snippet.java deleted file mode 100644 index ce192c35c65..00000000000 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava002Snippet.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.codenameone.developerguide.snippets.generated; - -import com.codename1.gpu.*; -import com.codename1.ui.*; -import com.codename1.ui.animations.*; -import com.codename1.ui.events.*; -import com.codename1.ui.geom.*; -import com.codename1.ui.layouts.*; -import com.codename1.ui.list.*; -import com.codename1.ui.plaf.*; -import com.codename1.ui.util.*; -import com.codename1.components.*; -import com.codename1.charts.models.*; -import com.codename1.charts.renderers.*; -import com.codename1.charts.views.*; -import com.codename1.capture.*; -import com.codename1.io.*; -import com.codename1.l10n.*; -import com.codename1.location.*; -import com.codename1.maps.*; -import com.codename1.media.*; -import com.codename1.messaging.*; -import com.codename1.payment.*; -import com.codename1.processing.*; -import com.codename1.properties.*; -import com.codename1.push.*; -import com.codename1.security.*; -import com.codename1.social.*; -import com.codename1.ui.spinner.*; -import java.io.*; -import java.util.*; - - -class ThemeBasicsJava002Snippet { - - Object context; - Object url; - Object value; - Object body; - Object event; - String apiKey = "test-key"; - String myHttpsURL = "https://example.com"; - java.util.List validKeysList = new java.util.ArrayList<>(); - Image myImage; - Graphics graphics; - Graphics g; - GraphicsDevice device; - Form form; - Form hi; - Container cnt; - Container myForm; - Component component; - Button button; - MultiButton myMultiButton; - Label label; - BrowserComponent browserComponent; - Resources theme; - void snippet() throws Exception { - // tag::theme-basics-java-002[] - try { - theme = Resources.openLayered("/theme"); - UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0])); - } catch(IOException e){ - e.printStackTrace(); - } - // end::theme-basics-java-002[] - } -} diff --git a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava005Snippet.java b/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava005Snippet.java deleted file mode 100644 index c9e56d0cd19..00000000000 --- a/docs/demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava005Snippet.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.codenameone.developerguide.snippets.generated; - -import com.codename1.gpu.*; -import com.codename1.ui.*; -import com.codename1.ui.animations.*; -import com.codename1.ui.events.*; -import com.codename1.ui.geom.*; -import com.codename1.ui.layouts.*; -import com.codename1.ui.list.*; -import com.codename1.ui.plaf.*; -import com.codename1.ui.util.*; -import com.codename1.components.*; -import com.codename1.charts.models.*; -import com.codename1.charts.renderers.*; -import com.codename1.charts.views.*; -import com.codename1.capture.*; -import com.codename1.io.*; -import com.codename1.l10n.*; -import com.codename1.location.*; -import com.codename1.maps.*; -import com.codename1.media.*; -import com.codename1.messaging.*; -import com.codename1.payment.*; -import com.codename1.processing.*; -import com.codename1.properties.*; -import com.codename1.push.*; -import com.codename1.security.*; -import com.codename1.social.*; -import com.codename1.ui.spinner.*; -import java.io.*; -import java.util.*; - - -class ThemeBasicsJava005Snippet { - - Object context; - Object url; - Object value; - Object body; - Object event; - String apiKey = "test-key"; - String myHttpsURL = "https://example.com"; - java.util.List validKeysList = new java.util.ArrayList<>(); - Image myImage; - Graphics graphics; - Graphics g; - GraphicsDevice device; - Form form; - Form hi; - Container cnt; - Container myForm; - Component component; - Button button; - MultiButton myMultiButton; - Label label; - BrowserComponent browserComponent; - Resources theme; - // tag::theme-basics-java-005[] - private Label createForFont(Font fnt, String s) { - Label l = new Label(s); - l.getUnselectedStyle().setFont(fnt); - return l; - } - - public void showForm() { - GridLayout gr = new GridLayout(5); - gr.setAutoFit(true); - Form hi = new Form("Fonts", gr); - - int fontSize = Display.getInstance().convertToPixels(3); - - // requires Handlee-Regular.ttf in the src folder root! - Font ttfFont = Font.createTrueTypeFont("Handlee", "Handlee-Regular.ttf"). - derive(fontSize, Font.STYLE_PLAIN); - - Font smallPlainSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL); - Font mediumPlainSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); - Font largePlainSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_LARGE); - Font smallBoldSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL); - Font mediumBoldSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM); - Font largeBoldSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE); - Font smallItalicSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_SMALL); - Font mediumItalicSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_MEDIUM); - Font largeItalicSystemFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_LARGE); - - Font smallPlainMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL); - Font mediumPlainMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); - Font largePlainMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_LARGE); - Font smallBoldMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_SMALL); - Font mediumBoldMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_MEDIUM); - Font largeBoldMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE); - Font smallItalicMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_ITALIC, Font.SIZE_SMALL); - Font mediumItalicMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_ITALIC, Font.SIZE_MEDIUM); - Font largeItalicMonospaceFont = Font.createSystemFont(Font.FACE_MONOSPACE, Font.STYLE_ITALIC, Font.SIZE_LARGE); - - Font smallPlainProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_SMALL); - Font mediumPlainProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); - Font largePlainProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_LARGE); - Font smallBoldProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_SMALL); - Font mediumBoldProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM); - Font largeBoldProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE); - Font smallItalicProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_ITALIC, Font.SIZE_SMALL); - Font mediumItalicProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_ITALIC, Font.SIZE_MEDIUM); - Font largeItalicProportionalFont = Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_ITALIC, Font.SIZE_LARGE); - - String[] nativeFontTypes = { - "native:MainThin", "native:MainLight", - "native:MainRegular", "native:MainBold", - "native:MainBlack", "native:ItalicThin", - "native:ItalicLight", "native:ItalicRegular", - "native:ItalicBold", "native:ItalicBlack"}; - - for(String s : nativeFontTypes) { - Font tt = Font.createTrueTypeFont(s, s).derive(fontSize, Font.STYLE_PLAIN); - hi.add(createForFont(tt, s)); - } - - hi.add(createForFont(ttfFont, "Handlee TTF Font")). - add(createForFont(smallPlainSystemFont, "smallPlainSystemFont")). - add(createForFont(mediumPlainSystemFont, "mediumPlainSystemFont")). - add(createForFont(largePlainSystemFont, "largePlainSystemFont")). - add(createForFont(smallBoldSystemFont, "smallBoldSystemFont")). - add(createForFont(mediumBoldSystemFont, "mediumBoldSystemFont")). - add(createForFont(largeBoldSystemFont, "largeBoldSystemFont")). - add(createForFont(smallPlainSystemFont, "smallItalicSystemFont")). - add(createForFont(mediumItalicSystemFont, "mediumItalicSystemFont")). - add(createForFont(largeItalicSystemFont, "largeItalicSystemFont")). - - add(createForFont(smallPlainMonospaceFont, "smallPlainMonospaceFont")). - add(createForFont(mediumPlainMonospaceFont, "mediumPlainMonospaceFont")). - add(createForFont(largePlainMonospaceFont, "largePlainMonospaceFont")). - add(createForFont(smallBoldMonospaceFont, "smallBoldMonospaceFont")). - add(createForFont(mediumBoldMonospaceFont, "mediumBoldMonospaceFont")). - add(createForFont(largeBoldMonospaceFont, "largeBoldMonospaceFont")). - add(createForFont(smallItalicMonospaceFont, "smallItalicMonospaceFont")). - add(createForFont(mediumItalicMonospaceFont, "mediumItalicMonospaceFont")). - add(createForFont(largeItalicMonospaceFont, "largeItalicMonospaceFont")). - - add(createForFont(smallPlainProportionalFont, "smallPlainProportionalFont")). - add(createForFont(mediumPlainProportionalFont, "mediumPlainProportionalFont")). - add(createForFont(largePlainProportionalFont, "largePlainProportionalFont")). - add(createForFont(smallBoldProportionalFont, "smallBoldProportionalFont")). - add(createForFont(mediumBoldProportionalFont, "mediumBoldProportionalFont")). - add(createForFont(largeBoldProportionalFont, "largeBoldProportionalFont")). - add(createForFont(smallItalicProportionalFont, "smallItalicProportionalFont")). - add(createForFont(mediumItalicProportionalFont, "mediumItalicProportionalFont")). - add(createForFont(largeItalicProportionalFont, "largeItalicProportionalFont")); - - hi.show(); - } - // end::theme-basics-java-005[] -} diff --git a/docs/demos/javase/pom.xml b/docs/demos/javase/pom.xml index b5abd3b2737..f908dae19a6 100644 --- a/docs/demos/javase/pom.xml +++ b/docs/demos/javase/pom.xml @@ -244,6 +244,58 @@ + + + guide-screenshot-generator + + javase + com.codenameone.developerguide.GuideScreenshotDesktopStub + ${project.build.directory}/generated-guide-screenshots + + + + com.codenameone + codenameone-core + compile + + + com.codenameone + codenameone-javase + compile + + + + + src/main/resources + src/desktop/resources + + + + org.codehaus.mojo + exec-maven-plugin + + java + true + + -classpath + + ${exec.mainClass} + ${guide.screenshot.output} + + + + + generate-guide-screenshots + verify + + exec + + + + + + + desktop_build diff --git a/docs/demos/javase/src/main/java/com/codenameone/developerguide/GuideScreenshotDesktopStub.java b/docs/demos/javase/src/main/java/com/codenameone/developerguide/GuideScreenshotDesktopStub.java new file mode 100644 index 00000000000..4dab0d0324a --- /dev/null +++ b/docs/demos/javase/src/main/java/com/codenameone/developerguide/GuideScreenshotDesktopStub.java @@ -0,0 +1,69 @@ +package com.codenameone.developerguide; + +import com.codename1.ui.Display; + +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.io.File; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +/** + * JavaSE desktop entry point used by docs automation to regenerate guide screenshots. + */ +public final class GuideScreenshotDesktopStub implements Runnable { + private static final String APP_TITLE = "Guide Screenshots"; + private static final String APP_NAME = "DemoCodeScreenshots"; + private static final String APP_VERSION = "1.0"; + private static final int APP_WIDTH = 800; + private static final int APP_HEIGHT = 600; + private static final boolean APP_RESIZEABLE = false; + private static final boolean APP_FULLSCREEN = false; + + private static JFrame frame; + + public static void main(String[] args) { + System.out.println("Starting guide screenshot desktop stub"); + System.setProperty("java.awt.headless", "false"); + System.setProperty("guide.screenshot.output", args.length > 0 ? args[0] : "target/generated-guide-screenshots"); + + frame = new JFrame(APP_TITLE); + Display.init(frame.getContentPane()); + Display.getInstance().setProperty("AppName", APP_NAME); + Display.getInstance().setProperty("AppVersion", APP_VERSION); + Display.getInstance().setProperty("Platform", System.getProperty("os.name")); + Display.getInstance().setProperty("OSVer", System.getProperty("os.version")); + + SwingUtilities.invokeLater(new GuideScreenshotDesktopStub()); + } + + @Override + public void run() { + GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); + if (APP_FULLSCREEN && gd.isFullScreenSupported()) { + frame.setResizable(false); + frame.setUndecorated(true); + gd.setFullScreenWindow(frame); + } else { + frame.setLocationByPlatform(true); + frame.setResizable(APP_RESIZEABLE); + frame.getContentPane().setPreferredSize(new java.awt.Dimension(APP_WIDTH, APP_HEIGHT)); + frame.getContentPane().setMinimumSize(new java.awt.Dimension(APP_WIDTH, APP_HEIGHT)); + frame.getContentPane().setMaximumSize(new java.awt.Dimension(APP_WIDTH, APP_HEIGHT)); + frame.pack(); + } + Display.getInstance().callSerially(new Runnable() { + @Override + public void run() { + try { + GuideScreenshotGeneratorStub.generateInto(new File(System.getProperty("guide.screenshot.output"))); + } catch (Exception err) { + err.printStackTrace(); + System.exit(1); + } + Display.getInstance().exitApplication(); + } + }); + } +} diff --git a/docs/demos/javase/src/main/java/com/codenameone/developerguide/GuideScreenshotGeneratorStub.java b/docs/demos/javase/src/main/java/com/codenameone/developerguide/GuideScreenshotGeneratorStub.java new file mode 100644 index 00000000000..cf04e238dae --- /dev/null +++ b/docs/demos/javase/src/main/java/com/codenameone/developerguide/GuideScreenshotGeneratorStub.java @@ -0,0 +1,34 @@ +package com.codenameone.developerguide; + +import com.codenameone.developerguide.screenshots.PreAdvancedThemingScreenshots; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * JavaSE entry point used by docs automation to regenerate guide screenshots. + */ +public final class GuideScreenshotGeneratorStub { + private GuideScreenshotGeneratorStub() { + } + + public static void main(String[] args) throws Exception { + generateInto(new File(args.length > 0 ? args[0] : "target/generated-guide-screenshots")); + } + + public static void generateInto(File outputDirectory) throws IOException { + System.out.println("Generating guide screenshots into: " + outputDirectory.getAbsolutePath()); + if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { + throw new IOException("Unable to create screenshot output directory: " + outputDirectory); + } + PreAdvancedThemingScreenshots.generate(new PreAdvancedThemingScreenshots.ScreenshotSink() { + @Override + public OutputStream open(String fileName) throws IOException { + System.out.println("Generating guide screenshot: " + fileName); + return new FileOutputStream(new File(outputDirectory, fileName)); + } + }); + } +} diff --git a/docs/developer-guide/Theme-Basics.asciidoc b/docs/developer-guide/Theme-Basics.asciidoc deleted file mode 100644 index a947abd01f8..00000000000 --- a/docs/developer-guide/Theme-Basics.asciidoc +++ /dev/null @@ -1,458 +0,0 @@ -== Theme basics - -This chapter covers the creation of a simple hello-world style theme and its visual customization. It uses the Codename One Designer tool to show basic concepts in theme creation such as 9-piece borders, selectors, and style types. You should review this even if you end up using CSS. - -[[theme-basics-section,Codename One Theme Basics]] -=== Understanding Codename One themes - -Codename One themes are pluggable CSS-like elements that let developers determine or switch the look of the application at runtime. A theme can be installed through the https://www.codenameone.com/javadoc/com/codename1/ui/plaf/UIManager.html[UIManager class], and themes can be layered one on top of another. A theme can also be generated from CSS, and this guide covers that and the supported CSS syntax later. - -By default, Codename One themes derive the native operating system themes, although this behavior is entirely optional. - -A theme initializes the https://www.codenameone.com/javadoc/com/codename1/ui/plaf/Style.html[Style] objects, -which are then used by the components to render themselves or by the -https://www.codenameone.com/javadoc/com/codename1/ui/plaf/LookAndFeel.html[LookAndFeel] and -https://www.codenameone.com/javadoc/com/codename1/ui/plaf/DefaultLookAndFeel.html[DefaultLookAndFeel] -classes to create the appearance of the application. - -Codename One themes have some built-in defaults. For example, there are borders for buttons and padding, margin, and opacity for various components. These are "`common sense`" defaults that you can override within the theme. - -Codename One themes are effectively a set of UIIDs mapped to a https://www.codenameone.com/javadoc/com/codename1/ui/plaf/Style.html[Style] object. Codename One applications always have a theme. You can change it to suit your needs, and you can add many themes within the main resource file. - -You can also add many resource files to a project and work with them. In code, initialize a theme like this in your main class: - - -The `initFirstTheme` method is a helper method that hides some `try`/`catch` logic and some verbosity. It could be expressed as: - -[source,java] ----- -include::../demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava002Snippet.java[tag=theme-basics-java-002,indent=0] ----- - -=== Customizing your theme - -You can launch the designer tool by double clicking on the `theme.res` file found in typical Codename One applications. -On the left side you can see the section picker and within it the Theme section. - -.The theme area in the designer -image::img/theme-area-in-designer.png[The theme area in the designer] - -When you select the theme you will see the theme default view. - -.Theme default view -image::img/theme-default-view.png[Theme default view] - -There are many interesting things to notice here: the preview section allows you to instantly see the changes you make to the theme data. - -.Theme preview section -image::img/theme-preview-section.png[Theme preview section,scaledwidth=50%] - -The theme state tabs and constant tabs allow you to pass between the various editing modes for the theme and also add theme constants. - -As discussed earlier, you can pick the right style mode through the tabs. - -.You can use these tabs to add the various types of styles and theme constants -image::img/theme-state-tabs.png[You can use these tabs to add the various types of styles and theme constants,scaledwidth=50%] - -The most important section is the style section. It allows you to add/edit/remove style UIID's. - -Notice the #Default Style# section, it allows you to customize global defaults for the styles. Use it with caution as changes here can have wide implications. - -.The theme selection area allows you to add, edit and delete entries. Notice the default style entry which is a unique special case -image::img/theme-style-selection-pane.png[The theme selection area allows you to add, edit and delete entries. Notice the default style entry which is a unique special case,scaledwidth=50%] - -When you add an entry to the style you can type the desired UIID into the box at the top of the dialog. You can also pick a UIID from the combo box but that might not include all potential options. - -TIP: You can use the Component Inspector tool in the simulator to locate a component and its UIID in a specific https://www.codenameone.com/javadoc/com/codename1/ui/Form.html[Form] - -.When pressing the Add/Edit entry you can edit a specific style entry UIID -image::img/theme-add-edit-entry.png[When pressing the Add/Edit entry you can edit a specific style entry UIID,scaledwidth=50%] - -When you add/edit an entry an important piece of the puzzle is the #Derive# check box that appears next to all the UIID entries. All styles derive from the base style and from the native theme defaults, so when this flag is checked the defaults will be used. - -When you uncheck that checkbox the fields below it become editable and you can override the default behavior. To restore the default recheck that flag. - -NOTE: A common oddity for developers is that when they press #Add# and don't derive any entry nothing is actually added. The entries in the theme are essentially key/value pairs so when you don't add anything there are no keys so the entry doesn't show up - - -=== Customizing the title - -The title is a great target for customization since it includes a few interesting "complexities." - -The `Title` is surrounded by a `TitleArea` container that encloses it, above the title you will also see the `StatusBar` UIID that prevents the status details from drawing on top of the title text. - -.Title Area UIID's -image::img/theme-title-area-UIIDs.png[Title Area UIID's,scaledwidth=50%] - -TIP: The `StatusBar` UIID is a special case that's there on iOS. In iOS the application needs to render the section under the status bar (which isn't the case for other OSes) and the `StatusBar` UIID was added so developers can ignore that behavior. - -==== Background priorities and types - -A slightly confusing aspects of styles in Codename One is the priorities of backgrounds. When you define a specific kind of background it will override prior definitions, this even applies to inheritance. - -For example: if the theme defined a border for the `Button` UIID (a common case) if you will try to define the background image or the background color of `Button` those will be ignored! - -TIP: The solution is to derive the border and select the `Empty` border type - -[[background-priorities-list]] -The order for UIID settings for background is as follows: - -1. Border - if the component has a border it can override everything. Image borders always override all background settings you might have. - -2. Image or gradient - an image or gradient background overrides background color/transparency settings. - -3. Background Color/Transparency - If transparency is larger than 0 then this takes effect. - -==== The background behavior and Image - -Start in the first page of the style entry, you will customize the background behavior for the `Title` UIID and show/explain some behaviors. - -The pictures below show the different types of background image behaviors. - -.IMAGE_SCALED scales the image without preserving aspect ratio to fit the exact size of the component -image::img/theme-background-image-scaled.png[IMAGE_SCALED scales the image without preserving aspect ratio to fit the exact size of the component] - -.IMAGE_SCALED_FILL scales the image while preserving aspect ratio so it fills the entire space of the component -image::img/theme-background-image-scaled-fill.png[IMAGE_SCALED_FILL scales the image while preserving aspect ratio so it fills the entire space of the component] - -TIP: Aspect ratio is the ratio between the width and the height of the image. For example: if the image is `100x50` pixels and you want the width to be 200 pixels preserving the aspect ratio will require the height to also double to `200x100`. + -You highly recommend preserving the aspect ratio to keep images more "natural." - -.IMAGE_SCALED_FIT scales the image while preserving aspect ratio so it fits within the component -image::img/theme-background-image-scaled-fit.png[IMAGE_SCALED_FIT scales the image while preserving aspect ratio so it fits within the component] - -.IMAGE_TILE_BOTH tiles the image on both axis of the component -image::img/theme-background-image-tile-both.png[IMAGE_TILE_BOTH tiles the image on both axis of the component] - -.IMAGE_TILE_VERTICAL_ALIGN_LEFT tiles the image on the left side of the component -image::img/theme-background-image-tile-vertical-left-align.png[IMAGE_TILE_VERTICAL_ALIGN_LEFT tiles the image on the left side of the component] - -.IMAGE_TILE_VERTICAL_ALIGN_CENTER tiles the image in the middle of the component -image::img/theme-background-image-tile-vertical-center-align.png[IMAGE_TILE_VERTICAL_ALIGN_CENTER tiles the image in the middle of the component] - -.IMAGE_TILE_VERTICAL_ALIGN_RIGHT tiles the image on the right side of the component -image::img/theme-background-image-tile-vertical-right-align.png[IMAGE_TILE_VERTICAL_ALIGN_RIGHT tiles the image on the right side of the component] - -.IMAGE_TILE_HORIZONTAL_ALIGN_TOP tiles the image on the top of the component -image::img/theme-background-image-tile-horizontal-align-top.png[IMAGE_TILE_HORIZONTAL_ALIGN_TOP tiles the image on the top of the component] - -.IMAGE_TILE_HORIZONTAL_ALIGN_CENTER tiles the image in the middle of the component -image::img/theme-background-image-tile-horizontal-align-center.png[IMAGE_TILE_HORIZONTAL_ALIGN_CENTER tiles the image in the middle of the component] - -.IMAGE_TILE_HORIZONTAL_ALIGN_BOTTOM tiles the image to the bottom of the component -image::img/theme-background-image-tile-horizontal-align-bottom.png[IMAGE_TILE_HORIZONTAL_ALIGN_BOTTOM tiles the image to the bottom of the component] - -.IMAGE_ALIGNED_TOP places the image centered at the top part of the component -image::img/theme-background-image-aligned-top.png[IMAGE_ALIGNED_TOP places the image centered at the top part of the component] - -.IMAGE_ALIGNED_BOTTOM places the image centered at the bottom part of the component -image::img/theme-background-image-aligned-bottom.png[IMAGE_ALIGNED_BOTTOM places the image centered at the bottom part of the component] - -.IMAGE_ALIGNED_LEFT places the image centered at the left part of the component -image::img/theme-background-image-aligned-left.png[IMAGE_ALIGNED_LEFT places the image centered at the left part of the component] - -.IMAGE_ALIGNED_RIGHT places the image centered at the right part of the component -image::img/theme-background-image-aligned-right.png[IMAGE_ALIGNED_RIGHT places the image centered at the right part of the component] - -.IMAGE_ALIGNED_TOP_LEFT places the image in the top left corner -image::img/theme-background-image-aligned-top-left.png[IMAGE_ALIGNED_TOP_LEFT places the image in the top left corner] - -.IMAGE_ALIGNED_TOP_RIGHT places the image in the top right corner -image::img/theme-background-image-aligned-top-right.png[IMAGE_ALIGNED_TOP_RIGHT places the image in the top right corner] - -.IMAGE_ALIGNED_BOTTOM_LEFT places the image in the bottom left corner -image::img/theme-background-image-aligned-bottom-left.png[IMAGE_ALIGNED_BOTTOM_LEFT places the image in the bottom left corner] - -.IMAGE_ALIGNED_BOTTOM_RIGHT places the image in the bottom right corner -image::img/theme-background-image-aligned-bottom-right.png[IMAGE_ALIGNED_BOTTOM_RIGHT places the image in the bottom right corner] - -.IMAGE_ALIGNED_CENTER places the image in the middle of the component -image::img/theme-background-image-aligned-center.png[IMAGE_ALIGNED_CENTER places the image in the middle of the component] - -==== The color settings - -The color settings are much simpler than the background behavior. As explained <> the priority for color is at the bottom so if you have a border, image or gradient defined the background color settings will be ignored. - -.Add theme entry color settings -image::img/theme-entry-color.png[Add theme entry color settings] - -There are three color settings: - -- Foreground color is the RRGGBB color that sets the style foreground color used to draw the text of the component. You can use the color picker button on the side to pick a color - -- Background same as foreground determines the background color of the component - -- Transparency represents the opacity of the component background as a value between 0 (transparent) and 255 (opaque) - -TIP: Setting the background will have no effect unless transparency is higher than 0. If you don't explicitly define this it might have a different value based on the native theme - -==== Alignment - -Not all component types support alignment and even when they do, they don't support it for all elements. For example: a https://www.codenameone.com/javadoc/com/codename1/ui/Label.html[Label] and its subclasses support alignment but will apply it to the text and not the icon. - -Notice that https://www.codenameone.com/javadoc/com/codename1/ui/Container.html[Container] doesn't support alignment. You should use the layout manager to tune component positioning. - -.Alignment of the text within some component types -image::img/theme-entry-align.png[Alignment of the text within some component types] - -WARNING: Aligning text components to anything other than the default alignment might be a problem if they're editable. The native editing capabilities might collide with the alignment behavior. - -NOTE: Bidi/RtL layout reverses the alignment value so left becomes right and vice versa - -==== Padding and margin - -Padding and margin are concepts derived from the CSS box model. They're slightly different in Codename One, where the border spacing is part of the padding, but other than that they're pretty similar: - -.Padding and Margin/Box Model -image::img/padding.png[Padding and Margin,scaledwidth=50%] - -In the diagram, you can see the component represented in yellow occupying its preferred size. The padding portion in gray effectively increases the components size. The margin is the space between components, it allows you to keep whitespace between many components. Margin is represented in red in the diagram. - -The theme allows you to customize the padding/margin, and specify them for all 4 sides of a component. They can be specified in pixels, millimeters/dips, or screen percentage: - -.Padding tab -image::img/theme-entry-padding.png[Padding tab] - -TIP: You recommend using millimeters for all spacing to make it look good for all device densities. Percentages make sense in extreme cases. - -==== Borders - -Borders are a big subject in their own right, the UI for their creation is also a bit confusing: - -.Border entry in the theme -image::img/theme-entry-border-settings.png[Border entry in the theme] - -==== 9-Piece Image Border - -A common border type is the 9-piece image border. To simplify creating this kind of border, there is a special #Image Border Wizard#. - -A 9-piece image border is a common convention in UI theming that divides a border into 9 pieces: 4 representing the corners, 4 representing the sides, and 1 representing the middle. - -TIP: Android uses a common variation on the 9-piece border: 9-patch. The main difference between the 9-piece border and 9-patch is that 9-piece borders tile the sides/center whereas 9-patch scales them - -The 9-piece image borders work better than background images for many use cases where the background needs to "grow/shrink" extensively and might need to change aspect ratio. - -They don't work well in cases where the image is asymmetric on both axis. For example: a radial gradient image. 9-piece images in general don't work well with complex gradients. - -The image border wizard simplifies the process of generating a 9-piece image border using a 3 stage process. - -.Stage 1: create or pick an image from an existing PNG file that you will convert to a 9-piece image -image::img/theme-entry-9-piece-wizard-stage1.png[Stage 1: create or pick an image from an existing PNG file that you will convert to a 9-piece image] - -TIP: Use an image that's designed for a high DPI device - -For your convenience you can create a rudimentary image with the `create image` stage but for a professional looking application you would want to use a design by a professional designer. - -.Stage 2: Cutting the image and adapting it to the DPI's -image::img/theme-entry-9-piece-wizard-stage2.png[Stage 2: Cutting the image and adapting it to the DPI's] - -The second stage is probably the hardest and most important one in this wizard! - -You can change the values of the top/bottom/left/right spinners to move the position of the guidelines that show the various 9 pieces. The image shows the correct cut for this image type with special attention to the following: - -- The left/right position is high enough to fit in the rounded corners in their entirety. Notice that you didn't leave 1 pixel as that performs badly, you want to leave as much space as possible! - -- The top and bottom lines have one pixel between them. This is to avoid breaking the gradient. For example: if you set the lines further apart you will end up with this: - -.This is why it's important to keep the lines close when a gradient is involved, notice the tiling effect... -image::img/theme-entry-9-piece-wizard-stage2-bad-border.png[This is why it's important to keep the lines close when a gradient is involved, notice the tiling effect...,scaledwidth=30%] - -.When the lines are close together the gradient effect grows more effectively -image::img/theme-entry-9-piece-wizard-stage2-better-border.png[When the lines are close together the gradient effect grows more effectively,scaledwidth=30%] - -- The elements on the right-hand side include the #Generate Multi Image# options. Here you can show the density of the source image you're using (for example: if its for iPhone 5 class device pick High). You can then select in the checkboxes below the densities that should be generated automatically for you. This allows fine detail on the border to be maintained in the various high/low resolution devices. - -TIP: You go into a lot of details about multi images in the advanced theming section. - -.Stage 3: Styles to which the border is applied -image::img/theme-entry-9-piece-wizard-stage3.png[Stage 3: Styles to which the border is applied] - -The last page indicates the styles to which the wizard will apply the border. Under normal usage you don't need to touch this as its filled out. - -You can define the same border for many UIIDs from here though. - -// vale-skip: write-good.TooWordy β€” 'Minimum Size' is a precise dimensional constraint label. -.Border Minimum Size -***** -A common oddity when using the image borders is the fact that even when padding is removed the component might take a larger size than the height of the text within it. - -// vale-skip: write-good.TooWordy β€” 'minimum height/width' refers to a numeric lower bound, not a comparison. -The reason for this is the border. Because of the way borders are implemented they can't be drawn to be smaller than the sum of their corners. For example: the minimum height of a border would be the height of the bottom corner + the height of the top corner. The minimum width would be the width of the left + right corners. - -This is coded into the common preferred size methods in Codename One and components don't shrink below the size of the image border even if padding is 0. -***** - -===== Customizing the 9-Piece Border - -You can use the 9-piece border wizard but you can also customize the border by pressing the "..." button on the border section in the theme. - -.Press this to customize borders -image::img/theme-entry-border-three-dot-button.png[Press this to customize borders] - -The UI for the 9-piece border you created above looks like <>. - -[[theme-entry-border-edit-9-piece]] -.9-piece border in edit mode -image::img/theme-entry-border-edit-9-piece.png[9-piece border in edit mode] - -You can pick the image represented by every section in the border from the combo boxes. They're organized in the same way the border is with the 9-pieces placed in the same position they would occupy when the border is rendered. - -NOTE: Notice that the other elements in the UI are disabled when the image border type is selected. - -.3 Image Mode -**** -// vale-skip: write-good.Weasel β€” 'rarely used' is the natural phrase here; deleting 'rarely' would lose the meaning. -The 9-piece border has a (rarely used) special case: 3 image mode. In this mode a developer can specify the top left corner, the top image and the center image to produce a 9 piece border. The corner and top piece are then rotated dynamically to produce a standard 9-piece border on the device. - -This is useful for reducing application code size but isn't used often as it requires a more symmetric UI. - -NOTE: Don't confuse the 3-image mode for the 9-piece border with the horizontal/vertical image border below -**** - -==== Horizontal/Vertical Image Border - -The 9-piece border is the workhorse of borders in Codename One, but there are some edge cases of UI elements that should grow on one axis and not on another. A perfect example of this is the iOS 6 style back button. If you tried to cut it into a 9-piece border the arrow effect would be broken. - -.Horizontal image border is commonly used for UI's that can't grow vertically for example: the iOS 6 style back button -image::img/theme-entry-border-edit-horizontal-image.png[Horizontal image border is commonly used for UI's that can't grow vertically for example: the iOS style back button] - -The horizontal and vertical image borders accept 3 images of their respective AXIS and build the border by placing one image on each side and tiling the center image between them. For example: A horizontal border will never grow vertically. - -TIP: In RTL/Bidi footnote:[Languages that are written from right to left such as Hebrew, Arabic etc.] modes the borders flip automatically to show the reverse direction. An iOS style back button will point to the right in such languages. - -==== Empty Border - -Empty borders enforce the removal of a border. This is important if you would like to block a base style from having a border. - -For example: Buttons have borders by default. If you would like to create a https://www.codenameone.com/javadoc/com/codename1/ui/Button.html[Button] that's of solid color you could define the border to be empty and then use the solid color as you see fit. - -IMPORTANT: A null border exists and is often confused with an empty border. You should use empty border and not null border - -==== Round Border - -Circles and round border sides are problematic for multi-resolutions. You need to draw them dynamically and can't use image borders which can't be tiled/cut to fit round designs (due to physical constraints of the round shape). - -You designed the `RoundBorder` to enable two distinct types of borders: - -- Circular borders - for example: Android floating action -- Rectangles with round (not rounded) sides - -**Round** Border is a bit confusing since you already support a **rounded** border type. The rounded border type is a rectangle with rounded corners whereas the round border has round sides or appears as a circle. - -To make matters worse the round border has a ridiculous number of features/configurations that would have made the already cluttered UI darn near impossible to navigate. To simplify this you split the UI into 3 tabs for standard borders, image borders and round border. - - -.Round Border -image::img/round-border-theme.png[Round Border,scaledwidth=50%] - -==== Rounded rectangle Border - -The `RoundRectBorder` was developed based on the `RoundBorder` and has similar features. It produces a rounded rectangle UI. - -TIP: Don't confuse the Rounded Rectangle border with the deprecated `Rounded` border... - -It's a pretty simple border type akin to the `RoundBorder`. - -.Rounded Rectangle Border -image::img/rounded-rectangle-border.png[Rounded Rectangle Border,scaledwidth=50%] - - -==== Bevel/Etched borders - -You recommend avoiding bevel/etched border types as they aren't as efficient and look a bit dated in today's applications. You cover them here for completeness. - -.Bevel border -image::img/theme-entry-border-edit-bevel.png[Bevel border] - -.Etched border -image::img/theme-entry-border-edit-etched.png[Etched border] - -==== Derive - -Derive allows you to inherit the behavior of a UIID and extend it with some customization. - -For example: Lets say you created a component that's supposed to look like a title, you could do something like: - - -However, title might sometimes be aligned to the left (based on theme) and you always want your component to be center aligned. For example, you don't want that to affect the actual titles in the app... - -To solve this you can define a `MyTitle` UIID and derive the `Title` UIID. Then customize that one attribute. - -.Derive title -image::img/theme-entry-derive.png[Derive title] - -.Issues With Derive -**** -Style inheritance is a problematic topic in every tool that supports such behavior. Codename One styles start from a global default then have a system default applied and on top of that have the native OS default applied to them. - -At that point a developer can define the style after all the user settings are in place. This works reasonably well, but there are some edge cases where inheriting a style can fail. - -When you override an existing style such as `Button` and choose to derive from `Button` in a different selection mode or even a different component altogether such as `Label` you might trigger a recursion effect where a theme setting in the base theme depends on something in a base triggering an infinite loop. - -To avoid this always inherit only from UIID's you defined for example, `MyButton`. -**** - -==== Fonts - -Codename One supports 3 font types: - -- *System fonts:* these are simplistic built-in fonts. They work on all platforms and come in one of 3 sizes. For example, they're ubiquitous and work in every platform in all languages. - -- *TTF files:* you can place a TTF file in the src directory of the project and it will appear in the #True Type# combo box. - -- *Native fonts:* these aren't supported on all platforms but they allow you to use a set of platform native good looking fonts. For example: on Android the devices Roboto font will be used and on iOS San Francisco or Helvetica Neue will be used. *This is the recommended font type for most use cases.* - -WARNING: If you use a TTF file **MAKE SURE** not to delete the file when there **MIGHT** be a reference to it. This can cause hard to track down issues! - -IMPORTANT: Notice that a TTF file must have the ".ttf" extension, otherwise the build server won't be able to recognize the file as a font and set it up accordingly (devices need fonts to be defined in specific ways). Once you do that, you can use the font from code or from the theme - -.Font Theme Entry -image::img/theme-entry-fonts.png[Font Theme Entry] - -NOTE: System fonts are always defined even if you use a TTF or native font. If the native font/TTF is unavailable in a specific platform the system font will be used instead. - -You can size native/TTF fonts either through pixels, millimeters or based on the size of the equivalent system fonts: - -1. *System font size* - the truetype font will have the same size as a small, medium or large system font. This allows the developer to size the font based on the device DPI - -2. *Millimeter size* - allows sizing the font in a more DPI aware size - -3. *Pixels* - useful for some unique cases, but highly problematic in multi-DPI scenarios - -NOTE: You should notice that font sizing is inconsistent between platforms recommend using millimeters for sizing - -You can load a truetype font from code using: - - -Notice that, in code, pixel sizes are supported, so it’s up to you to decide how to convert that. Recommend using millimeters with the `convertToPixels` method. You also need to derive the font with the proper size, unless you want a 0 sized font which isn't useful. - -The font name is the difficult bit, iOS requires the name of the font to load the font. This font name doesn't always correlate to the file name making this task rather "tricky." The actual font name is sometimes viewable within a font viewer. It isn't always intuitive, so be sure to test that on the device to make sure you got it right. - -IMPORTANT: Due to licensing restrictions Codename One doesn't bundle Apple's iOS fonts. In the simulator with an iOS skin you try to use installed San Francisco/SF Pro (or Helvetica Neue) fonts when available on your machine; otherwise you fall back to bundled Roboto. You can get Apple's font downloads and terms at https://developer.apple.com/fonts/ - -The code below demonstrates all the major fonts available in Codename One with the handlee ttf file posing as a standin for arbitrary TTF: - -[source,java] ----- -include::../demos/common/src/main/java/com/codenameone/developerguide/snippets/generated/ThemeBasicsJava005Snippet.java[tag=theme-basics-java-005,indent=0] ----- - -.The fonts running on the ipad simulator on a Mac, notice that this will look different on a PC -image::img/theme-font-catalog.png[The fonts running on the ipad simulator on a Mac, notice that this will look different on a PC,scaledwidth=60%] - -.The same demo running on a OnePlus One device with Android 5.1 -image::img/theme-font-catalog-opo.png[The same demo running on a OnePlus One device with Android 5.1,scaledwidth=60%] - - -===== Font effects - -You can define an effect to be applied to a specific font, specifically: - -- Underline -- Strike through -- 3d text raised/lowered -- 3d shadow north - -The "3d" effects effectively draw the text twice, with a slight offset and two different colors to create a "3d" feel. - -All the effects are simple and performant. diff --git a/docs/developer-guide/developer-guide.asciidoc b/docs/developer-guide/developer-guide.asciidoc index b1f02ccdffd..81416bfebfb 100644 --- a/docs/developer-guide/developer-guide.asciidoc +++ b/docs/developer-guide/developer-guide.asciidoc @@ -49,8 +49,6 @@ include::Index.asciidoc[] include::basics.asciidoc[] -include::Theme-Basics.asciidoc[] - include::Advanced-Theming.asciidoc[] include::Native-Themes.asciidoc[] diff --git a/docs/developer-guide/img/border-layout-RTL.png b/docs/developer-guide/img/border-layout-RTL.png index 5239ea165c8..95e79675f1f 100644 Binary files a/docs/developer-guide/img/border-layout-RTL.png and b/docs/developer-guide/img/border-layout-RTL.png differ diff --git a/docs/developer-guide/img/border-layout-center.png b/docs/developer-guide/img/border-layout-center.png index 18cd90820bc..398b2658b15 100644 Binary files a/docs/developer-guide/img/border-layout-center.png and b/docs/developer-guide/img/border-layout-center.png differ diff --git a/docs/developer-guide/img/border-layout.png b/docs/developer-guide/img/border-layout.png index 959ee265309..b88ae544390 100644 Binary files a/docs/developer-guide/img/border-layout.png and b/docs/developer-guide/img/border-layout.png differ diff --git a/docs/developer-guide/img/box-layout-x-no-grow.png b/docs/developer-guide/img/box-layout-x-no-grow.png index 06cc4a55ccd..df53706a6c4 100644 Binary files a/docs/developer-guide/img/box-layout-x-no-grow.png and b/docs/developer-guide/img/box-layout-x-no-grow.png differ diff --git a/docs/developer-guide/img/box-layout-x.png b/docs/developer-guide/img/box-layout-x.png index 11cdc429221..a676564e83f 100644 Binary files a/docs/developer-guide/img/box-layout-x.png and b/docs/developer-guide/img/box-layout-x.png differ diff --git a/docs/developer-guide/img/box-layout-y.png b/docs/developer-guide/img/box-layout-y.png index 205311ce9e9..6c5aa6e082b 100644 Binary files a/docs/developer-guide/img/box-layout-y.png and b/docs/developer-guide/img/box-layout-y.png differ diff --git a/docs/developer-guide/img/flow-layout-center-middle.png b/docs/developer-guide/img/flow-layout-center-middle.png index 1ee82decba2..f67dfa2281b 100644 Binary files a/docs/developer-guide/img/flow-layout-center-middle.png and b/docs/developer-guide/img/flow-layout-center-middle.png differ diff --git a/docs/developer-guide/img/flow-layout-center.png b/docs/developer-guide/img/flow-layout-center.png index c1b3237419a..abb0f26a28a 100644 Binary files a/docs/developer-guide/img/flow-layout-center.png and b/docs/developer-guide/img/flow-layout-center.png differ diff --git a/docs/developer-guide/img/flow-layout-right.png b/docs/developer-guide/img/flow-layout-right.png index 1e9bd7b7b67..333ffa7c2b2 100644 Binary files a/docs/developer-guide/img/flow-layout-right.png and b/docs/developer-guide/img/flow-layout-right.png differ diff --git a/docs/developer-guide/img/flow-layout.png b/docs/developer-guide/img/flow-layout.png index a4787999c46..609f84de599 100644 Binary files a/docs/developer-guide/img/flow-layout.png and b/docs/developer-guide/img/flow-layout.png differ diff --git a/docs/developer-guide/img/grid-layout-2x2.png b/docs/developer-guide/img/grid-layout-2x2.png index 7f1d2184f0e..ba2329cce9b 100644 Binary files a/docs/developer-guide/img/grid-layout-2x2.png and b/docs/developer-guide/img/grid-layout-2x2.png differ diff --git a/docs/developer-guide/img/grid-layout-2x4.png b/docs/developer-guide/img/grid-layout-2x4.png index c9a4d455c46..af3242b504a 100644 Binary files a/docs/developer-guide/img/grid-layout-2x4.png and b/docs/developer-guide/img/grid-layout-2x4.png differ diff --git a/docs/developer-guide/img/grid-layout-autofit-landscape.png b/docs/developer-guide/img/grid-layout-autofit-landscape.png index 0108ebcbe6a..4cf353d5626 100644 Binary files a/docs/developer-guide/img/grid-layout-autofit-landscape.png and b/docs/developer-guide/img/grid-layout-autofit-landscape.png differ diff --git a/docs/developer-guide/img/grid-layout-autofit-portrait.png b/docs/developer-guide/img/grid-layout-autofit-portrait.png index 517cc895c80..7e62c765a54 100644 Binary files a/docs/developer-guide/img/grid-layout-autofit-portrait.png and b/docs/developer-guide/img/grid-layout-autofit-portrait.png differ diff --git a/docs/developer-guide/img/gridbag-layout.png b/docs/developer-guide/img/gridbag-layout.png index 835cfe6b54d..e9c6b977d5f 100644 Binary files a/docs/developer-guide/img/gridbag-layout.png and b/docs/developer-guide/img/gridbag-layout.png differ diff --git a/docs/developer-guide/img/group-layout.png b/docs/developer-guide/img/group-layout.png index 2d40bc14b87..9a886156db2 100644 Binary files a/docs/developer-guide/img/group-layout.png and b/docs/developer-guide/img/group-layout.png differ diff --git a/docs/developer-guide/img/guibuilder-2-insets-1.png b/docs/developer-guide/img/guibuilder-2-insets-1.png index a7b824d2dde..179a9cebcea 100644 Binary files a/docs/developer-guide/img/guibuilder-2-insets-1.png and b/docs/developer-guide/img/guibuilder-2-insets-1.png differ diff --git a/docs/developer-guide/img/guibuilder-2-insets-2.png b/docs/developer-guide/img/guibuilder-2-insets-2.png index 557530e1da2..e3051918c76 100644 Binary files a/docs/developer-guide/img/guibuilder-2-insets-2.png and b/docs/developer-guide/img/guibuilder-2-insets-2.png differ diff --git a/docs/developer-guide/img/guibuilder-2-insets-3.png b/docs/developer-guide/img/guibuilder-2-insets-3.png index 656bc4f0362..3aa0bfbf478 100644 Binary files a/docs/developer-guide/img/guibuilder-2-insets-3.png and b/docs/developer-guide/img/guibuilder-2-insets-3.png differ diff --git a/docs/developer-guide/img/layered-layout.png b/docs/developer-guide/img/layered-layout.png index 4782364d4bc..af04164ae34 100644 Binary files a/docs/developer-guide/img/layered-layout.png and b/docs/developer-guide/img/layered-layout.png differ diff --git a/docs/developer-guide/img/mig-layout.png b/docs/developer-guide/img/mig-layout.png index c758d463a8e..910e722133c 100644 Binary files a/docs/developer-guide/img/mig-layout.png and b/docs/developer-guide/img/mig-layout.png differ diff --git a/docs/developer-guide/img/padding.png b/docs/developer-guide/img/padding.png deleted file mode 100644 index 8ef43251cff..00000000000 Binary files a/docs/developer-guide/img/padding.png and /dev/null differ diff --git a/docs/developer-guide/img/round-border-theme.png b/docs/developer-guide/img/round-border-theme.png deleted file mode 100644 index 07625081a8f..00000000000 Binary files a/docs/developer-guide/img/round-border-theme.png and /dev/null differ diff --git a/docs/developer-guide/img/rounded-rectangle-border.png b/docs/developer-guide/img/rounded-rectangle-border.png deleted file mode 100644 index eea2a6286b4..00000000000 Binary files a/docs/developer-guide/img/rounded-rectangle-border.png and /dev/null differ diff --git a/docs/developer-guide/img/table-layout-2x2.png b/docs/developer-guide/img/table-layout-2x2.png index 93eff1449cd..7a066de29dc 100644 Binary files a/docs/developer-guide/img/table-layout-2x2.png and b/docs/developer-guide/img/table-layout-2x2.png differ diff --git a/docs/developer-guide/img/table-layout-constraints.png b/docs/developer-guide/img/table-layout-constraints.png index 1df95450cdc..c9afd65acc6 100644 Binary files a/docs/developer-guide/img/table-layout-constraints.png and b/docs/developer-guide/img/table-layout-constraints.png differ diff --git a/docs/developer-guide/img/table-layout-enclose.png b/docs/developer-guide/img/table-layout-enclose.png index 76e59c15cdf..0bce1e15513 100644 Binary files a/docs/developer-guide/img/table-layout-enclose.png and b/docs/developer-guide/img/table-layout-enclose.png differ diff --git a/docs/developer-guide/img/theme-add-edit-entry.png b/docs/developer-guide/img/theme-add-edit-entry.png deleted file mode 100644 index 27663fbe6b1..00000000000 Binary files a/docs/developer-guide/img/theme-add-edit-entry.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-area-in-designer.png b/docs/developer-guide/img/theme-area-in-designer.png deleted file mode 100644 index b020d3df6c3..00000000000 Binary files a/docs/developer-guide/img/theme-area-in-designer.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-bottom-left.png b/docs/developer-guide/img/theme-background-image-aligned-bottom-left.png deleted file mode 100644 index ab7fda6c212..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-bottom-left.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-bottom-right.png b/docs/developer-guide/img/theme-background-image-aligned-bottom-right.png deleted file mode 100644 index beb4f30d9ef..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-bottom-right.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-bottom.png b/docs/developer-guide/img/theme-background-image-aligned-bottom.png deleted file mode 100644 index b4e8037ac69..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-bottom.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-center.png b/docs/developer-guide/img/theme-background-image-aligned-center.png deleted file mode 100644 index c80ca8f0a1e..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-center.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-left.png b/docs/developer-guide/img/theme-background-image-aligned-left.png deleted file mode 100644 index 3a04fb4be65..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-left.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-right.png b/docs/developer-guide/img/theme-background-image-aligned-right.png deleted file mode 100644 index dc8277d94d5..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-right.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-top-left.png b/docs/developer-guide/img/theme-background-image-aligned-top-left.png deleted file mode 100644 index 06a3184a90e..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-top-left.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-top-right.png b/docs/developer-guide/img/theme-background-image-aligned-top-right.png deleted file mode 100644 index 60194909802..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-top-right.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-aligned-top.png b/docs/developer-guide/img/theme-background-image-aligned-top.png deleted file mode 100644 index a567bdec783..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-aligned-top.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-scaled-fill.png b/docs/developer-guide/img/theme-background-image-scaled-fill.png deleted file mode 100644 index 730106c7e6f..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-scaled-fill.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-scaled-fit.png b/docs/developer-guide/img/theme-background-image-scaled-fit.png deleted file mode 100644 index 06e9d523c3c..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-scaled-fit.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-scaled.png b/docs/developer-guide/img/theme-background-image-scaled.png deleted file mode 100644 index e582f78cfb2..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-scaled.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-both.png b/docs/developer-guide/img/theme-background-image-tile-both.png deleted file mode 100644 index 84a9b1da8e2..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-both.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-horizontal-align-bottom.png b/docs/developer-guide/img/theme-background-image-tile-horizontal-align-bottom.png deleted file mode 100644 index 01cf2480c22..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-horizontal-align-bottom.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-horizontal-align-center.png b/docs/developer-guide/img/theme-background-image-tile-horizontal-align-center.png deleted file mode 100644 index 75b5e82eaf9..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-horizontal-align-center.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-horizontal-align-top.png b/docs/developer-guide/img/theme-background-image-tile-horizontal-align-top.png deleted file mode 100644 index c9fa57eeb1e..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-horizontal-align-top.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-vertical-center-align.png b/docs/developer-guide/img/theme-background-image-tile-vertical-center-align.png deleted file mode 100644 index 62bf24f026b..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-vertical-center-align.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-vertical-left-align.png b/docs/developer-guide/img/theme-background-image-tile-vertical-left-align.png deleted file mode 100644 index 326bcf3230a..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-vertical-left-align.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-background-image-tile-vertical-right-align.png b/docs/developer-guide/img/theme-background-image-tile-vertical-right-align.png deleted file mode 100644 index 8c65b5926b1..00000000000 Binary files a/docs/developer-guide/img/theme-background-image-tile-vertical-right-align.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-default-view.png b/docs/developer-guide/img/theme-default-view.png deleted file mode 100644 index ff2443da9fb..00000000000 Binary files a/docs/developer-guide/img/theme-default-view.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage1.png b/docs/developer-guide/img/theme-entry-9-piece-wizard-stage1.png deleted file mode 100644 index 994637713b1..00000000000 Binary files a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage1.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2-bad-border.png b/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2-bad-border.png deleted file mode 100644 index a7b765bf402..00000000000 Binary files a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2-bad-border.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2-better-border.png b/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2-better-border.png deleted file mode 100644 index f389f46cce3..00000000000 Binary files a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2-better-border.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2.png b/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2.png deleted file mode 100644 index 350d716a43d..00000000000 Binary files a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage2.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage3.png b/docs/developer-guide/img/theme-entry-9-piece-wizard-stage3.png deleted file mode 100644 index cca8ea2b3e8..00000000000 Binary files a/docs/developer-guide/img/theme-entry-9-piece-wizard-stage3.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-align.png b/docs/developer-guide/img/theme-entry-align.png deleted file mode 100644 index f2f25447e33..00000000000 Binary files a/docs/developer-guide/img/theme-entry-align.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-border-edit-9-piece.png b/docs/developer-guide/img/theme-entry-border-edit-9-piece.png deleted file mode 100644 index 3c325d8d574..00000000000 Binary files a/docs/developer-guide/img/theme-entry-border-edit-9-piece.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-border-edit-bevel.png b/docs/developer-guide/img/theme-entry-border-edit-bevel.png deleted file mode 100644 index 4f046ffa462..00000000000 Binary files a/docs/developer-guide/img/theme-entry-border-edit-bevel.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-border-edit-etched.png b/docs/developer-guide/img/theme-entry-border-edit-etched.png deleted file mode 100644 index f88e8182b52..00000000000 Binary files a/docs/developer-guide/img/theme-entry-border-edit-etched.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-border-edit-horizontal-image.png b/docs/developer-guide/img/theme-entry-border-edit-horizontal-image.png deleted file mode 100644 index 4574a742f9a..00000000000 Binary files a/docs/developer-guide/img/theme-entry-border-edit-horizontal-image.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-border-settings.png b/docs/developer-guide/img/theme-entry-border-settings.png deleted file mode 100644 index 743adc6e7fe..00000000000 Binary files a/docs/developer-guide/img/theme-entry-border-settings.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-border-three-dot-button.png b/docs/developer-guide/img/theme-entry-border-three-dot-button.png deleted file mode 100644 index ea14b5239ac..00000000000 Binary files a/docs/developer-guide/img/theme-entry-border-three-dot-button.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-color.png b/docs/developer-guide/img/theme-entry-color.png deleted file mode 100644 index 33ba7d4a8d9..00000000000 Binary files a/docs/developer-guide/img/theme-entry-color.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-derive.png b/docs/developer-guide/img/theme-entry-derive.png deleted file mode 100644 index 17884e75e5e..00000000000 Binary files a/docs/developer-guide/img/theme-entry-derive.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-fonts.png b/docs/developer-guide/img/theme-entry-fonts.png deleted file mode 100644 index df03b9451b8..00000000000 Binary files a/docs/developer-guide/img/theme-entry-fonts.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-entry-padding.png b/docs/developer-guide/img/theme-entry-padding.png deleted file mode 100644 index 6a6ad232d4e..00000000000 Binary files a/docs/developer-guide/img/theme-entry-padding.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-font-catalog-opo.png b/docs/developer-guide/img/theme-font-catalog-opo.png deleted file mode 100644 index b743e37c41d..00000000000 Binary files a/docs/developer-guide/img/theme-font-catalog-opo.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-font-catalog.png b/docs/developer-guide/img/theme-font-catalog.png deleted file mode 100644 index 94a6cd1102a..00000000000 Binary files a/docs/developer-guide/img/theme-font-catalog.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-preview-section.png b/docs/developer-guide/img/theme-preview-section.png deleted file mode 100644 index 1befaeaaa27..00000000000 Binary files a/docs/developer-guide/img/theme-preview-section.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-state-tabs.png b/docs/developer-guide/img/theme-state-tabs.png deleted file mode 100644 index 7dab145f41a..00000000000 Binary files a/docs/developer-guide/img/theme-state-tabs.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-style-selection-pane.png b/docs/developer-guide/img/theme-style-selection-pane.png deleted file mode 100644 index 287d754812d..00000000000 Binary files a/docs/developer-guide/img/theme-style-selection-pane.png and /dev/null differ diff --git a/docs/developer-guide/img/theme-title-area-UIIDs.png b/docs/developer-guide/img/theme-title-area-UIIDs.png deleted file mode 100644 index 5425f787945..00000000000 Binary files a/docs/developer-guide/img/theme-title-area-UIIDs.png and /dev/null differ