ProgressView spinner theming
- New SpinnerSettings which integrates with ThemeSettings - Support infra around spinner theming - Relates #995
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.shell.style.FigureSettings;
|
||||
import org.springframework.shell.style.SpinnerSettings;
|
||||
import org.springframework.shell.style.StyleSettings;
|
||||
import org.springframework.shell.style.TemplateExecutor;
|
||||
import org.springframework.shell.style.Theme;
|
||||
@@ -90,7 +91,7 @@ public class ThemingAutoConfigurationTests {
|
||||
|
||||
static class MyThemeSettings extends ThemeSettings {
|
||||
MyThemeSettings() {
|
||||
super(StyleSettings.defaults(), FigureSettings.defaults());
|
||||
super(StyleSettings.defaults(), FigureSettings.defaults(), SpinnerSettings.defaults());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,4 +145,29 @@ public abstract class AbstractControl implements Control {
|
||||
return getThemeResolvedValues(tag).map(ResolvedValues::background).orElse(fallbackColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve {@link Spinner} using existing {@link ThemeResolver} and {@code theme name}.
|
||||
* {@code defaultSpinner} is used if it's not {@code null}. {@code fallbackSpinner} is
|
||||
* used if theme resolver cannot be used.
|
||||
*
|
||||
* @param tag the spinner tag to use
|
||||
* @param defaultSpinner the default spinner to use
|
||||
* @param fallbackSpinner the fallback spinner to use
|
||||
* @return resolved spinner
|
||||
*/
|
||||
protected Spinner resolveThemeSpinner(String tag, Spinner defaultSpinner, Spinner fallbackSpinner) {
|
||||
if (defaultSpinner != null) {
|
||||
return defaultSpinner;
|
||||
}
|
||||
Spinner spinner = null;
|
||||
ThemeResolver themeResolver = getThemeResolver();
|
||||
if (themeResolver != null) {
|
||||
spinner = getThemeResolver().resolveSpinnerTag(tag);
|
||||
}
|
||||
if (spinner == null) {
|
||||
spinner = fallbackSpinner;
|
||||
}
|
||||
return spinner;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.shell.component.view.control.cell.TextCell;
|
||||
import org.springframework.shell.component.view.screen.Screen;
|
||||
import org.springframework.shell.geom.HorizontalAlign;
|
||||
import org.springframework.shell.geom.Rectangle;
|
||||
import org.springframework.shell.style.SpinnerSettings;
|
||||
import org.springframework.shell.style.ThemeResolver;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -75,10 +76,10 @@ public class ProgressView extends BoxView {
|
||||
TextCell<Context> cell = TextCell.of(item, ctx -> {
|
||||
int frame = 0;
|
||||
|
||||
Spinner spin = ctx.getSpinner();
|
||||
if (spin == null) {
|
||||
spin = Spinner.of(Spinner.LINE1, 130);
|
||||
}
|
||||
// via view setting, then via theming, then fallback default
|
||||
Spinner spin = ctx.resolveThemeSpinner(SpinnerSettings.TAG_DOT, ctx.getSpinner(),
|
||||
Spinner.of(Spinner.LINE1, 130));
|
||||
|
||||
if (ctx.getState().running()) {
|
||||
// we know start time and current update time,
|
||||
// calculate elapsed time "frame" to pick rolling
|
||||
@@ -343,6 +344,11 @@ public class ProgressView extends BoxView {
|
||||
return ProgressView.this.resolveThemeStyle(tag, defaultStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spinner resolveThemeSpinner(String tag, Spinner defaultSpinner, Spinner fallbackSpinner) {
|
||||
return ProgressView.this.resolveThemeSpinner(tag, defaultSpinner, fallbackSpinner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spinner getSpinner() {
|
||||
return ProgressView.this.spinner;
|
||||
@@ -393,6 +399,8 @@ public class ProgressView extends BoxView {
|
||||
*/
|
||||
int resolveThemeStyle(String tag, int defaultStyle);
|
||||
|
||||
Spinner resolveThemeSpinner(String tag, Spinner defaultSpinner, Spinner fallbackSpinner);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.shell.style;
|
||||
|
||||
import org.springframework.shell.component.view.control.Spinner;
|
||||
|
||||
/**
|
||||
* Base class defining a settings for spinners.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public abstract class SpinnerSettings {
|
||||
|
||||
/**
|
||||
* Spinner with line characters.
|
||||
*/
|
||||
public final static String TAG_LINE = "line";
|
||||
|
||||
/**
|
||||
* Spinner with dot characters.
|
||||
*/
|
||||
public final static String TAG_DOT = "dot";
|
||||
|
||||
public Spinner line() {
|
||||
return Spinner.of(Spinner.LINE1, 130);
|
||||
}
|
||||
|
||||
public Spinner dot() {
|
||||
return Spinner.of(Spinner.DOTS1, 80);
|
||||
}
|
||||
|
||||
public Spinner resolveTag(String tag) {
|
||||
switch (tag) {
|
||||
case TAG_LINE:
|
||||
return line();
|
||||
case TAG_DOT:
|
||||
return dot();
|
||||
}
|
||||
throw new IllegalArgumentException(String.format("Unknown tag '%s'", tag));
|
||||
}
|
||||
|
||||
public static String[] tags() {
|
||||
return new String[] {
|
||||
TAG_LINE,
|
||||
TAG_DOT,
|
||||
};
|
||||
}
|
||||
|
||||
public static SpinnerSettings defaults() {
|
||||
return new DefaultSpinnerSettings();
|
||||
}
|
||||
|
||||
public static SpinnerSettings dump() {
|
||||
return new DumpSpinnerSettings();
|
||||
}
|
||||
|
||||
private static class DefaultSpinnerSettings extends SpinnerSettings {
|
||||
}
|
||||
|
||||
private static class DumpSpinnerSettings extends SpinnerSettings {
|
||||
|
||||
@Override
|
||||
public Spinner dot() {
|
||||
return Spinner.of(Spinner.DOTS14, 200);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022-2023 the original author or authors.
|
||||
* Copyright 2022-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import org.jline.utils.AttributedString;
|
||||
import org.jline.utils.AttributedStyle;
|
||||
import org.jline.utils.Colors;
|
||||
|
||||
import org.springframework.shell.component.view.control.Spinner;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -141,6 +142,16 @@ public class ThemeResolver {
|
||||
return theme.getSettings().figures().resolveTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve spinner from a tag with activated theme.
|
||||
*
|
||||
* @param tag the tag
|
||||
* @return a spinner
|
||||
*/
|
||||
public Spinner resolveSpinnerTag(String tag) {
|
||||
return theme.getSettings().spinners().resolveTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve {@link AttributedStyle} from a {@code spec}.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
* Copyright 2022-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ public abstract class ThemeSettings {
|
||||
|
||||
private StyleSettings styleSettings;
|
||||
private FigureSettings figureSettings;
|
||||
private SpinnerSettings spinnerSettings;
|
||||
|
||||
/**
|
||||
* Creates theme settings with dump styles and figures.
|
||||
@@ -32,6 +33,15 @@ public abstract class ThemeSettings {
|
||||
this(StyleSettings.dump(), FigureSettings.dump());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates theme settings with styles.
|
||||
*
|
||||
* @param styleSettings style settings
|
||||
*/
|
||||
public ThemeSettings(StyleSettings styleSettings) {
|
||||
this(styleSettings, FigureSettings.dump(), SpinnerSettings.dump());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates theme settings with styles and figures.
|
||||
*
|
||||
@@ -39,8 +49,20 @@ public abstract class ThemeSettings {
|
||||
* @param figureSettings figure settings
|
||||
*/
|
||||
public ThemeSettings(StyleSettings styleSettings, FigureSettings figureSettings) {
|
||||
this(styleSettings, figureSettings, SpinnerSettings.dump());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates theme settings with styles, figures and spinners.
|
||||
*
|
||||
* @param styleSettings style settings
|
||||
* @param figureSettings figure settings
|
||||
* @param spinnerSettings spinner settings
|
||||
*/
|
||||
public ThemeSettings(StyleSettings styleSettings, FigureSettings figureSettings, SpinnerSettings spinnerSettings) {
|
||||
this.styleSettings = styleSettings;
|
||||
this.figureSettings = figureSettings;
|
||||
this.spinnerSettings = spinnerSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,13 +83,22 @@ public abstract class ThemeSettings {
|
||||
return this.figureSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link SpinnerSettings}.
|
||||
*
|
||||
* @return spinner settings
|
||||
*/
|
||||
public SpinnerSettings spinners() {
|
||||
return this.spinnerSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a default theme settings.
|
||||
*
|
||||
* @return default theme settings
|
||||
*/
|
||||
public static ThemeSettings defaults() {
|
||||
return new DefaultThemeSettings(StyleSettings.defaults(), FigureSettings.defaults());
|
||||
return new DefaultThemeSettings(StyleSettings.defaults(), FigureSettings.defaults(), SpinnerSettings.defaults());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,8 +116,8 @@ public abstract class ThemeSettings {
|
||||
super();
|
||||
}
|
||||
|
||||
DefaultThemeSettings(StyleSettings styleSettings, FigureSettings figureSettings) {
|
||||
super(styleSettings, figureSettings);
|
||||
DefaultThemeSettings(StyleSettings styleSettings, FigureSettings figureSettings, SpinnerSettings spinnerSettings) {
|
||||
super(styleSettings, figureSettings, spinnerSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,8 @@ public class ComponentUiCommands extends AbstractShellComponent {
|
||||
|
||||
@Command(command = "componentui progress2")
|
||||
public void progress2() {
|
||||
ProgressView view = new ProgressView(0, 100, ProgressViewItem.ofText(10, HorizontalAlign.LEFT),
|
||||
ProgressView view = new ProgressView(0, 100,
|
||||
ProgressViewItem.ofText(10, HorizontalAlign.LEFT),
|
||||
ProgressViewItem.ofSpinner(3, HorizontalAlign.LEFT),
|
||||
ProgressViewItem.ofPercent(0, HorizontalAlign.RIGHT));
|
||||
view.setDescription("name");
|
||||
@@ -154,4 +155,15 @@ public class ComponentUiCommands extends AbstractShellComponent {
|
||||
runProgress(view);
|
||||
}
|
||||
|
||||
@Command(command = "componentui progress4")
|
||||
public void progress4() {
|
||||
ProgressView view = new ProgressView();
|
||||
view.setDescription("name");
|
||||
view.setRect(0, 0, 20, 1);
|
||||
view.setThemeResolver(getThemeResolver());
|
||||
view.start();
|
||||
|
||||
runProgress(view);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user