X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2FLocalReaderBook.java;fp=src%2Fbe%2Fnikiroo%2Ffanfix%2Freader%2FLocalReaderBook.java;h=0000000000000000000000000000000000000000;hp=0145559cd04d15ed189548cb6ef909e712e25a81;hb=5dd985cf7d5e2bb88b07fd43e7b4a4eda4647181;hpb=68e2c6d20049d713de1bd31b749450b2f60d8340 diff --git a/src/be/nikiroo/fanfix/reader/LocalReaderBook.java b/src/be/nikiroo/fanfix/reader/LocalReaderBook.java deleted file mode 100644 index 0145559..0000000 --- a/src/be/nikiroo/fanfix/reader/LocalReaderBook.java +++ /dev/null @@ -1,410 +0,0 @@ -package be.nikiroo.fanfix.reader; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.EventListener; -import java.util.List; - -import javax.imageio.ImageIO; -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import be.nikiroo.fanfix.Instance; -import be.nikiroo.fanfix.data.MetaData; -import be.nikiroo.fanfix.data.Story; -import be.nikiroo.utils.IOUtils; -import be.nikiroo.utils.ui.UIUtils; - -/** - * A book item presented in a {@link LocalReaderFrame}. - * - * @author niki - */ -class LocalReaderBook extends JPanel { - /** - * Action on a book item. - * - * @author niki - */ - interface BookActionListener extends EventListener { - /** - * The book was selected (single click). - * - * @param book - * the {@link LocalReaderBook} itself - */ - public void select(LocalReaderBook book); - - /** - * The book was double-clicked. - * - * @param book - * the {@link LocalReaderBook} itself - */ - public void action(LocalReaderBook book); - - /** - * A popup menu was requested for this {@link LocalReaderBook}. - * - * @param book - * the {@link LocalReaderBook} itself - * @param e - * the {@link MouseEvent} that generated this call - */ - public void popupRequested(LocalReaderBook book, MouseEvent e); - } - - private static final long serialVersionUID = 1L; - - // TODO: export some of the configuration options? - private static final int COVER_WIDTH = 100; - private static final int COVER_HEIGHT = 150; - private static final int SPINE_WIDTH = 5; - private static final int SPINE_HEIGHT = 5; - private static final int HOFFSET = 20; - private static final Color SPINE_COLOR_BOTTOM = new Color(180, 180, 180); - private static final Color SPINE_COLOR_RIGHT = new Color(100, 100, 100); - private static final int TEXT_WIDTH = COVER_WIDTH + 40; - private static final int TEXT_HEIGHT = 50; - private static final String AUTHOR_COLOR = "#888888"; - private static final Color BORDER = Color.black; - private static final long doubleClickDelay = 200; // in ms - // - - private JLabel icon; - private JLabel title; - private boolean selected; - private boolean hovered; - private Date lastClick; - - private List listeners; - private MetaData meta; - private boolean cached; - - /** - * Create a new {@link LocalReaderBook} item for the given {@link Story}. - * - * @param meta - * the story {@code}link MetaData} - * @param cached - * TRUE if it is locally cached - * @param seeWordcount - * TRUE to see word counts, FALSE to see authors - */ - public LocalReaderBook(MetaData meta, boolean cached, boolean seeWordCount) { - this.cached = cached; - this.meta = meta; - - String optSecondary = meta.getAuthor(); - if (seeWordCount) { - if (meta.getWords() >= 4000) { - optSecondary = (meta.getWords() / 1000) + "k words"; - } else if (meta.getWords() > 0) { - optSecondary = meta.getWords() + " words"; - } else { - optSecondary = ""; - } - } - - if (optSecondary != null && !optSecondary.isEmpty()) { - optSecondary = "(" + optSecondary + ")"; - } - - icon = new JLabel(generateCoverIcon(meta)); - title = new JLabel( - String.format( - "" - + "" - + "%s" + "
" + "" - + "%s" + "" + "" + "", - TEXT_WIDTH, TEXT_HEIGHT, meta.getTitle(), AUTHOR_COLOR, - optSecondary)); - - setLayout(new BorderLayout(10, 10)); - add(icon, BorderLayout.CENTER); - add(title, BorderLayout.SOUTH); - - setupListeners(); - } - - /** - * The book current selection state. - * - * @return the selection state - */ - public boolean isSelected() { - return selected; - } - - /** - * The book current selection state. - * - * @param selected - * TRUE if it is selected - */ - public void setSelected(boolean selected) { - if (this.selected != selected) { - this.selected = selected; - repaint(); - } - } - - /** - * The item mouse-hover state. - * - * @param hovered - * TRUE if it is mouse-hovered - */ - private void setHovered(boolean hovered) { - if (this.hovered != hovered) { - this.hovered = hovered; - repaint(); - } - } - - /** - * Setup the mouse listener that will activate {@link BookActionListener} - * events. - */ - private void setupListeners() { - listeners = new ArrayList(); - addMouseListener(new MouseListener() { - public void mouseReleased(MouseEvent e) { - if (e.isPopupTrigger()) { - popup(e); - } - } - - public void mousePressed(MouseEvent e) { - if (e.isPopupTrigger()) { - popup(e); - } - } - - public void mouseExited(MouseEvent e) { - setHovered(false); - } - - public void mouseEntered(MouseEvent e) { - setHovered(true); - } - - public void mouseClicked(MouseEvent e) { - if (isEnabled()) { - Date now = new Date(); - if (lastClick != null - && now.getTime() - lastClick.getTime() < doubleClickDelay) { - click(true); - } else { - click(false); - } - - lastClick = now; - } - } - - private void click(boolean doubleClick) { - for (BookActionListener listener : listeners) { - if (doubleClick) { - listener.action(LocalReaderBook.this); - } else { - listener.select(LocalReaderBook.this); - } - } - } - - private void popup(MouseEvent e) { - for (BookActionListener listener : listeners) { - listener.select((LocalReaderBook.this)); - listener.popupRequested(LocalReaderBook.this, e); - } - } - }); - } - - /** - * Add a new {@link BookActionListener} on this item. - * - * @param listener - * the listener - */ - public void addActionListener(BookActionListener listener) { - listeners.add(listener); - } - - /** - * The Library {@code}link MetaData} of the book represented by this item. - * - * @return the meta - */ - public MetaData getMeta() { - return meta; - } - - /** - * This item {@link LocalReader} library cache state. - * - * @return TRUE if it is present in the {@link LocalReader} cache - */ - public boolean isCached() { - return cached; - } - - /** - * This item {@link LocalReader} library cache state. - * - * @param cached - * TRUE if it is present in the {@link LocalReader} cache - */ - public void setCached(boolean cached) { - if (this.cached != cached) { - this.cached = cached; - repaint(); - } - } - - /** - * Paint the item, then call {@link LocalReaderBook#paintOverlay(Graphics)}. - */ - @Override - public void paint(Graphics g) { - super.paint(g); - paintOverlay(g); - } - - /** - * Draw a partially transparent overlay if needed depending upon the - * selection and mouse-hover states on top of the normal component, as well - * as a possible "cached" icon if the item is cached. - */ - public void paintOverlay(Graphics g) { - Rectangle clip = g.getClipBounds(); - if (clip.getWidth() <= 0 || clip.getHeight() <= 0) { - return; - } - - int h = COVER_HEIGHT; - int w = COVER_WIDTH; - int xOffset = (TEXT_WIDTH - COVER_WIDTH) - 1; - int yOffset = HOFFSET; - - if (BORDER != null) { - if (BORDER != null) { - g.setColor(BORDER); - g.drawRect(xOffset, yOffset, COVER_WIDTH, COVER_HEIGHT); - } - - xOffset++; - yOffset++; - } - - int[] xs = new int[] { xOffset, xOffset + SPINE_WIDTH, - xOffset + w + SPINE_WIDTH, xOffset + w }; - int[] ys = new int[] { yOffset + h, yOffset + h + SPINE_HEIGHT, - yOffset + h + SPINE_HEIGHT, yOffset + h }; - g.setColor(SPINE_COLOR_BOTTOM); - g.fillPolygon(new Polygon(xs, ys, xs.length)); - xs = new int[] { xOffset + w, xOffset + w + SPINE_WIDTH, - xOffset + w + SPINE_WIDTH, xOffset + w }; - ys = new int[] { yOffset, yOffset + SPINE_HEIGHT, - yOffset + h + SPINE_HEIGHT, yOffset + h }; - g.setColor(SPINE_COLOR_RIGHT); - g.fillPolygon(new Polygon(xs, ys, xs.length)); - - Color color = new Color(255, 255, 255, 0); - if (!isEnabled()) { - } else if (selected && !hovered) { - color = new Color(80, 80, 100, 40); - } else if (!selected && hovered) { - color = new Color(230, 230, 255, 100); - } else if (selected && hovered) { - color = new Color(200, 200, 255, 100); - } - - g.setColor(color); - g.fillRect(clip.x, clip.y, clip.width, clip.height); - - if (cached) { - UIUtils.drawEllipse3D(g, Color.green.darker(), COVER_WIDTH - + HOFFSET + 30, 10, 20, 20); - } - } - - /** - * Generate a cover icon based upon the given {@link MetaData}. - * - * @param meta - * the {@link MetaData} about the target {@link Story} - * - * @return the icon - */ - private ImageIcon generateCoverIcon(MetaData meta) { - String id = meta.getUuid() + ".thumb_" + SPINE_WIDTH + "x" - + COVER_WIDTH + "+" + SPINE_HEIGHT + "+" + COVER_HEIGHT + "@" - + HOFFSET; - BufferedImage resizedImage = null; - - InputStream in = Instance.getCache().getFromCache(id); - if (in != null) { - try { - resizedImage = IOUtils.toImage(in); - in.close(); - in = null; - } catch (IOException e) { - Instance.syserr(e); - } - } - - if (resizedImage == null) { - try { - BufferedImage cover = Instance.getLibrary().getCover( - meta.getLuid()); - - resizedImage = new BufferedImage(SPINE_WIDTH + COVER_WIDTH, - SPINE_HEIGHT + COVER_HEIGHT + HOFFSET, - BufferedImage.TYPE_4BYTE_ABGR); - Graphics2D g = resizedImage.createGraphics(); - g.setColor(Color.white); - g.fillRect(0, HOFFSET, COVER_WIDTH, COVER_HEIGHT); - if (cover != null) { - g.drawImage(cover, 0, HOFFSET, COVER_WIDTH, COVER_HEIGHT, - null); - } else { - g.setColor(Color.black); - g.drawLine(0, HOFFSET, COVER_WIDTH, HOFFSET + COVER_HEIGHT); - g.drawLine(COVER_WIDTH, HOFFSET, 0, HOFFSET + COVER_HEIGHT); - } - g.dispose(); - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ImageIO.write(resizedImage, "png", out); - byte[] imageBytes = out.toByteArray(); - in = new ByteArrayInputStream(imageBytes); - Instance.getCache().addToCache(in, id); - in.close(); - in = null; - } catch (MalformedURLException e) { - Instance.syserr(e); - } catch (IOException e) { - Instance.syserr(e); - } - } - - return new ImageIcon(resizedImage); - } -}