+++ /dev/null
-package be.nikiroo.fanfix.reader.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.EventListener;
-import java.util.List;
-
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import be.nikiroo.fanfix.data.Story;
-import be.nikiroo.fanfix.reader.Reader;
-
-/**
- * A book item presented in a {@link GuiReaderFrame}.
- * <p>
- * Can be a story, or a comic or... a group.
- *
- * @author niki
- */
-class GuiReaderBook extends JPanel {
- /**
- * Action on a book item.
- *
- * @author niki
- */
- interface BookActionListener extends EventListener {
- /**
- * The book was selected (single click).
- *
- * @param book
- * the {@link GuiReaderBook} itself
- */
- public void select(GuiReaderBook book);
-
- /**
- * The book was double-clicked.
- *
- * @param book
- * the {@link GuiReaderBook} itself
- */
- public void action(GuiReaderBook book);
-
- /**
- * A popup menu was requested for this {@link GuiReaderBook}.
- *
- * @param book
- * the {@link GuiReaderBook} itself
- * @param target
- * the target component for the popup
- * @param x
- * the X position of the click/request (in case of popup
- * request from the keyboard, the center of the target is
- * selected as point of reference)
- * @param y
- * the Y position of the click/request (in case of popup
- * request from the keyboard, the center of the target is
- * selected as point of reference)
- */
- public void popupRequested(GuiReaderBook book, Component target, int x,
- int y);
- }
-
- private static final long serialVersionUID = 1L;
-
- private static final String AUTHOR_COLOR = "#888888";
- 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<BookActionListener> listeners;
- private GuiReaderBookInfo info;
- private boolean cached;
- private boolean seeWordCount;
-
- /**
- * Create a new {@link GuiReaderBook} item for the given {@link Story}.
- *
- * @param reader
- * the associated reader
- * @param info
- * the information about the story to represent
- * @param cached
- * TRUE if it is locally cached
- * @param seeWordCount
- * TRUE to see word counts, FALSE to see authors
- */
- public GuiReaderBook(Reader reader, GuiReaderBookInfo info, boolean cached,
- boolean seeWordCount) {
- this.info = info;
- this.cached = cached;
- this.seeWordCount = seeWordCount;
-
- icon = new JLabel(GuiReaderCoverImager.generateCoverIcon(
- reader.getLibrary(), info));
-
- title = new JLabel();
- updateTitle();
-
- 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.
- * <p>
- * Setting this value to true can cause a "select" action to occur if the
- * previous state was "unselected".
- *
- * @param selected
- * TRUE if it is selected
- */
- public void setSelected(boolean selected) {
- if (this.selected != selected) {
- this.selected = selected;
- repaint();
-
- if (selected) {
- select();
- }
- }
- }
-
- /**
- * The item mouse-hover state.
- *
- * @return TRUE if it is mouse-hovered
- */
- public boolean isHovered() {
- return this.hovered;
- }
-
- /**
- * The item mouse-hover state.
- *
- * @param hovered
- * TRUE if it is mouse-hovered
- */
- public 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<GuiReaderBook.BookActionListener>();
- addMouseListener(new MouseListener() {
- @Override
- public void mouseReleased(MouseEvent e) {
- if (isEnabled() && e.isPopupTrigger()) {
- popup(e);
- }
- }
-
- @Override
- public void mousePressed(MouseEvent e) {
- if (isEnabled() && e.isPopupTrigger()) {
- popup(e);
- }
- }
-
- @Override
- public void mouseExited(MouseEvent e) {
- setHovered(false);
- }
-
- @Override
- public void mouseEntered(MouseEvent e) {
- setHovered(true);
- }
-
- @Override
- 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;
- e.consume();
- }
- }
-
- private void click(boolean doubleClick) {
- if (doubleClick) {
- action();
- } else {
- select();
- }
- }
-
- private void popup(MouseEvent e) {
- GuiReaderBook.this
- .popup(GuiReaderBook.this, e.getX(), e.getY());
- e.consume();
- }
- });
- }
-
- /**
- * Add a new {@link BookActionListener} on this item.
- *
- * @param listener
- * the listener
- */
- public void addActionListener(BookActionListener listener) {
- listeners.add(listener);
- }
-
- /**
- * Cause an action to occur on this {@link GuiReaderBook}.
- */
- public void action() {
- for (BookActionListener listener : listeners) {
- listener.action(GuiReaderBook.this);
- }
- }
-
- /**
- * Cause a select event on this {@link GuiReaderBook}.
- * <p>
- * Have a look at {@link GuiReaderBook#setSelected(boolean)}.
- */
- private void select() {
- for (BookActionListener listener : listeners) {
- listener.select(GuiReaderBook.this);
- }
- }
-
- /**
- * Request a popup.
- *
- * @param target
- * the target component for the popup
- * @param x
- * the X position of the click/request (in case of popup request
- * from the keyboard, the center of the target should be selected
- * as point of reference)
- * @param y
- * the Y position of the click/request (in case of popup request
- * from the keyboard, the center of the target should be selected
- * as point of reference)
- */
- public void popup(Component target, int x, int y) {
- for (BookActionListener listener : listeners) {
- listener.select((GuiReaderBook.this));
- listener.popupRequested(GuiReaderBook.this, target, x, y);
- }
- }
-
- /**
- * The information about the book represented by this item.
- *
- * @return the meta
- */
- public GuiReaderBookInfo getInfo() {
- return info;
- }
-
- /**
- * This item {@link GuiReader} library cache state.
- *
- * @return TRUE if it is present in the {@link GuiReader} cache
- */
- public boolean isCached() {
- return cached;
- }
-
- /**
- * This item {@link GuiReader} library cache state.
- *
- * @param cached
- * TRUE if it is present in the {@link GuiReader} cache
- */
- public void setCached(boolean cached) {
- if (this.cached != cached) {
- this.cached = cached;
- repaint();
- }
- }
-
- /**
- * Update the title, paint the item, then call
- * {@link GuiReaderCoverImager#paintOverlay(Graphics, boolean, boolean, boolean, boolean)}
- * .
- */
- @Override
- public void paint(Graphics g) {
- updateTitle();
- super.paint(g);
- GuiReaderCoverImager.paintOverlay(g, isEnabled(), isSelected(),
- isHovered(), isCached());
- }
-
- /**
- * Update the title with the currently registered information.
- */
- private void updateTitle() {
- String optSecondary = info.getSecondaryInfo(seeWordCount);
- title.setText(String
- .format("<html>"
- + "<body style='width: %d px; height: %d px; text-align: center'>"
- + "%s" + "<br>" + "<span style='color: %s;'>" + "%s"
- + "</span>" + "</body>" + "</html>",
- GuiReaderCoverImager.TEXT_WIDTH,
- GuiReaderCoverImager.TEXT_HEIGHT, info.getMainInfo(),
- AUTHOR_COLOR, optSecondary));
- }
-}