1 package be
.nikiroo
.fanfix
.reader
.tui
;
10 import be
.nikiroo
.utils
.resources
.Bundle
;
11 import be
.nikiroo
.utils
.resources
.MetaInfo
;
12 import be
.nikiroo
.utils
.ui
.ConfigItemBase
;
15 * A graphical item that reflect a configuration option from the given
18 * This graphical item can be edited, and the result will be saved back into the
19 * linked {@link MetaInfo}; you still have to save the {@link MetaInfo} should
20 * you wish to, of course.
25 * the type of {@link Bundle} to edit
27 public abstract class ConfigItem
<E
extends Enum
<E
>> extends TWidget
{
29 private final ConfigItemBase
<TWidget
, E
> base
;
32 * Prepare a new {@link ConfigItem} instance, linked to the given
39 * @param autoDirtyHandling
40 * TRUE to automatically manage the setDirty/Save operations,
41 * FALSE if you want to do it yourself via
42 * {@link ConfigItem#setDirtyItem(int)}
44 protected ConfigItem(TWidget parent
, MetaInfo
<E
> info
,
45 boolean autoDirtyHandling
) {
48 base
= new ConfigItemBase
<TWidget
, E
>(info
, autoDirtyHandling
) {
50 protected TWidget
createEmptyField(int item
) {
51 return ConfigItem
.this.createEmptyField(item
);
55 protected Object
getFromInfo(int item
) {
56 return ConfigItem
.this.getFromInfo(item
);
60 protected void setToInfo(Object value
, int item
) {
61 ConfigItem
.this.setToInfo(value
, item
);
65 protected Object
getFromField(int item
) {
66 return ConfigItem
.this.getFromField(item
);
70 protected void setToField(Object value
, int item
) {
71 ConfigItem
.this.setToField(value
, item
);
75 public TWidget
createField(int item
) {
76 TWidget field
= super.createField(item
);
84 public List
<TWidget
> reload() {
85 List
<TWidget
> removed
= base
.reload();
86 if (!removed
.isEmpty()) {
87 for (TWidget c
: removed
) {
98 * Create a new {@link ConfigItem} for the given {@link MetaInfo}.
101 * negative horisontal gap in pixel to use for the label, i.e.,
102 * the step lock sized labels will start smaller by that amount
103 * (the use case would be to align controls that start at a
104 * different horisontal position)
106 public void init(int nhgap
) {
107 if (getInfo().isArray()) {
109 int size
= getInfo().getListSize(false);
110 final TPanel pane
= new TPanel(this, 0, 0, 20, size
+ 2);
111 final TWidget label
= label(0, 0, nhgap
);
112 label
.setParent(pane
, false);
113 setHeight(pane
.getHeight());
115 for (int i
= 0; i
< size
; i
++) {
117 TWidget field
= base
.addItem(i
, null);
118 field
.setParent(pane
, false);
119 field
.setX(label
.getWidth() + 1);
124 final TButton add
= new TButton(pane
, "+", label
.getWidth() + 1,
126 TAction action
= new TAction() {
129 TWidget field
= base
.addItem(base
.getFieldsSize(), null);
130 field
.setParent(pane
, false);
131 field
.setX(label
.getWidth() + 1);
132 field
.setY(add
.getY());
133 add
.setY(add
.getY() + 1);
136 add
.setAction(action
);
138 final TWidget label
= label(0, 0, nhgap
);
140 TWidget field
= base
.createField(-1);
141 field
.setX(label
.getWidth() + 1);
142 field
.setWidth(10); // TODO
150 /** The {@link MetaInfo} linked to the field. */
151 public MetaInfo
<E
> getInfo() {
152 return base
.getInfo();
156 * Retrieve the associated graphical component that was created with
157 * {@link ConfigItemBase#createEmptyField(int)}.
160 * the item number to get for an array of values, or -1 to get
161 * the whole value (has no effect if {@link MetaInfo#isArray()}
164 * @return the graphical component
166 protected TWidget
getField(int item
) {
167 return base
.getField(item
);
171 * Manually specify that the given item is "dirty" and thus should be saved
174 * Has no effect if the class is using automatic dirty handling (see
175 * {@link ConfigItemBase#ConfigItem(MetaInfo, boolean)}).
178 * the item number to get for an array of values, or -1 to get
179 * the whole value (has no effect if {@link MetaInfo#isArray()}
182 protected void setDirtyItem(int item
) {
183 base
.setDirtyItem(item
);
187 * Check if the value changed since the last load/save into the linked
190 * Note that we consider NULL and an Empty {@link String} to be equals.
195 * the item number to get for an array of values, or -1 to get
196 * the whole value (has no effect if {@link MetaInfo#isArray()}
199 * @return TRUE if it has
201 protected boolean hasValueChanged(Object value
, int item
) {
202 return base
.hasValueChanged(value
, item
);
206 * Create an empty graphical component to be used later by
207 * {@link ConfigItem#createField(int)}.
209 * Note that {@link ConfigItem#reload(int)} will be called after it was
210 * created by {@link ConfigItem#createField(int)}.
213 * the item number to get for an array of values, or -1 to get
214 * the whole value (has no effect if {@link MetaInfo#isArray()}
217 * @return the graphical component
219 abstract protected TWidget
createEmptyField(int item
);
222 * Get the information from the {@link MetaInfo} in the subclass preferred
226 * the item number to get for an array of values, or -1 to get
227 * the whole value (has no effect if {@link MetaInfo#isArray()}
230 * @return the information in the subclass preferred format
232 abstract protected Object
getFromInfo(int item
);
235 * Set the value to the {@link MetaInfo}.
238 * the value in the subclass preferred format
240 * the item number to get for an array of values, or -1 to get
241 * the whole value (has no effect if {@link MetaInfo#isArray()}
244 abstract protected void setToInfo(Object value
, int item
);
247 * The value present in the given item's related field in the subclass
251 * the item number to get for an array of values, or -1 to get
252 * the whole value (has no effect if {@link MetaInfo#isArray()}
255 * @return the value present in the given item's related field in the
256 * subclass preferred format
258 abstract protected Object
getFromField(int item
);
261 * Set the value (in the subclass preferred format) into the field.
264 * the value in the subclass preferred format
266 * the item number to get for an array of values, or -1 to get
267 * the whole value (has no effect if {@link MetaInfo#isArray()}
270 abstract protected void setToField(Object value
, int item
);
273 * Create a label which width is constrained in lock steps.
276 * the X position of the label
278 * the Y position of the label
280 * negative horisontal gap in pixel to use for the label, i.e.,
281 * the step lock sized labels will start smaller by that amount
282 * (the use case would be to align controls that start at a
283 * different horisontal position)
287 protected TWidget
label(int x
, int y
, int nhgap
) {
288 // TODO: see Swing version for lock-step sizes
289 // TODO: see Swing version for help info-buttons
291 String lbl
= getInfo().getName();
292 return new TLabel(this, lbl
, x
, y
);
296 * Create a new {@link ConfigItem} for the given {@link MetaInfo}.
299 * the type of {@link Bundle} to edit
302 * the X position of the item
304 * the Y position of the item
306 * the parent widget to use for this one
308 * the {@link MetaInfo}
310 * negative horisontal gap in pixel to use for the label, i.e.,
311 * the step lock sized labels will start smaller by that amount
312 * (the use case would be to align controls that start at a
313 * different horisontal position)
315 * @return the new {@link ConfigItem}
317 static public <E
extends Enum
<E
>> ConfigItem
<E
> createItem(TWidget parent
,
318 int x
, int y
, MetaInfo
<E
> info
, int nhgap
) {
320 ConfigItem
<E
> configItem
;
321 switch (info
.getFormat()) {
324 // configItem = new ConfigItemBoolean<E>(info);
327 // configItem = new ConfigItemColor<E>(info);
330 // configItem = new ConfigItemBrowse<E>(info, false);
333 // configItem = new ConfigItemBrowse<E>(info, true);
336 // configItem = new ConfigItemCombobox<E>(info, true);
339 // configItem = new ConfigItemCombobox<E>(info, false);
342 // configItem = new ConfigItemInteger<E>(info);
345 // configItem = new ConfigItemPassword<E>(info);
348 // configItem = new ConfigItemLocale<E>(info);
352 configItem
= new ConfigItemString
<E
>(parent
, info
);
356 configItem
.init(nhgap
);