From b16fa4406a39050c4690bd8273485c3221a5713d Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Wed, 6 May 2020 19:43:12 +0200 Subject: [PATCH] prepare kiosk and touch mode --- src/be/nikiroo/fanfix_swing/Actions.java | 4 +- src/be/nikiroo/fanfix_swing/Main.java | 20 ++- .../nikiroo/fanfix_swing/gui/BooksPanel.java | 116 +++++++++++++---- .../nikiroo/fanfix_swing/gui/TouchFrame.java | 118 ++++++++++++++++++ 4 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 src/be/nikiroo/fanfix_swing/gui/TouchFrame.java diff --git a/src/be/nikiroo/fanfix_swing/Actions.java b/src/be/nikiroo/fanfix_swing/Actions.java index b1c73dbe..6350c8a7 100644 --- a/src/be/nikiroo/fanfix_swing/Actions.java +++ b/src/be/nikiroo/fanfix_swing/Actions.java @@ -93,7 +93,7 @@ public class Actions { * @param story * the story to open */ - static private void openInternal(Story story) { + static public void openInternal(Story story) { if (story.getMeta().isImageDocument()) { ViewerImages viewer = new ViewerImages(story); viewer.setVisible(true); @@ -117,7 +117,7 @@ public class Actions { * @throws IOException * in case of I/O error */ - static private void openExternal(File target, boolean isImageDocument) + static public void openExternal(File target, boolean isImageDocument) throws IOException { String program = null; if (isImageDocument) { diff --git a/src/be/nikiroo/fanfix_swing/Main.java b/src/be/nikiroo/fanfix_swing/Main.java index 5efbc248..9ebfb1a9 100644 --- a/src/be/nikiroo/fanfix_swing/Main.java +++ b/src/be/nikiroo/fanfix_swing/Main.java @@ -20,6 +20,7 @@ import be.nikiroo.fanfix.VersionCheck; import be.nikiroo.fanfix.bundles.StringIdGui; import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix_swing.gui.MainFrame; +import be.nikiroo.fanfix_swing.gui.TouchFrame; import be.nikiroo.utils.Version; import be.nikiroo.utils.ui.UIUtils; @@ -31,6 +32,7 @@ import be.nikiroo.utils.ui.UIUtils; public class Main extends be.nikiroo.fanfix.Main { private boolean busy; private boolean kiosk; + private boolean touch; /** * The main entry point of the application. @@ -38,8 +40,16 @@ public class Main extends be.nikiroo.fanfix.Main { * It overrides some function of Fanfix's Main. * * @param args - * the arguments (none, "--kiosk" (fullceen, no decorations, - * Nimbus Look & Feel) or will be passed to Fanfix) + * in addition to the supported Fanfix arguments, we also + * support: + * */ public static void main(String[] args) { new Main().start(args); @@ -51,6 +61,8 @@ public class Main extends be.nikiroo.fanfix.Main { for (String arg : args) { if ("--kiosk".equals(arg)) { kiosk = true; + } else if ("--touch".equals(arg)) { + touch = true; } else { argsList.add(arg); } @@ -114,13 +126,11 @@ public class Main extends be.nikiroo.fanfix.Main { Instance.init(); - JFrame main = new MainFrame(); - + JFrame main = touch ? new TouchFrame() : new MainFrame(); if (kiosk) { main.setUndecorated(kiosk); main.setExtendedState(JFrame.MAXIMIZED_BOTH); } - main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); main.setVisible(true); } diff --git a/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java b/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java index 8af6d5fd..a49c5b81 100644 --- a/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java +++ b/src/be/nikiroo/fanfix_swing/gui/BooksPanel.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; +import javax.swing.JPopupMenu; import javax.swing.ListSelectionModel; import javax.swing.SwingWorker; @@ -29,15 +30,14 @@ import be.nikiroo.fanfix_swing.gui.book.BookInfo.Type; import be.nikiroo.fanfix_swing.gui.book.BookLine; import be.nikiroo.fanfix_swing.gui.book.BookPopup; import be.nikiroo.fanfix_swing.gui.book.BookPopup.Informer; -import be.nikiroo.fanfix_swing.gui.importer.ImporterFrame; import be.nikiroo.utils.ui.DelayWorker; import be.nikiroo.utils.ui.ListModel; import be.nikiroo.utils.ui.ListModel.Predicate; -import be.nikiroo.utils.ui.compat.JList6; -import be.nikiroo.utils.ui.compat.ListCellRenderer6; import be.nikiroo.utils.ui.ListSnapshot; import be.nikiroo.utils.ui.ListenerPanel; import be.nikiroo.utils.ui.UIUtils; +import be.nikiroo.utils.ui.compat.JList6; +import be.nikiroo.utils.ui.compat.ListCellRenderer6; public class BooksPanel extends ListenerPanel { /** @@ -92,10 +92,20 @@ public class BooksPanel extends ListenerPanel { private Informer informer; private BooksPanelActions actions; - private BookPopup popup; private ReloadData lastLoad = new ReloadData(); + /** + * Create a new {@link BooksPanel}. + *

+ * It will come by default with a popup and a tooltip. + * + * @param showThumbnails + * show thumbnails instead of lsit items + * @param seeWordCount + * show the number of words/images of the book instead of its + * author + */ public BooksPanel(boolean showThumbnails, boolean seeWordCount) { setLayout(new BorderLayout()); this.seeWordCount = seeWordCount; @@ -185,7 +195,10 @@ public class BooksPanel extends ListenerPanel { } // Reset the popup menu items for for sources/author - popup.reloadData(); + JPopupMenu popup = data.getPopup(); + if (popup instanceof BookPopup) { + ((BookPopup) popup).reloadData(); + } if (lastLoad.mode == ReloadMode.NONE) { return; // nothing was loaded yet @@ -209,6 +222,79 @@ public class BooksPanel extends ListenerPanel { snapshot.apply(); } + /** + * The informer we use for the popup or other actions. + * + * @return the informer + */ + public Informer getInformer() { + return informer; + } + + /** + * The popup that we use to generate a {@link BookPopup} on right click. + *

+ * Note that a {@link BookPopup} is set by default, with the informer from + * this panel. + * + * @return the current popup (can be NULL) + */ + public JPopupMenu hasPopup() { + return data.getPopup(); + } + + /** + * The popup that we use to generate a {@link BookPopup} on right click. + *

+ * Note that a {@link BookPopup} is set by default, with the informer from + * this panel. + * + * @param popup + * the new popup (can be NULL) + */ + public void setPopup(JPopupMenu popup) { + data.setPopup(popup); + } + + /** + * Generate a tooltip on mouse hover that shows the details of the book + * under the mouse. + * + * @return TRUE if we use it, FALSE if not + */ + public boolean hasTooltip() { + return data.getTooltipCreator() != null; + } + + /** + * Generate a tooltip on mouse hover that shows the details of the book + * under the mouse. + * + * @param tooltip + * TRUE to use it, FALSE not to + */ + public void setTooltip(boolean tooltip) { + if (tooltip) { + data.setTooltipCreator(new ListModel.TooltipCreator() { + @Override + public Window generateTooltip(BookInfo book, + boolean undecorated) { + MetaData meta = book == null ? null : book.getMeta(); + if (meta != null) { + PropertiesDialog tooltip = new PropertiesDialog( + Instance.getInstance().getLibrary(), meta, + undecorated); + return tooltip; + } + + return null; + } + }); + } else { + data.setTooltipCreator(null); + } + } + // is UI! private void filter() { data.filter(new Predicate() { @@ -252,25 +338,11 @@ public class BooksPanel extends ListenerPanel { private JList6 initList() { informer = initInformer(); - popup = new BookPopup(Instance.getInstance().getLibrary(), informer); actions = new BooksPanelActions(this, informer); final JList6 list = new JList6(); - data = new ListModel(list, popup, - new ListModel.TooltipCreator() { - @Override - public Window generateTooltip(BookInfo book, - boolean undecorated) { - MetaData meta = book == null ? null : book.getMeta(); - if (meta != null) { - PropertiesDialog tooltip = new PropertiesDialog( - Instance.getInstance().getLibrary(), meta, - undecorated); - return tooltip; - } - - return null; - } - }); + data = new ListModel(list); + setPopup(new BookPopup(Instance.getInstance().getLibrary(), informer)); + setTooltip(true); list.addMouseListener(new MouseAdapter() { @Override diff --git a/src/be/nikiroo/fanfix_swing/gui/TouchFrame.java b/src/be/nikiroo/fanfix_swing/gui/TouchFrame.java new file mode 100644 index 00000000..0bde0344 --- /dev/null +++ b/src/be/nikiroo/fanfix_swing/gui/TouchFrame.java @@ -0,0 +1,118 @@ +package be.nikiroo.fanfix_swing.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Window; +import java.io.File; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingWorker; + +import be.nikiroo.fanfix.Instance; +import be.nikiroo.fanfix.data.Story; +import be.nikiroo.fanfix.library.BasicLibrary; +import be.nikiroo.fanfix_swing.Actions; +import be.nikiroo.fanfix_swing.gui.book.BookInfo; +import be.nikiroo.fanfix_swing.gui.utils.UiHelper; +import be.nikiroo.fanfix_swing.gui.utils.WaitingDialogMeta; +import be.nikiroo.fanfix_swing.gui.viewer.ViewerImages; +import be.nikiroo.fanfix_swing.gui.viewer.ViewerNonImages; +import be.nikiroo.utils.ui.WaitingDialog; + +public class TouchFrame extends JFrame { + private JPanel root; + + private JPanel wait; + private BooksPanel books; + + public TouchFrame() { + root = new JPanel(new BorderLayout()); + + wait = new JPanel(); + wait.add(new JLabel("Waiting...")); + + books = new BooksPanel(false, true); + books.setTooltip(false); + books.loadData(null, null, null); + // We hijack the popup to generate an action on long-press. + books.setPopup(new JPopupMenu() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isShowing() { + return false; + } + + @Override + public void show(Component invoker, int x, int y) { + final BookInfo book = books.getInformer().getUniqueSelected(); + if (book != null && book.getMeta() != null) { + final BasicLibrary lib = Instance.getInstance() + .getLibrary(); + + showWait(); // TODO: some details + + new SwingWorker() { + private Story story; + + @Override + protected File doInBackground() throws Exception { + story = lib.getStory(book.getMeta().getLuid(), + null); + return null; + } + + @Override + protected void done() { + try { + get(); + Actions.openInternal(story); + } catch (Exception e) { + // TODO: i18n + UiHelper.error(TouchFrame.this, + e.getLocalizedMessage(), + "Cannot open the story", e); + } + + // Integrate it with showViewer or something + if (story.getMeta().isImageDocument()) { + ViewerImages viewer = new ViewerImages(story); + viewer.setVisible(true); + } else { + ViewerNonImages viewer = new ViewerNonImages( + Instance.getInstance().getLibrary(), + story); + viewer.setVisible(true); + } + + } + }.execute(); + } + } + }); + + this.add(root); + showBooks(); + setSize(355, 465); + } + + private void removeShows() { + root.remove(wait); + root.remove(books); + } + + private void showBooks() { + removeShows(); + root.add(books); + revalidate(); + } + + private void showWait() { + removeShows(); + root.add(wait); + revalidate(); + } +} -- 2.27.0