Fix CBZ importer, improve GUI
[fanfix.git] / src / be / nikiroo / fanfix / reader / LocalReaderBook.java
1 package be.nikiroo.fanfix.reader;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.Rectangle;
8 import java.awt.event.MouseEvent;
9 import java.awt.event.MouseListener;
10 import java.awt.image.BufferedImage;
11 import java.util.ArrayList;
12 import java.util.Date;
13 import java.util.EventListener;
14 import java.util.List;
15
16 import javax.swing.ImageIcon;
17 import javax.swing.JLabel;
18 import javax.swing.JPanel;
19 import javax.swing.JTextArea;
20
21 import be.nikiroo.fanfix.data.MetaData;
22
23 /**
24 * A book item presented in a {@link LocalReaderFrame}.
25 *
26 * @author niki
27 */
28 class LocalReaderBook extends JPanel {
29 /**
30 * Action on a book item.
31 *
32 * @author niki
33 */
34 interface BookActionListner extends EventListener {
35 /**
36 * The book was selected (single click).
37 *
38 * @param book
39 * the {@link LocalReaderBook} itself
40 */
41 public void select(LocalReaderBook book);
42
43 /**
44 * The book was double-clicked.
45 *
46 * @param book
47 * the {@link LocalReaderBook} itself
48 */
49 public void action(LocalReaderBook book);
50 }
51
52 private static final long serialVersionUID = 1L;
53 private JLabel icon;
54 private JTextArea title;
55 private JTextArea author;
56 private boolean selected;
57 private boolean hovered;
58 private Date lastClick;
59 private long doubleClickDelay = 200; // in ms
60 private List<BookActionListner> listeners;
61
62 public LocalReaderBook(MetaData meta) {
63 if (meta.getCover() != null) {
64 BufferedImage resizedImage = new BufferedImage(100, 150,
65 BufferedImage.TYPE_4BYTE_ABGR);
66 Graphics2D g = resizedImage.createGraphics();
67 g.drawImage(meta.getCover(), 0, 0, 100, 150, null);
68 g.dispose();
69
70 icon = new JLabel(new ImageIcon(resizedImage));
71 } else {
72 icon = new JLabel(" [ no cover ] ");
73 }
74
75 title = new JTextArea(meta.getTitle());
76 title.setWrapStyleWord(true);
77 title.setLineWrap(true);
78 title.setEditable(false);
79 title.setBackground(new Color(0, true));
80 author = new JTextArea("by " + meta.getAuthor());
81
82 this.setLayout(new BorderLayout());
83 this.add(icon, BorderLayout.CENTER);
84 this.add(title, BorderLayout.SOUTH);
85
86 setupListeners();
87 setSelected(false);
88 }
89
90 /**
91 * The book current selection state.
92 *
93 * @return the selected
94 */
95 public boolean isSelected() {
96 return selected;
97 }
98
99 /**
100 * The book current selection state.
101 *
102 * @param selected
103 * the selected to set
104 */
105 public void setSelected(boolean selected) {
106 this.selected = selected;
107 repaint();
108 }
109
110 private void setHovered(boolean hovered) {
111 this.hovered = hovered;
112 repaint();
113 }
114
115 private void setupListeners() {
116 listeners = new ArrayList<LocalReaderBook.BookActionListner>();
117 addMouseListener(new MouseListener() {
118 public void mouseReleased(MouseEvent e) {
119 }
120
121 public void mousePressed(MouseEvent e) {
122 }
123
124 public void mouseExited(MouseEvent e) {
125 setHovered(false);
126 }
127
128 public void mouseEntered(MouseEvent e) {
129 setHovered(true);
130 }
131
132 public void mouseClicked(MouseEvent e) {
133 Date now = new Date();
134 if (lastClick != null
135 && now.getTime() - lastClick.getTime() < doubleClickDelay) {
136 click(true);
137 } else {
138 click(false);
139 }
140 lastClick = now;
141 }
142 });
143 }
144
145 private void click(boolean doubleClick) {
146 for (BookActionListner listener : listeners) {
147 if (doubleClick) {
148 listener.action(this);
149 } else {
150 listener.select(this);
151 }
152 }
153 }
154
155 public void addActionListener(BookActionListner listener) {
156 listeners.add(listener);
157 }
158
159 @Override
160 public void paint(Graphics g) {
161 super.paint(g);
162
163 Color color = new Color(255, 255, 255, 0);
164 if (selected && !hovered) {
165 color = new Color(80, 80, 100, 40);
166 } else if (!selected && hovered) {
167 color = new Color(230, 230, 255, 100);
168 } else if (selected && hovered) {
169 color = new Color(200, 200, 255, 100);
170 }
171
172 Rectangle clip = g.getClipBounds();
173 g.setColor(color);
174 g.fillRect(clip.x, clip.y, clip.width, clip.height);
175 }
176 }