Skip to content

Commit cb3f405

Browse files
Refactor icon parsing and rendering in EnumIconImage and Icons classes for improved functionality and clarity
1 parent 66415c4 commit cb3f405

File tree

3 files changed

+28
-134
lines changed

3 files changed

+28
-134
lines changed

platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/Icons.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,19 +230,20 @@ public static List<String> parseIconNames(String names) {
230230
* Icons.parseIconName(""); // Returns: null
231231
* Icons.parseIconName(" "); // Returns: null
232232
* }</pre>
233-
*
234233
* @see IconName
235234
* @see #parseIconNames(String)
236235
*/
237236
public static IconName parseIconName(String name) {
238237

239238
if (name == null || name.isBlank()) {
240-
return null;
239+
return new IconName(null, Collections.emptyList());
241240
}
242-
String[] parts = name.split("\\|");
243-
if (parts.length == 0) {
244-
return null;
241+
242+
if (!name.contains("|")) {
243+
return new IconName(name.trim(), Collections.emptyList());
245244
}
245+
246+
String[] parts = name.split("\\|");
246247
String iconName = parts[0].trim();
247248
List<String> classes = Collections.emptyList();
248249
if (parts.length > 1) {

platform/ui/zk/src/main/java/tools/dynamia/zk/ui/EnumIconImage.java

Lines changed: 11 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -21,134 +21,58 @@
2121
import org.zkoss.zul.Image;
2222
import org.zkoss.zul.Label;
2323
import org.zkoss.zul.Span;
24-
import tools.dynamia.ui.icons.Icon;
25-
import tools.dynamia.ui.icons.IconSize;
26-
import tools.dynamia.ui.icons.IconType;
27-
import tools.dynamia.ui.icons.IconsTheme;
24+
import tools.dynamia.ui.icons.*;
2825
import tools.dynamia.zk.BindingComponentIndex;
2926
import tools.dynamia.zk.ComponentAliasIndex;
3027
import tools.dynamia.zk.util.ZKUtil;
3128

32-
/**
33-
* A ZK component that displays an icon representation for enum values.
34-
* This component extends Span and provides a visual way to render enum constants
35-
* using icons instead of plain text. Each enum ordinal can be mapped to a specific icon name.
36-
*
37-
* <p>The component supports both image-based and font-based icons through the IconsTheme system.
38-
* If no icon mapping is found for a given enum value, it falls back to displaying the enum name as text.</p>
39-
*
40-
* <p>Example usage in ZUL:</p>
41-
* <pre>{@code
42-
* <enumIconImage value="@bind(vm.status)"
43-
* iconsNames="check-circle,clock,times-circle"
44-
* size="LARGE"/>
45-
* }</pre>
46-
*
47-
* <p>This component is registered in both ComponentAliasIndex and BindingComponentIndex
48-
* for easy integration with ZK's data binding system.</p>
49-
*
50-
* @see IconsTheme
51-
* @see IconSize
52-
* @see LoadableOnly
53-
*/
5429
public class EnumIconImage extends Span implements LoadableOnly {
5530

5631
/**
57-
* Serial version UID for serialization compatibility.
32+
*
5833
*/
5934
private static final long serialVersionUID = -5975771607086380537L;
6035

61-
/**
62-
* Static initializer block that registers this component in the framework's index systems.
63-
* Adds the component to ComponentAliasIndex for alias resolution and to BindingComponentIndex
64-
* for data binding support on the "value" property.
65-
*/
6636
static {
6737
ComponentAliasIndex.getInstance().add(EnumIconImage.class);
6838
BindingComponentIndex.getInstance().put("value", EnumIconImage.class);
6939
}
7040

71-
/**
72-
* The size of the icon to be displayed.
73-
*/
7441
private IconSize size = IconSize.NORMAL;
75-
76-
/**
77-
* The enum value to be displayed as an icon.
78-
*/
7942
private Enum value;
80-
81-
/**
82-
* Array of icon names mapped to enum ordinals.
83-
* Each position in the array corresponds to an enum ordinal value.
84-
*/
8543
private String[] iconsNames;
8644

87-
/**
88-
* Sets the value to be displayed as an icon.
89-
* This method accepts an Object parameter but only processes Enum values.
90-
* Non-enum values are ignored.
91-
*
92-
* @param value the enum value to display. If not an Enum instance, the method does nothing
93-
*
94-
* Example:
95-
* <pre>{@code
96-
* EnumIconImage iconImage = new EnumIconImage();
97-
* iconImage.setValue(Status.ACTIVE);
98-
* }</pre>
99-
*/
10045
public void setValue(Object value) {
10146
if (value instanceof Enum) {
10247
this.value = (Enum) value;
10348
render();
10449
}
10550
}
10651

107-
/**
108-
* Renders the icon representation of the current enum value.
109-
* This method clears existing children and creates the appropriate component
110-
* based on the icon type (Image or font-based icon). If no icon mapping exists,
111-
* it displays the enum name as a Label.
112-
*
113-
* <p>The rendering process:</p>
114-
* <ul>
115-
* <li>Clears all existing child components</li>
116-
* <li>Retrieves the icon name mapped to the enum's ordinal</li>
117-
* <li>Creates an Image component for image-based icons</li>
118-
* <li>Creates an I (italic) component for font-based icons</li>
119-
* <li>Falls back to a Label with the enum name if no icon is found</li>
120-
* </ul>
121-
*/
12252
private void render() {
12353
getChildren().clear();
12454
if (value != null) {
12555
setTooltiptext(null);
12656
String iconName = getIconName();
12757
if (iconName != null) {
128-
Icon icon = IconsTheme.get().getIcon(iconName);
58+
IconName iconNameObj = Icons.parseIconName(iconName);
59+
Icon icon = IconsTheme.get().getIcon(iconNameObj.name());
12960
setTooltiptext(value.name());
13061
if (icon.getType() == IconType.IMAGE) {
13162
Image image = new Image();
13263
image.setParent(this);
133-
ZKUtil.configureComponentIcon(icon, image, size);
64+
ZKUtil.configureComponentIcon(icon, image, size, iconNameObj.classes());
13465
} else {
13566
I i = new I();
13667
i.setParent(this);
137-
ZKUtil.configureComponentIcon(icon, i, size);
68+
ZKUtil.configureComponentIcon(icon, i, size, iconNameObj.classes());
13869
}
13970
} else {
14071
appendChild(new Label(value.name()));
14172
}
14273
}
14374
}
14475

145-
/**
146-
* Retrieves the icon name mapped to the current enum value's ordinal.
147-
* Returns null if the value is null, the iconsNames array is not set,
148-
* or if the ordinal is out of bounds.
149-
*
150-
* @return the icon name corresponding to the enum's ordinal position, or null if not found
151-
*/
15276
private String getIconName() {
15377
try {
15478
if (value != null) {
@@ -161,65 +85,26 @@ private String getIconName() {
16185
return null;
16286
}
16387

164-
/**
165-
* Gets the current icon size.
166-
*
167-
* @return the size of the icon
168-
*/
16988
public IconSize getSize() {
17089
return size;
17190
}
17291

173-
/**
174-
* Sets the icon size.
175-
*
176-
* @param size the desired icon size
177-
*/
17892
public void setSize(IconSize size) {
17993
this.size = size;
18094
}
18195

182-
/**
183-
* Gets the current enum value being displayed.
184-
*
185-
* @return the enum value, or null if not set
186-
*/
18796
public Enum getValue() {
18897
return value;
18998
}
19099

191-
/**
192-
* Sets the icon size using a string representation.
193-
* The string is converted to uppercase and parsed as an IconSize enum value.
194-
*
195-
* @param size the icon size as a string (e.g., "small", "normal", "large")
196-
* @throws IllegalArgumentException if the size string does not match any IconSize value
197-
*/
198100
public void setSize(String size) {
199101
setSize(IconSize.valueOf(size.toUpperCase()));
200102
}
201103

202-
/**
203-
* Gets the array of icon names mapped to enum ordinals.
204-
*
205-
* @return the array of icon names
206-
*/
207104
public String[] getIconsNames() {
208105
return iconsNames;
209106
}
210107

211-
/**
212-
* Sets the array of icon names and triggers a re-render of the component.
213-
* Each position in the array corresponds to an enum ordinal value.
214-
*
215-
* @param iconsNames array of icon names to map to enum ordinals
216-
*
217-
* Example:
218-
* <pre>{@code
219-
* String[] icons = {"check", "clock", "times"};
220-
* iconImage.setIconsNamesValues(icons);
221-
* }</pre>
222-
*/
223108
public void setIconsNamesValues(String[] iconsNames) {
224109
this.iconsNames = iconsNames;
225110
render();
@@ -230,11 +115,11 @@ public void setIconsNamesValues(String[] iconsNames) {
230115
* Spaces are automatically removed from the input string.
231116
*
232117
* @param iconsNames comma-separated string of icon names (e.g., "check,clock,times")
233-
*
234-
* Example:
235-
* <pre>{@code
236-
* iconImage.setIconsNames("check-circle, clock, times-circle");
237-
* }</pre>
118+
* <p>
119+
* Example:
120+
* <pre>{@code
121+
* iconImage.setIconsNames("check-circle, clock, times-circle");
122+
* }</pre>
238123
*/
239124
public void setIconsNames(String iconsNames) {
240125
if (iconsNames != null) {

platform/ui/zk/src/main/java/tools/dynamia/zk/util/ZKUtil.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -830,16 +830,24 @@ public static void configureComponentIcon(Icon icon, Component component, IconSi
830830
image.setSrc(realPath);
831831
}
832832

833-
if (extraClasses != null && !extraClasses.isEmpty() && component instanceof HtmlBasedComponent hcomp) {
834-
extraClasses.forEach(hcomp::addSclass);
833+
if (extraClasses != null && !extraClasses.isEmpty()) {
834+
if (component instanceof HtmlBasedComponent hcomp) {
835+
extraClasses.forEach(hcomp::addSclass);
836+
} else if (component instanceof AbstractTag tag) {
837+
if (tag.getSclass() != null) {
838+
tag.setSclass(tag.getSclass() + " " + String.join(" ", extraClasses));
839+
} else {
840+
tag.setSclass(String.join(" ", extraClasses));
841+
}
842+
}
835843
}
836844
}
837845

838846
/**
839847
* Configures an icon for a component using an icon name from the current theme.
840848
* Resolves the icon from {@link IconsTheme} and applies it to the component.
841849
*
842-
* @param icon the icon name or identifier
850+
* @param icon the icon name or identifier
843851
* @param component the component to apply the icon to
844852
* @param size the desired icon size
845853
*/

0 commit comments

Comments
 (0)