Skip to content
Merged
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
95 changes: 95 additions & 0 deletions .github/scripts/compare-animation-screenshots.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
BASELINE_DIR="${BASELINE_DIR:-${PROJECT_ROOT}/docs/developer-guide/img}"
STORAGE_DIR="${CN1_STORAGE_DIR:-${HOME}/.cn1}"
ARTIFACT_DIR="${1:-${PROJECT_ROOT}/docs/demos/animation-screenshot-artifacts}"

if ! command -v compare >/dev/null 2>&1; then
echo "ImageMagick 'compare' command is required." >&2
exit 2
fi

mkdir -p "${ARTIFACT_DIR}"
find "${ARTIFACT_DIR}" -mindepth 1 -delete

if [[ ! -d "${STORAGE_DIR}" ]]; then
echo "Storage directory ${STORAGE_DIR} does not exist; nothing to compare."
exit 0
fi

shopt -s nullglob
mapfile -d '' SCREENSHOTS < <(find "${STORAGE_DIR}" -type f -name '*.png' -print0)
shopt -u nullglob

if [[ ${#SCREENSHOTS[@]} -eq 0 ]]; then
echo "No screenshots found under ${STORAGE_DIR}; nothing to compare."
exit 0
fi

mismatch_count=0

for screenshot in "${SCREENSHOTS[@]}"; do
filename="$(basename "${screenshot}")"
base="${filename%.png}"

baseline=""
baseline_ext=""
for ext in png PNG jpg JPG jpeg JPEG; do
candidate="${BASELINE_DIR}/${base}.${ext}"
if [[ -f "${candidate}" ]]; then
baseline="${candidate}"
baseline_ext="${ext}"
break
fi
done

if [[ -z "${baseline}" ]]; then
echo "No baseline found for ${filename}; treating as mismatch." >&2
mismatch_count=$((mismatch_count + 1))
cp "${screenshot}" "${ARTIFACT_DIR}/${filename}"
rm -f "${screenshot}"
continue
fi

metric_file="$(mktemp)"
diff_image="${ARTIFACT_DIR}/${base}.diff.png"

set +e
compare -metric AE "${screenshot}" "${baseline}" "${diff_image}" 2>"${metric_file}"
status=$?
set -e

if [[ ${status} -eq 0 ]]; then
rm -f "${screenshot}" "${diff_image}" "${metric_file}"
echo "${filename} matches baseline; capture discarded."
continue
fi

if [[ ${status} -ne 1 ]]; then
cat "${metric_file}" >&2
rm -f "${metric_file}" "${diff_image}"
echo "ImageMagick comparison failed for ${filename}." >&2
exit ${status}
fi

mismatch_count=$((mismatch_count + 1))
metric_value="$(cat "${metric_file}")"
rm -f "${metric_file}"

cp "${screenshot}" "${ARTIFACT_DIR}/${filename}"
cp "${baseline}" "${ARTIFACT_DIR}/${base}.baseline.${baseline_ext}"
echo "${metric_value}" > "${ARTIFACT_DIR}/${base}.metric.txt"
rm -f "${screenshot}"
echo "${filename} differs from baseline; artifacts stored in ${ARTIFACT_DIR}." >&2
done

if [[ ${mismatch_count} -eq 0 ]]; then
echo "All screenshots match their baselines."
exit 0
fi

echo "${mismatch_count} screenshot(s) differ from the documented baseline." >&2
exit 1
31 changes: 31 additions & 0 deletions .github/workflows/developer-guide-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,37 @@ jobs:
cp maven/CodeNameOneBuildClient.jar "$HOME/.codenameone/CodeNameOneBuildClient.jar"
xvfb-run -a mvn -B -ntp -Dgenerate-gui-sources-done=true -pl common -am -f docs/demos/pom.xml test

- name: Install ImageMagick for screenshot comparison
if: github.event_name != 'pull_request' || steps.changes.outputs.demos == 'true'
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y --no-install-recommends imagemagick

- name: Compare animation screenshots
id: compare_animation_screenshots
if: github.event_name != 'pull_request' || steps.changes.outputs.demos == 'true'
continue-on-error: true
run: |
set -euo pipefail
ARTIFACT_DIR="build/developer-guide/animation-screenshots"
mkdir -p "${ARTIFACT_DIR}"
.github/scripts/compare-animation-screenshots.sh "${ARTIFACT_DIR}"

- name: Upload animation screenshot mismatches
if: steps.compare_animation_screenshots.outcome == 'failure'
uses: actions/upload-artifact@v4
with:
name: developer-guide-animation-screenshots
path: build/developer-guide/animation-screenshots
if-no-files-found: warn

- name: Fail when animation screenshots differ
if: steps.compare_animation_screenshots.outcome == 'failure'
run: |
echo "Animation demo screenshots differ from developer guide assets." >&2
exit 1

- name: Determine publication metadata
run: |
set -euo pipefail
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
package com.codenameone.developerguide;

import com.codenameone.developerguide.animations.AnimationManagerDemo;
import com.codenameone.developerguide.animations.AnimationSynchronicityDemo;
import com.codenameone.developerguide.animations.BubbleTransitionDemo;
import com.codenameone.developerguide.animations.HiddenComponentDemo;
import com.codenameone.developerguide.animations.HierarchyAnimationDemo;
import com.codenameone.developerguide.animations.LayoutAnimationsDemo;
import com.codenameone.developerguide.animations.LowLevelAnimationDemo;
import com.codenameone.developerguide.animations.MorphTransitionDemo;
import com.codenameone.developerguide.animations.ReplaceTransitionDemo;
import com.codenameone.developerguide.animations.SlideTransitionsDemo;
import com.codenameone.developerguide.animations.SwipeBackSupportDemo;
import com.codenameone.developerguide.animations.UnlayoutAnimationsDemo;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand All @@ -10,8 +23,18 @@
public final class DemoRegistry {
private static final List<Demo> DEMOS = Collections.unmodifiableList(
Arrays.asList(
new HelloWorldDemo(),
new CounterDemo()
new LayoutAnimationsDemo(),
new UnlayoutAnimationsDemo(),
new HiddenComponentDemo(),
new AnimationSynchronicityDemo(),
new HierarchyAnimationDemo(),
new AnimationManagerDemo(),
new LowLevelAnimationDemo(),
new ReplaceTransitionDemo(),
new SlideTransitionsDemo(),
new BubbleTransitionDemo(),
new MorphTransitionDemo(),
new SwipeBackSupportDemo()
)
);

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.codenameone.developerguide.animations;

import com.codename1.ui.Form;
import com.codename1.ui.Toolbar;

/**
* Utility helpers shared by the animation demos.
*/
final class AnimationDemoUtil {
private AnimationDemoUtil() {
}

static void show(Form form, Form parent) {
if (parent != null) {
Toolbar toolbar = form.getToolbar();
toolbar.setBackCommand(toolbar.addCommandToLeftBar("Back", null, e -> parent.showBack()));
}
form.show();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.codenameone.developerguide.animations;

import com.codename1.ui.Button;
import com.codename1.ui.Container;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BoxLayout;
import com.codenameone.developerguide.Demo;

/**
* Demonstrates interaction with the AnimationManager.
*/
public class AnimationManagerDemo implements Demo {
@Override
public String getTitle() {
return "Animation Manager";
}

@Override
public String getDescription() {
return "Shows how AnimationManager queues operations.";
}

@Override
public void show(Form parent) {
Form hi = new Form("Animation Manager", BoxLayout.y());
Container cnt = new Container(BoxLayout.y());
Button myButton = new Button("Animated");
cnt.add(myButton);
hi.add(cnt);
AnimationDemoUtil.show(hi, parent);
// Methods below exist only so their code can be included in the guide.
}

private void demoProblem(Container cnt, Button myButton) {
// tag::animationManagerProblem[]
cnt.add(myButton);
int componentCount = cnt.getComponentCount();
cnt.animateLayout(300);
cnt.removeComponent(myButton);
if(componentCount == cnt.getComponentCount()) {
// this will happen...
}
// end::animationManagerProblem[]
}

private void demoWait(Container cnt, Button myButton) {
// tag::animationManagerWait[]
cnt.add(myButton);
int componentCount = cnt.getComponentCount();
cnt.animateLayoutAndWait(300);
cnt.removeComponent(myButton);
if(componentCount == cnt.getComponentCount()) {
// this probably won't happen...
}
// end::animationManagerWait[]
}

private void demoFlush(Container cnt, Button myButton) {
// tag::animationManagerFlush[]
cnt.add(myButton);
int componentCount = cnt.getComponentCount();
cnt.animateLayout(300);
cnt.getAnimationManager().flushAnimation(() -> {
cnt.removeComponent(myButton);
if(componentCount == cnt.getComponentCount()) {
// this shouldn't happen...
}
});
// end::animationManagerFlush[]
}
}
Loading