tangled
alpha
login
or
join now
starhaven.dev
/
diorama
1
fork
atom
this repo has no description
1
fork
atom
overview
issues
pulls
pipelines
add TexturesAsset thumbnails
bates64.com
1 month ago
e19cb17f
082f17e8
+63
-68
4 changed files
expand all
collapse all
unified
split
src
main
java
app
pane
AssetsPanel.java
assets
AssetHandle.java
ui
TexArchiveAssetCellRenderer.java
TexturesAsset.java
+3
-6
src/main/java/app/pane/AssetsPanel.java
···
216
216
217
217
private JPanel createSubdirItem(String name)
218
218
{
219
219
-
JPanel panel = createItem(name, ThemedIcon.FOLDER_OPEN_24, null, () -> {
219
219
+
return createItem(name, ThemedIcon.FOLDER_OPEN_24, false, () -> {
220
220
navigateTo(currentPath + name + "/");
221
221
});
222
222
-
return panel;
223
222
}
224
223
225
224
private JPanel createAssetItem(AssetHandle asset)
226
225
{
227
227
-
JPanel panel = createItem(asset.getAssetName(), ThemedIcon.PACKAGE_24, asset, () -> {
226
226
+
JPanel panel = createItem(asset.getAssetName(), ThemedIcon.PACKAGE_24, asset.thumbnailHasCheckerboard(), () -> {
228
227
openAsset(asset);
229
228
});
230
229
···
263
262
return panel;
264
263
}
265
264
266
266
-
private JPanel createItem(String name, Icon defaultIcon, AssetHandle asset, Runnable onDoubleClick)
265
265
+
private JPanel createItem(String name, Icon defaultIcon, boolean checkerboard, Runnable onDoubleClick)
267
266
{
268
267
JPanel panel = createItemPanel();
269
269
-
270
270
-
boolean checkerboard = asset != null && asset.thumbnailHasCheckerboard();
271
268
JLabel icon = checkerboard ? new JLabel(defaultIcon) {
272
269
@Override
273
270
protected void paintComponent(Graphics g)
+4
-6
src/main/java/assets/AssetHandle.java
···
37
37
38
38
public String getAssetName()
39
39
{
40
40
-
int slash = assetPath.lastIndexOf('/');
41
41
-
if (slash >= 0)
42
42
-
return assetPath.substring(slash + 1);
43
43
-
else
44
44
-
return assetPath;
40
40
+
String name = getName();
41
41
+
int dot = name.lastIndexOf('.');
42
42
+
return dot > 0 ? name.substring(0, dot) : name;
45
43
}
46
44
47
45
public String getAssetDescription()
···
113
111
/** Upgrades a plain AssetHandle to a typed subclass based on file extension. */
114
112
public static AssetHandle upgrade(AssetHandle handle)
115
113
{
116
116
-
String name = handle.getAssetName();
114
114
+
String name = handle.getName();
117
115
if (name.endsWith(".xml")) return new MapAsset(handle);
118
116
if (name.endsWith(".png")) return new BackgroundAsset(handle);
119
117
if (name.endsWith(".json")) return new TexturesAsset(handle);
+3
-3
src/main/java/assets/ui/TexArchiveAssetCellRenderer.java
···
60
60
String mapFileName = FilenameUtils.getBaseName(bg.assetPath);
61
61
nameLabel.setText(assetDirName + " / " + mapFileName);
62
62
nameLabel.setForeground(null);
63
63
-
previewPanel1.setImage(bg.bimg1);
64
64
-
previewPanel2.setImage(bg.bimg2);
65
65
-
previewPanel3.setImage(bg.bimg3);
63
63
+
previewPanel1.setImage(bg.getPreview(0));
64
64
+
previewPanel2.setImage(bg.getPreview(1));
65
65
+
previewPanel3.setImage(bg.getPreview(2));
66
66
}
67
67
else {
68
68
nameLabel.setText("ERROR");
+53
-53
src/main/java/assets/ui/TexturesAsset.java
···
1
1
package assets.ui;
2
2
3
3
import java.awt.Graphics2D;
4
4
+
import java.awt.Image;
4
5
import java.awt.RenderingHints;
5
6
import java.awt.image.BufferedImage;
6
7
import java.io.File;
···
10
11
import java.nio.file.Path;
11
12
import java.util.ArrayList;
12
13
import java.util.Collections;
13
13
-
import java.util.Iterator;
14
14
import java.util.List;
15
15
16
16
import javax.imageio.ImageIO;
17
17
-
import javax.imageio.ImageReader;
18
18
-
import javax.imageio.stream.ImageInputStream;
19
17
20
18
import org.apache.commons.io.FilenameUtils;
21
19
···
25
23
26
24
public class TexturesAsset extends AssetHandle
27
25
{
28
28
-
public BufferedImage bimg1;
29
29
-
public BufferedImage bimg2;
30
30
-
public BufferedImage bimg3;
26
26
+
private static final int THUMB_W = THUMBNAIL_WIDTH;
27
27
+
private static final int THUMB_H = THUMBNAIL_HEIGHT;
28
28
+
private static final int GAP = 2;
29
29
+
private static final int ROW_HEIGHT = (THUMB_H - GAP) / 2; // two rows
30
30
+
31
31
+
private final List<BufferedImage> textures = new ArrayList<>();
32
32
+
33
33
+
public BufferedImage getPreview(int index)
34
34
+
{
35
35
+
return index < textures.size() ? textures.get(index) : null;
36
36
+
}
31
37
32
38
public TexturesAsset(AssetHandle asset)
33
39
{
···
41
47
42
48
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir.toPath(), "*.png")) {
43
49
for (Path file : stream) {
44
44
-
if (Files.isRegularFile(file)) {
50
50
+
if (Files.isRegularFile(file))
45
51
images.add(file.toFile());
46
46
-
}
47
52
}
48
53
}
49
54
50
50
-
// pick three textures randomly for previews
51
55
Collections.shuffle(images);
52
56
53
53
-
if (images.size() > 0) {
54
54
-
bimg1 = getPreview(images.get(0));
55
55
-
}
56
56
-
if (images.size() > 1) {
57
57
-
bimg2 = getPreview(images.get(1));
58
58
-
}
59
59
-
if (images.size() > 2) {
60
60
-
bimg3 = getPreview(images.get(2));
57
57
+
for (int i = 0; i < images.size(); i++) {
58
58
+
BufferedImage img = readImage(images.get(i));
59
59
+
if (img != null)
60
60
+
textures.add(img);
61
61
}
62
62
}
63
63
catch (IOException e) {
···
65
65
}
66
66
}
67
67
68
68
-
private int getImageSize(File imgFile) throws IOException
68
68
+
@Override
69
69
+
public boolean thumbnailHasCheckerboard()
69
70
{
70
70
-
try (ImageInputStream in = ImageIO.createImageInputStream(imgFile)) {
71
71
-
final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
72
72
-
if (readers.hasNext()) {
73
73
-
ImageReader reader = readers.next();
74
74
-
try {
75
75
-
reader.setInput(in);
76
76
-
int width = reader.getWidth(0);
77
77
-
int height = reader.getHeight(0);
78
78
-
return width * height;
79
79
-
}
80
80
-
finally {
81
81
-
reader.dispose();
82
82
-
}
83
83
-
}
84
84
-
}
85
85
-
return 0;
71
71
+
return false;
86
72
}
87
73
88
88
-
private static BufferedImage getPreview(File imgFile)
74
74
+
@Override
75
75
+
protected Image loadThumbnail()
89
76
{
90
90
-
try {
91
91
-
BufferedImage bimg = ImageIO.read(imgFile);
92
92
-
if (bimg == null)
93
93
-
return null;
77
77
+
if (textures.isEmpty())
78
78
+
return null;
79
79
+
80
80
+
var composite = new BufferedImage(THUMB_W, THUMB_H, BufferedImage.TYPE_INT_ARGB);
81
81
+
Graphics2D g = composite.createGraphics();
82
82
+
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
83
83
+
84
84
+
int x = 0;
85
85
+
int y = 0;
86
86
+
for (BufferedImage tex : textures) {
87
87
+
float scale = (float) ROW_HEIGHT / tex.getHeight();
88
88
+
int w = Math.max(1, Math.round(tex.getWidth() * scale));
89
89
+
int h = ROW_HEIGHT;
94
90
95
95
-
int targetWidth = 32;
96
96
-
int targetHeight = 32;
97
97
-
float ratio = (float) bimg.getHeight() / (float) bimg.getWidth();
98
98
-
if (ratio <= 1.0f) {
99
99
-
targetHeight = (int) Math.ceil(targetWidth * ratio);
100
100
-
}
101
101
-
else {
102
102
-
targetWidth = Math.round(targetHeight / ratio);
91
91
+
if (x + w > THUMB_W) {
92
92
+
// Wrap to next row
93
93
+
x = 0;
94
94
+
y += ROW_HEIGHT + GAP;
95
95
+
if (y + ROW_HEIGHT > THUMB_H)
96
96
+
break;
103
97
}
104
98
105
105
-
BufferedImage resized = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
106
106
-
Graphics2D g2d = resized.createGraphics();
107
107
-
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
108
108
-
g2d.drawImage(bimg, 0, 0, targetWidth, targetHeight, null);
109
109
-
g2d.dispose();
110
110
-
return resized;
99
99
+
g.drawImage(tex, x, y, w, h, null);
100
100
+
x += w + GAP;
101
101
+
}
102
102
+
103
103
+
g.dispose();
104
104
+
return composite;
105
105
+
}
106
106
+
107
107
+
private static BufferedImage readImage(File imgFile)
108
108
+
{
109
109
+
try {
110
110
+
return ImageIO.read(imgFile);
111
111
}
112
112
catch (IOException e) {
113
113
return null;