From: Niki Roo Date: Wed, 15 May 2019 19:50:47 +0000 (+0200) Subject: ConfigItem: remove logic from UI, improve UI X-Git-Tag: fanfix-swing-0.0.1~21^2~70 X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=9e834013f84e8797acf26f5418ae3448044ad097;p=fanfix-swing.git ConfigItem: remove logic from UI, improve UI --- diff --git a/src/be/nikiroo/utils/resources/Bundle.java b/src/be/nikiroo/utils/resources/Bundle.java index 424f1209..5932cfff 100644 --- a/src/be/nikiroo/utils/resources/Bundle.java +++ b/src/be/nikiroo/utils/resources/Bundle.java @@ -298,7 +298,7 @@ public class Bundle> { * the new colour */ public void setColor(E id, Integer color) { - setString(id, BundleHelper.fromColour(color)); + setString(id, BundleHelper.fromColor(color)); } /** diff --git a/src/be/nikiroo/utils/resources/BundleHelper.java b/src/be/nikiroo/utils/resources/BundleHelper.java index 94066d86..39c00c5c 100644 --- a/src/be/nikiroo/utils/resources/BundleHelper.java +++ b/src/be/nikiroo/utils/resources/BundleHelper.java @@ -227,7 +227,7 @@ class BundleHelper { * the ARGB colour value * @return the raw {@link String} value that correspond to it */ - static public String fromColour(int color) { + static public String fromColor(int color) { int a = (color >> 24) & 0xFF; int r = (color >> 16) & 0xFF; int g = (color >> 8) & 0xFF; diff --git a/src/be/nikiroo/utils/resources/Meta.java b/src/be/nikiroo/utils/resources/Meta.java index d50664da..a83bcca4 100644 --- a/src/be/nikiroo/utils/resources/Meta.java +++ b/src/be/nikiroo/utils/resources/Meta.java @@ -46,11 +46,22 @@ public @interface Meta { * custom String value (basically, a {@link Format#FIXED_LIST} with an * option to enter a not accounted for value). */ - COMBO_LIST + COMBO_LIST, + /** + * A list of {@link Format#STRING}s. + *

+ * The list items are separated by a comma, each surrounded by + * double-quotes, with backslashes and double-quotes escaped by a + * backslash. + *

+ * Example: "un", "deux" + */ + LIST_OF_STRINGS, } /** - * A description of this item. + * A description of this item (what it is or does, how to explain that item + * to the user). * * @return what it is */ diff --git a/src/be/nikiroo/utils/resources/MetaInfo.java b/src/be/nikiroo/utils/resources/MetaInfo.java new file mode 100644 index 00000000..3a6e71ae --- /dev/null +++ b/src/be/nikiroo/utils/resources/MetaInfo.java @@ -0,0 +1,226 @@ +package be.nikiroo.utils.resources; + +import java.util.ArrayList; +import java.util.List; + +import be.nikiroo.utils.resources.Meta.Format; + +/** + * A graphical item that reflect a configuration option from the given + * {@link Bundle}. + * + * @author niki + * + * @param + * the type of {@link Bundle} to edit + */ +public class MetaInfo> { + private final Bundle bundle; + private final E id; + + private Meta meta; + + private String value; + private List reloadListeners = new ArrayList(); + + private String name; + private String description; + + public MetaInfo(Class type, Bundle bundle, E id) { + this.bundle = bundle; + this.id = id; + + try { + this.meta = type.getDeclaredField(id.name()).getAnnotation( + Meta.class); + } catch (NoSuchFieldException e) { + } catch (SecurityException e) { + } + + // We consider that if a description bundle is used, everything is in it + + String description = null; + if (bundle.getDescriptionBundle() != null) { + description = bundle.getDescriptionBundle().getString(id); + if (description != null && description.trim().isEmpty()) { + description = null; + } + } + + if (description == null) { + description = meta.description(); + if (meta.info() != null && !meta.info().isEmpty()) { + description += "\n" + meta.info(); + } + } + + String name = id.toString(); + if (name.length() > 1) { + name = name.substring(0, 1) + name.substring(1).toLowerCase(); + name = name.replace("_", " "); + } + + this.name = name; + this.description = description; + + reload(); + } + + /** + * THe name of this item, deduced from its ID. + *

+ * In other words, it is the ID but presented in a displayable form. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * The description of this item (information to present to the user). + * + * @return the description + */ + public String getDescription() { + return description; + } + + public Format getFormat() { + return meta.format(); + } + + /** + * The value stored by this item, as a {@link String}. + * + * @return the value + */ + public String getString() { + return value; + } + + public String getDefaultString() { + return meta.def(); + } + + public Boolean getBoolean() { + return BundleHelper.parseBoolean(getString()); + } + + public Boolean getDefaultBoolean() { + return BundleHelper.parseBoolean(getDefaultString()); + } + + public Character getCharacter() { + return BundleHelper.parseCharacter(getString()); + } + + public Character getDefaultCharacter() { + return BundleHelper.parseCharacter(getDefaultString()); + } + + public Integer getInteger() { + return BundleHelper.parseInteger(getString()); + } + + public Integer getDefaultInteger() { + return BundleHelper.parseInteger(getDefaultString()); + } + + public Integer getColor() { + return BundleHelper.parseColor(getString()); + } + + public Integer getDefaultColor() { + return BundleHelper.parseColor(getDefaultString()); + } + + public List getList() { + return BundleHelper.parseList(getString()); + } + + public List getDefaultList() { + return BundleHelper.parseList(getDefaultString()); + } + + /** + * The value stored by this item, as a {@link String}. + * + * @param value + * the new value + */ + public void setString(String value) { + this.value = value; + } + + public void setBoolean(boolean value) { + setString(BundleHelper.fromBoolean(value)); + } + + public void setCharacter(char value) { + setString(BundleHelper.fromCharacter(value)); + } + + public void setInteger(int value) { + setString(BundleHelper.fromInteger(value)); + } + + public void setColor(int value) { + setString(BundleHelper.fromColor(value)); + } + + public void setList(List value) { + setString(BundleHelper.fromList(value)); + } + + /** + * Reload the value from the {@link Bundle}. + */ + public void reload() { + value = bundle.getString(id); + for (Runnable listener : reloadListeners) { + try { + listener.run(); + } catch (Exception e) { + // TODO: error management? + e.printStackTrace(); + } + } + } + + public void addReloadListener(Runnable listener) { + reloadListeners.add(listener); + } + + /** + * Save the current value to the {@link Bundle}. + */ + public void save() { + bundle.setString(id, value); + } + + /** + * Create a list of {@link MetaInfo}, one for each of the item in the given + * {@link Bundle}. + * + * @param + * the type of {@link Bundle} to edit + * @param type + * a class instance of the item type to work on + * @param bundle + * the {@link Bundle} to sort through + * + * @return the list + */ + static public > List> getItems(Class type, + Bundle bundle) { + List> list = new ArrayList>(); + for (E id : type.getEnumConstants()) { + list.add(new MetaInfo(type, bundle, id)); + } + + return list; + } + + // TODO: by groups, a-là Authors/Sources +} diff --git a/src/be/nikiroo/utils/ui/ConfigEditor.java b/src/be/nikiroo/utils/ui/ConfigEditor.java index 7bdf17a2..367396da 100644 --- a/src/be/nikiroo/utils/ui/ConfigEditor.java +++ b/src/be/nikiroo/utils/ui/ConfigEditor.java @@ -15,6 +15,7 @@ import javax.swing.JScrollPane; import javax.swing.border.EmptyBorder; import be.nikiroo.utils.resources.Bundle; +import be.nikiroo.utils.resources.MetaInfo; /** * A configuration panel for a {@link Bundle}. @@ -30,7 +31,7 @@ import be.nikiroo.utils.resources.Bundle; */ public class ConfigEditor> extends JPanel { private static final long serialVersionUID = 1L; - private List> items; + private List> items; /** * Create a new {@link ConfigEditor} for this {@link Bundle}. @@ -54,15 +55,15 @@ public class ConfigEditor> extends JPanel { main.add(new JLabel(title)); - items = ConfigItem.getItems(type, bundle); - for (ConfigItem item : items) { - main.add(item); + items = MetaInfo.getItems(type, bundle); + for (MetaInfo item : items) { + main.add(new ConfigItem(item)); } main.add(createButton("Reset", new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - for (ConfigItem item : items) { + for (MetaInfo item : items) { item.reload(); } } @@ -73,7 +74,7 @@ public class ConfigEditor> extends JPanel { public void actionPerformed(ActionEvent e) { Object snap = bundle.takeSnapshot(); bundle.reload(true); - for (ConfigItem item : items) { + for (MetaInfo item : items) { item.reload(); } bundle.reload(false); @@ -84,7 +85,7 @@ public class ConfigEditor> extends JPanel { main.add(createButton("Save", new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - for (ConfigItem item : items) { + for (MetaInfo item : items) { item.save(); } diff --git a/src/be/nikiroo/utils/ui/ConfigItem.java b/src/be/nikiroo/utils/ui/ConfigItem.java index 691c6198..beed66f5 100644 --- a/src/be/nikiroo/utils/ui/ConfigItem.java +++ b/src/be/nikiroo/utils/ui/ConfigItem.java @@ -1,17 +1,15 @@ package be.nikiroo.utils.ui; import java.awt.BorderLayout; -import java.awt.Dimension; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JLabel; +import javax.swing.JCheckBox; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import be.nikiroo.utils.resources.Bundle; -import be.nikiroo.utils.resources.Meta; +import be.nikiroo.utils.resources.Meta.Format; +import be.nikiroo.utils.resources.MetaInfo; /** * A graphical item that reflect a configuration option from the given @@ -24,92 +22,50 @@ import be.nikiroo.utils.resources.Meta; */ public class ConfigItem> extends JPanel { private static final long serialVersionUID = 1L; - private Class type; - private final Bundle bundle; - private final E id; - - private Meta meta; - private String value; - - private JTextField valueField; - - public ConfigItem(Class type, Bundle bundle, E id) { - this.type = type; - this.bundle = bundle; - this.id = id; - - try { - this.meta = type.getDeclaredField(id.name()).getAnnotation( - Meta.class); - } catch (NoSuchFieldException e) { - } catch (SecurityException e) { - } + public ConfigItem(final MetaInfo info) { this.setLayout(new BorderLayout()); this.setBorder(new EmptyBorder(2, 10, 2, 10)); - String tooltip = null; - if (bundle.getDescriptionBundle() != null) { - tooltip = bundle.getDescriptionBundle().getString(id); - if (tooltip != null && tooltip.trim().isEmpty()) { - tooltip = null; + if (info.getFormat() == Format.BOOLEAN) { + final JCheckBox field = new JCheckBox(); + field.setToolTipText(info.getDescription()); + Boolean state = info.getBoolean(); + if (state == null) { + info.getDefaultBoolean(); } - } - - String name = id.toString(); - if (name.length() > 1) { - name = name.substring(0, 1) + name.substring(1).toLowerCase(); - name = name.replace("_", " "); - } - - JLabel nameLabel = new JLabel(name); - nameLabel.setToolTipText(tooltip); - nameLabel.setPreferredSize(new Dimension(400, 0)); - this.add(nameLabel, BorderLayout.WEST); - valueField = new JTextField(); - valueField.setText(value); - - reload(); - this.add(valueField, BorderLayout.CENTER); - } - - /** - * Reload the value from the {@link Bundle}. - */ - public void reload() { - value = bundle.getString(id); - valueField.setText(value); - } - - /** - * Save the current value to the {@link Bundle}. - */ - public void save() { - value = valueField.getText(); - bundle.setString(id, value); - } + // Should not happen! + if (state == null) { + System.err + .println("No default value given for BOOLEAN parameter " + + info.getName() + ", we consider it is FALSE"); + state = false; + } - /** - * Create a list of {@link ConfigItem}, one for each of the item in the - * given {@link Bundle}. - * - * @param - * the type of {@link Bundle} to edit - * @param type - * a class instance of the item type to work on - * @param bundle - * the {@link Bundle} to sort through - * - * @return the list - */ - static public > List> getItems( - Class type, Bundle bundle) { - List> list = new ArrayList>(); - for (E id : type.getEnumConstants()) { - list.add(new ConfigItem(type, bundle, id)); + field.setSelected(state); + + info.addReloadListener(new Runnable() { + @Override + public void run() { + field.setText(info.getString()); + } + }); + + this.add(field, BorderLayout.CENTER); + } else { + final JTextField field = new JTextField(); + field.setToolTipText(info.getDescription()); + field.setText(info.getString()); + + info.addReloadListener(new Runnable() { + @Override + public void run() { + field.setText(info.getString()); + } + }); + + this.add(field, BorderLayout.CENTER); } - - return list; } }