1 package be
.nikiroo
.fanfix
.reader
.ui
;
4 import java
.awt
.Graphics
;
5 import java
.awt
.Graphics2D
;
6 import java
.awt
.Polygon
;
7 import java
.awt
.Rectangle
;
8 import java
.awt
.image
.BufferedImage
;
9 import java
.io
.ByteArrayInputStream
;
10 import java
.io
.ByteArrayOutputStream
;
11 import java
.io
.IOException
;
12 import java
.io
.InputStream
;
13 import java
.net
.MalformedURLException
;
15 import javax
.imageio
.ImageIO
;
16 import javax
.swing
.ImageIcon
;
18 import be
.nikiroo
.fanfix
.Instance
;
19 import be
.nikiroo
.fanfix
.data
.MetaData
;
20 import be
.nikiroo
.fanfix
.data
.Story
;
21 import be
.nikiroo
.fanfix
.library
.BasicLibrary
;
22 import be
.nikiroo
.utils
.Image
;
23 import be
.nikiroo
.utils
.ui
.ImageUtilsAwt
;
24 import be
.nikiroo
.utils
.ui
.UIUtils
;
27 * This class can create a cover icon ready to use for the graphical
32 class GuiReaderCoverImager
{
34 // TODO: export some of the configuration options?
35 private static final int COVER_WIDTH
= 100;
36 private static final int COVER_HEIGHT
= 150;
37 private static final int SPINE_WIDTH
= 5;
38 private static final int SPINE_HEIGHT
= 5;
39 private static final int HOFFSET
= 20;
40 private static final Color SPINE_COLOR_BOTTOM
= new Color(180, 180, 180);
41 private static final Color SPINE_COLOR_RIGHT
= new Color(100, 100, 100);
42 private static final Color BORDER
= Color
.black
;
44 public static final int TEXT_HEIGHT
= 50;
45 public static final int TEXT_WIDTH
= COVER_WIDTH
+ 40;
50 * Draw a partially transparent overlay if needed depending upon the
51 * selection and mouse-hover states on top of the normal component, as well
52 * as a possible "cached" icon if the item is cached.
55 * the {@link Graphics} to paint onto
57 * draw an enabled overlay
59 * draw a selected overlay
61 * draw a hovered overlay
63 * draw a cached overlay
65 static public void paintOverlay(Graphics g
, boolean enabled
,
66 boolean selected
, boolean hovered
, boolean cached
) {
67 Rectangle clip
= g
.getClipBounds();
68 if (clip
.getWidth() <= 0 || clip
.getHeight() <= 0) {
74 int xOffset
= (TEXT_WIDTH
- COVER_WIDTH
) - 1;
75 int yOffset
= HOFFSET
;
80 g
.drawRect(xOffset
, yOffset
, COVER_WIDTH
, COVER_HEIGHT
);
87 int[] xs
= new int[] { xOffset
, xOffset
+ SPINE_WIDTH
,
88 xOffset
+ w
+ SPINE_WIDTH
, xOffset
+ w
};
89 int[] ys
= new int[] { yOffset
+ h
, yOffset
+ h
+ SPINE_HEIGHT
,
90 yOffset
+ h
+ SPINE_HEIGHT
, yOffset
+ h
};
91 g
.setColor(SPINE_COLOR_BOTTOM
);
92 g
.fillPolygon(new Polygon(xs
, ys
, xs
.length
));
93 xs
= new int[] { xOffset
+ w
, xOffset
+ w
+ SPINE_WIDTH
,
94 xOffset
+ w
+ SPINE_WIDTH
, xOffset
+ w
};
95 ys
= new int[] { yOffset
, yOffset
+ SPINE_HEIGHT
,
96 yOffset
+ h
+ SPINE_HEIGHT
, yOffset
+ h
};
97 g
.setColor(SPINE_COLOR_RIGHT
);
98 g
.fillPolygon(new Polygon(xs
, ys
, xs
.length
));
100 Color color
= new Color(255, 255, 255, 0);
102 } else if (selected
&& !hovered
) {
103 color
= new Color(80, 80, 100, 40);
104 } else if (!selected
&& hovered
) {
105 color
= new Color(230, 230, 255, 100);
106 } else if (selected
&& hovered
) {
107 color
= new Color(200, 200, 255, 100);
111 g
.fillRect(clip
.x
, clip
.y
, clip
.width
, clip
.height
);
114 UIUtils
.drawEllipse3D(g
, Color
.green
.darker(), COVER_WIDTH
115 + HOFFSET
+ 30, 10, 20, 20);
120 * Generate a cover icon based upon the given {@link MetaData}.
123 * the library the meta comes from
125 * the {@link MetaData}
129 static public ImageIcon
generateCoverIcon(BasicLibrary lib
, MetaData meta
) {
130 BufferedImage resizedImage
= null;
131 String id
= getIconId(meta
);
133 InputStream in
= Instance
.getCache().getFromCache(id
);
136 resizedImage
= ImageUtilsAwt
.fromImage(new Image(in
));
139 } catch (IOException e
) {
140 Instance
.getTraceHandler().error(e
);
144 if (resizedImage
== null) {
147 if (meta
.getLuid() != null) {
148 cover
= lib
.getCover(meta
.getLuid());
151 cover
= lib
.getSourceCover(meta
.getSource());
154 resizedImage
= new BufferedImage(SPINE_WIDTH
+ COVER_WIDTH
,
155 SPINE_HEIGHT
+ COVER_HEIGHT
+ HOFFSET
,
156 BufferedImage
.TYPE_4BYTE_ABGR
);
157 Graphics2D g
= resizedImage
.createGraphics();
158 g
.setColor(Color
.white
);
159 g
.fillRect(0, HOFFSET
, COVER_WIDTH
, COVER_HEIGHT
);
161 BufferedImage coverb
= ImageUtilsAwt
.fromImage(cover
);
162 g
.drawImage(coverb
, 0, HOFFSET
, COVER_WIDTH
, COVER_HEIGHT
,
165 g
.setColor(Color
.black
);
166 g
.drawLine(0, HOFFSET
, COVER_WIDTH
, HOFFSET
+ COVER_HEIGHT
);
167 g
.drawLine(COVER_WIDTH
, HOFFSET
, 0, HOFFSET
+ COVER_HEIGHT
);
172 ByteArrayOutputStream out
= new ByteArrayOutputStream();
173 ImageIO
.write(resizedImage
, "png", out
);
174 byte[] imageBytes
= out
.toByteArray();
175 in
= new ByteArrayInputStream(imageBytes
);
176 Instance
.getCache().addToCache(in
, id
);
180 } catch (MalformedURLException e
) {
181 Instance
.getTraceHandler().error(e
);
182 } catch (IOException e
) {
183 Instance
.getTraceHandler().error(e
);
187 return new ImageIcon(resizedImage
);
191 * Manually clear the icon set for this item.
194 * the meta of the story or source (if luid is null)
196 static public void clearIcon(MetaData meta
) {
197 String id
= getIconId(meta
);
198 Instance
.getCache().removeFromCache(id
);
202 * Get a unique ID from this meta (note that if the luid is null, it is
203 * considered a source and not a {@link Story}).
207 * @return the unique ID
209 static private String
getIconId(MetaData meta
) {
212 String key
= meta
.getUuid();
213 if (meta
.getLuid() == null) {
214 // a fake meta (== a source)
215 key
= "source_" + meta
.getSource();
218 id
= key
+ ".thumb_" + SPINE_WIDTH
+ "x" + COVER_WIDTH
+ "+"
219 + SPINE_HEIGHT
+ "+" + COVER_HEIGHT
+ "@" + HOFFSET
;