prepare kiosk and touch mode
authorNiki Roo <niki@nikiroo.be>
Wed, 6 May 2020 17:43:12 +0000 (19:43 +0200)
committerNiki Roo <niki@nikiroo.be>
Wed, 6 May 2020 17:43:12 +0000 (19:43 +0200)
src/be/nikiroo/fanfix_swing/Actions.java
src/be/nikiroo/fanfix_swing/Main.java
src/be/nikiroo/fanfix_swing/gui/BooksPanel.java
src/be/nikiroo/fanfix_swing/gui/TouchFrame.java [new file with mode: 0644]

index b1c73dbe9fbd5431b384ac7f7a459d081037072c..6350c8a781dffc8714d3f037ebebd4405366ff4f 100644 (file)
@@ -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) {
index 5efbc248db7dd071077935742baded74ec08460e..9ebfb1a9f5aa5eb16adaaee6e900ef8c1708d4d3 100644 (file)
@@ -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 &amp; Feel) or will be passed to Fanfix)
+        *            in addition to the supported Fanfix arguments, we also
+        *            support:
+        *            <ul>
+        *            <li>(no arguments): we start normally</li>
+        *            <li><tt>--kisok</tt>: we start fullceen, without window
+        *            decorations on the main frame and with the Nimbus Look &amp;
+        *            Feel</li>
+        *            <li><tt>--touch</tt>: a special mode dedicated to small touch
+        *            devices</li>
+        *            </ul>
         */
        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);
        }
index 8af6d5fd42e01ed94bb441ad403186cb13f176c3..a49c5b81c7cf63b1dac49b95748ec4d572ddf116 100644 (file)
@@ -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}.
+        * <p>
+        * 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.
+        * <p>
+        * 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.
+        * <p>
+        * 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<BookInfo>() {
+                               @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<BookInfo>() {
@@ -252,25 +338,11 @@ public class BooksPanel extends ListenerPanel {
 
        private JList6<BookInfo> initList() {
                informer = initInformer();
-               popup = new BookPopup(Instance.getInstance().getLibrary(), informer);
                actions = new BooksPanelActions(this, informer);
                final JList6<BookInfo> list = new JList6<BookInfo>();
-               data = new ListModel<BookInfo>(list, popup,
-                               new ListModel.TooltipCreator<BookInfo>() {
-                                       @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<BookInfo>(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 (file)
index 0000000..0bde034
--- /dev/null
@@ -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<File, Void>() {
+                                               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();
+       }
+}