Move MainContent and its derivative to a new package, rework ContactList
authorNiki Roo <roo.niki@gmail.com>
Wed, 24 Feb 2016 13:38:05 +0000 (14:38 +0100)
committerNiki Roo <roo.niki@gmail.com>
Wed, 24 Feb 2016 13:38:05 +0000 (14:38 +0100)
to use it for other purposes, too

src/be/nikiroo/jvcard/test/TestCli.java
src/be/nikiroo/jvcard/tui/KeyAction.java
src/be/nikiroo/jvcard/tui/MainWindow.java
src/be/nikiroo/jvcard/tui/panes/ContactDetails.java [new file with mode: 0644]
src/be/nikiroo/jvcard/tui/panes/ContactList.java [new file with mode: 0644]
src/be/nikiroo/jvcard/tui/panes/FileList.java [new file with mode: 0644]
src/be/nikiroo/jvcard/tui/panes/MainContent.java [new file with mode: 0644]
src/be/nikiroo/jvcard/tui/panes/MainContentList.java [new file with mode: 0644]

index 37a3ac9811ba55be663346401bf9b695981d5f7b..6cda3e6261b437cfbba61a786a858309edd403cb 100644 (file)
@@ -2,18 +2,19 @@ package be.nikiroo.jvcard.test;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.LinkedList;
 import java.util.List;
 
 import be.nikiroo.jvcard.Card;
 import be.nikiroo.jvcard.parsers.Format;
-import be.nikiroo.jvcard.tui.ContactList;
 import be.nikiroo.jvcard.tui.MainWindow;
 import be.nikiroo.jvcard.tui.TuiLauncher;
+import be.nikiroo.jvcard.tui.panes.ContactList;
+import be.nikiroo.jvcard.tui.panes.FileList;
 
 import com.googlecode.lanterna.TerminalSize;
 import com.googlecode.lanterna.TextColor;
 import com.googlecode.lanterna.gui2.BasicWindow;
-import com.googlecode.lanterna.gui2.BorderLayout;
 import com.googlecode.lanterna.gui2.Button;
 import com.googlecode.lanterna.gui2.DefaultWindowManager;
 import com.googlecode.lanterna.gui2.EmptySpace;
@@ -37,11 +38,18 @@ public class TestCli {
                if (args.length > 0 && args[0].equals("--gui"))
                        textMode = false;
 
-               //TODO: do not hardcode that:
+               Window win = null;
+               
+               // TODO: do not hardcode that:
                Card card = new Card(new File("/home/niki/.addressbook"), Format.Abook);
-               Window win = new MainWindow(new ContactList(card));
+               win = new MainWindow(new ContactList(card));
                //
-               
+               List<File> files = new LinkedList<File>();
+               files.add(new File("/home/niki/vcf/coworkers.vcf"));
+               files.add(new File("/home/niki/vcf/oce.vcf"));
+               win = new MainWindow(new FileList(files));
+               //
+
                TuiLauncher.start(textMode, win);
 
                /*
index e6aad034a2627da68f1961b18c2d82f879fdbe28..ac1b093849a279ddd26d09fb3a748582c22466d9 100644 (file)
@@ -1,5 +1,7 @@
 package be.nikiroo.jvcard.tui;
 
+import java.io.File;
+
 import be.nikiroo.jvcard.Card;
 import be.nikiroo.jvcard.Contact;
 import be.nikiroo.jvcard.Data;
@@ -24,12 +26,32 @@ public class KeyAction {
         * @author niki
         * 
         */
-       enum Mode {
-               NONE, MOVE, BACK, HELP, CONTACT_LIST, CONTACT_DETAILS, SWICTH_FORMAT,
+       public enum Mode {
+               NONE, MOVE, BACK, HELP, FILE_LIST, CONTACT_LIST, CONTACT_DETAILS, SWICTH_FORMAT,
        }
 
-       enum DataType {
-               CONTACT, CARD, DATA, NONE
+       public enum DataType {
+               /**
+                * A list of Card {@link File}s.
+                */
+               CARD_FILES,
+               /**
+                * Contains a list of contacts.
+                */
+               CARD,
+               /**
+                * All the known informations about a specific contact person or
+                * company.
+                */
+               CONTACT,
+               /**
+                * An information about a contact.
+                */
+               DATA,
+               /**
+                * Empty.
+                */
+               NONE
        }
 
        private StringId id;
index a17e549b84a33d8152bf759300e8528ba4bacb37..7f438d918a717792f2686d6a86379c8949d74dd2 100644 (file)
@@ -10,6 +10,9 @@ import be.nikiroo.jvcard.i18n.Trans;
 import be.nikiroo.jvcard.i18n.Trans.StringId;
 import be.nikiroo.jvcard.tui.KeyAction.Mode;
 import be.nikiroo.jvcard.tui.UiColors.Element;
+import be.nikiroo.jvcard.tui.panes.ContactDetails;
+import be.nikiroo.jvcard.tui.panes.ContactList;
+import be.nikiroo.jvcard.tui.panes.MainContent;
 
 import com.googlecode.lanterna.TerminalSize;
 import com.googlecode.lanterna.gui2.BasicWindow;
@@ -272,7 +275,7 @@ public class MainWindow extends BasicWindow {
                        messagePanel.addComponent(hpanel, LinearLayout
                                        .createLayoutData(LinearLayout.Alignment.Beginning));
 
-                       this.setFocusedInteractable(text);
+                       text.takeFocus();
                }
        }
 
@@ -296,7 +299,7 @@ public class MainWindow extends BasicWindow {
                                // focus = content.get(0).getDefaultFocusElement();
                                focus = content.get(0).nextFocus(null);
 
-                       this.setFocusedInteractable(focus);
+                       focus.takeFocus();
                }
 
                return answer;
diff --git a/src/be/nikiroo/jvcard/tui/panes/ContactDetails.java b/src/be/nikiroo/jvcard/tui/panes/ContactDetails.java
new file mode 100644 (file)
index 0000000..2cd1403
--- /dev/null
@@ -0,0 +1,60 @@
+package be.nikiroo.jvcard.tui.panes;
+
+import java.util.List;
+
+import be.nikiroo.jvcard.Contact;
+import be.nikiroo.jvcard.Data;
+import be.nikiroo.jvcard.tui.KeyAction;
+import be.nikiroo.jvcard.tui.KeyAction.DataType;
+import be.nikiroo.jvcard.tui.KeyAction.Mode;
+
+import com.googlecode.lanterna.gui2.Direction;
+import com.googlecode.lanterna.gui2.Label;
+
+public class ContactDetails extends MainContent {
+       private Contact contact;
+
+       public ContactDetails(Contact contact) {
+               super(Direction.VERTICAL);
+
+               this.contact = contact;
+
+               for (Data data : contact.getContent()) {
+                       addComponent(new Label(data.getName() + ": " + data.getValue()));
+               }
+       }
+
+       @Override
+       public DataType getDataType() {
+               return DataType.CONTACT;
+       }
+
+       @Override
+       public String getExitWarning() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public List<KeyAction> getKeyBindings() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Mode getMode() {
+               return Mode.CONTACT_DETAILS;
+       }
+
+       @Override
+       public String getTitle() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String move(int x, int y) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+}
diff --git a/src/be/nikiroo/jvcard/tui/panes/ContactList.java b/src/be/nikiroo/jvcard/tui/panes/ContactList.java
new file mode 100644 (file)
index 0000000..3a943f9
--- /dev/null
@@ -0,0 +1,129 @@
+package be.nikiroo.jvcard.tui.panes;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import be.nikiroo.jvcard.Card;
+import be.nikiroo.jvcard.i18n.Trans;
+import be.nikiroo.jvcard.tui.KeyAction;
+import be.nikiroo.jvcard.tui.UiColors;
+import be.nikiroo.jvcard.tui.KeyAction.DataType;
+import be.nikiroo.jvcard.tui.KeyAction.Mode;
+
+import com.googlecode.lanterna.input.KeyType;
+
+public class ContactList extends MainContentList {
+       private Card card;
+
+       private List<String> formats = new LinkedList<String>();
+       private int selectedFormat = -1;
+       private String format = "";
+
+       public ContactList(Card card) {
+               super(UiColors.Element.CONTACT_LINE,
+                               UiColors.Element.CONTACT_LINE_SELECTED);
+
+               // TODO: should get that in an INI file
+               formats.add("NICKNAME@3|FN@+|EMAIL@30");
+               formats.add("FN@+|EMAIL@40");
+               switchFormat();
+
+               setCard(card);
+       }
+
+       /**
+        * Change the currently displayed contacts card.
+        * 
+        * @param card
+        *            the new {@link Card}
+        */
+       public void setCard(Card card) {
+               clearItems();
+               this.card = card;
+
+               if (card != null) {
+                       for (int i = 0; i < card.getContacts().size(); i++) {
+                               addItem("[contact line]");
+                       }
+               }
+
+               setSelectedIndex(0);
+       }
+
+       @Override
+       public String getExitWarning() {
+               if (card != null && card.isDirty()) {
+                       return "Some of your contact information is not saved";
+               }
+               return null;
+       }
+
+       @Override
+       public List<KeyAction> getKeyBindings() {
+               List<KeyAction> actions = new LinkedList<KeyAction>();
+
+               // TODO del, save...
+               actions.add(new KeyAction(Mode.CONTACT_DETAILS, 'e',
+                               Trans.StringId.KEY_ACTION_EDIT_CONTACT) {
+                       @Override
+                       public Object getObject() {
+                               int index = getSelectedIndex();
+                               return card.getContacts().get(index);
+                       }
+               });
+               actions.add(new KeyAction(Mode.CONTACT_DETAILS, KeyType.Enter,
+                               Trans.StringId.KEY_ACTION_VIEW_CONTACT) {
+                       @Override
+                       public Object getObject() {
+                               int index = getSelectedIndex();
+                               return card.getContacts().get(index);
+                       }
+               });
+               actions.add(new KeyAction(Mode.SWICTH_FORMAT, KeyType.Tab,
+                               Trans.StringId.KEY_ACTION_SWITCH_FORMAT) {
+                       @Override
+                       public boolean onAction() {
+                               switchFormat();
+                               return false;
+                       }
+               });
+
+               return actions;
+       }
+
+       @Override
+       public DataType getDataType() {
+               return DataType.CARD;
+       }
+
+       @Override
+       public Mode getMode() {
+               return Mode.CONTACT_LIST;
+       }
+
+       @Override
+       public String getTitle() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       protected String getLabel(int index, int width) {
+               // we could use: " ", "┃", "│"...
+               return card.getContacts().get(index).toString(format, " ┃ ", width);
+       }
+
+       private void switchFormat() {
+               if (formats.size() == 0)
+                       return;
+
+               selectedFormat++;
+               if (selectedFormat >= formats.size()) {
+                       selectedFormat = 0;
+               }
+
+               format = formats.get(selectedFormat);
+
+               invalidate();
+       }
+}
diff --git a/src/be/nikiroo/jvcard/tui/panes/FileList.java b/src/be/nikiroo/jvcard/tui/panes/FileList.java
new file mode 100644 (file)
index 0000000..9930070
--- /dev/null
@@ -0,0 +1,69 @@
+package be.nikiroo.jvcard.tui.panes;
+
+import java.io.File;
+import java.util.List;
+
+import be.nikiroo.jvcard.tui.KeyAction;
+import be.nikiroo.jvcard.tui.UiColors;
+import be.nikiroo.jvcard.tui.KeyAction.DataType;
+import be.nikiroo.jvcard.tui.KeyAction.Mode;
+
+import com.googlecode.lanterna.gui2.Label;
+
+public class FileList extends MainContentList {
+       private List<File> files;
+
+       public FileList(List<File> files) {
+               super(UiColors.Element.CONTACT_LINE,
+                               UiColors.Element.CONTACT_LINE_SELECTED);
+
+               setFiles(files);
+       }
+
+       /**
+        * Change the list of currently selected files.
+        * 
+        * @param files
+        *            the new files
+        */
+       public void setFiles(List<File> files) {
+               clearItems();
+               this.files = files;
+
+               // TODO
+               for (File file : files) {
+                       addItem(file.getName());
+               }
+
+               setSelectedIndex(0);
+       }
+
+       @Override
+       public DataType getDataType() {
+               return DataType.CARD_FILES;
+       }
+
+       @Override
+       public String getExitWarning() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public List<KeyAction> getKeyBindings() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public Mode getMode() {
+               return Mode.FILE_LIST;
+       }
+
+       @Override
+       public String getTitle() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+}
diff --git a/src/be/nikiroo/jvcard/tui/panes/MainContent.java b/src/be/nikiroo/jvcard/tui/panes/MainContent.java
new file mode 100644 (file)
index 0000000..df87313
--- /dev/null
@@ -0,0 +1,81 @@
+package be.nikiroo.jvcard.tui.panes;
+
+import java.util.List;
+
+import be.nikiroo.jvcard.tui.KeyAction;
+
+import com.googlecode.lanterna.gui2.Direction;
+import com.googlecode.lanterna.gui2.LinearLayout;
+import com.googlecode.lanterna.gui2.Panel;
+
+/**
+ * This class represents the main content that you can see in this application
+ * (i.e., everything but the title and the actions keys is a {@link Panel}
+ * extended from this class).
+ * 
+ * @author niki
+ * 
+ */
+abstract public class MainContent extends Panel {
+
+       public MainContent() {
+               super();
+       }
+
+       public MainContent(Direction dir) {
+               super();
+               LinearLayout layout = new LinearLayout(dir);
+               layout.setSpacing(0);
+               setLayoutManager(layout);
+       }
+
+       /**
+        * The title to display instead of the application name, or NULL for the
+        * default application name.
+        * 
+        * @return the title or NULL
+        */
+       abstract public String getTitle();
+
+       /**
+        * Returns an error message ready to be displayed if we should ask something
+        * to the user before exiting.
+        * 
+        * @return an error message or NULL
+        */
+       abstract public String getExitWarning();
+
+       /**
+        * The {@link KeyAction#Mode} that links to this {@link MainContent}.
+        * 
+        * @return the linked mode
+        */
+       abstract public KeyAction.Mode getMode();
+
+       /**
+        * The kind of data displayed by this {@link MainContent}.
+        * 
+        * @return the kind of data displayed
+        */
+       abstract public KeyAction.DataType getDataType();
+
+       /**
+        * Returns the list of actions and the keys that are bound to it.
+        * 
+        * @return the list of actions
+        */
+       abstract public List<KeyAction> getKeyBindings();
+
+       /**
+        * Move the active cursor (not the text cursor, but the currently active
+        * item).
+        * 
+        * @param x
+        *            the horizontal move (&lt; 0 for left, &gt; 0 for right)
+        * @param y
+        *            the vertical move (&lt; 0 for up, &gt; 0 for down)
+        * 
+        * @return the error message to display if any
+        */
+       abstract public String move(int x, int y);
+}
diff --git a/src/be/nikiroo/jvcard/tui/panes/MainContentList.java b/src/be/nikiroo/jvcard/tui/panes/MainContentList.java
new file mode 100644 (file)
index 0000000..137a68d
--- /dev/null
@@ -0,0 +1,144 @@
+package be.nikiroo.jvcard.tui.panes;
+
+import be.nikiroo.jvcard.tui.UiColors;
+
+import com.googlecode.lanterna.gui2.ActionListBox;
+import com.googlecode.lanterna.gui2.Direction;
+import com.googlecode.lanterna.gui2.LinearLayout;
+import com.googlecode.lanterna.gui2.TextGUIGraphics;
+import com.googlecode.lanterna.gui2.AbstractListBox.ListItemRenderer;
+
+abstract public class MainContentList extends MainContent implements Runnable {
+       private ActionListBox lines;
+
+       public MainContentList(final UiColors.Element normalStyle,
+                       final UiColors.Element selectedStyle) {
+               super(Direction.VERTICAL);
+
+               lines = new ActionListBox();
+
+               lines
+                               .setListItemRenderer(new ListItemRenderer<Runnable, ActionListBox>() {
+                                       /**
+                                        * This is the main drawing method for a single list box
+                                        * item, it applies the current theme to setup the colors
+                                        * and then calls {@code getLabel(..)} and draws the result
+                                        * using the supplied {@code TextGUIGraphics}. The graphics
+                                        * object is created just for this item and is restricted so
+                                        * that it can only draw on the area this item is occupying.
+                                        * The top-left corner (0x0) should be the starting point
+                                        * when drawing the item.
+                                        * 
+                                        * @param graphics
+                                        *            Graphics object to draw with
+                                        * @param listBox
+                                        *            List box we are drawing an item from
+                                        * @param index
+                                        *            Index of the item we are drawing
+                                        * @param item
+                                        *            The item we are drawing
+                                        * @param selected
+                                        *            Will be set to {@code true} if the item is
+                                        *            currently selected, otherwise {@code false},
+                                        *            but please notice what context 'selected'
+                                        *            refers to here (see {@code setSelectedIndex})
+                                        * @param focused
+                                        *            Will be set to {@code true} if the list box
+                                        *            currently has input focus, otherwise {@code
+                                        *            false}
+                                        */
+                                       public void drawItem(TextGUIGraphics graphics,
+                                                       ActionListBox listBox, int index, Runnable item,
+                                                       boolean selected, boolean focused) {
+
+                                               if (selected && focused) {
+                                                       graphics.setForegroundColor(selectedStyle
+                                                                       .getForegroundColor());
+                                                       graphics.setBackgroundColor(selectedStyle
+                                                                       .getBackgroundColor());
+                                               } else {
+                                                       graphics.setForegroundColor(normalStyle
+                                                                       .getForegroundColor());
+                                                       graphics.setBackgroundColor(normalStyle
+                                                                       .getBackgroundColor());
+                                               }
+
+                                               // original impl:
+                                               // String label = getLabel(listBox, index, item);
+                                               // label = TerminalTextUtils.fitString(label,
+                                               // graphics.getSize().getColumns());
+
+                                               // TODO: why +5 ?? padding problem?
+                                               String label = MainContentList.this.getLabel(index,
+                                                               lines.getSize().getColumns() + 5);
+                                               graphics.putString(0, 0, label);
+                                       }
+                               });
+
+               addComponent(lines, LinearLayout
+                               .createLayoutData(LinearLayout.Alignment.Fill));
+       }
+
+       /**
+        * Add an item to this {@link MainContentList}.
+        * 
+        * @param line
+        *            the item to add
+        */
+       public void addItem(String line) {
+               lines.addItem(line, this);
+       }
+       
+       /**
+        * Clear all the items in this {@link MainContentList}
+        */
+       public void clearItems() {
+               lines.clearItems();
+       }
+
+       /**
+        * Get the index of the currently selected line.
+        * 
+        * @return the index
+        */
+       public int getSelectedIndex() {
+               return lines.getSelectedIndex();
+       }
+
+       /**
+        * Change the index of the currently selected line.
+        * 
+        * @param index
+        *            the new index
+        */
+       public void setSelectedIndex(int index) {
+               lines.setSelectedIndex(index);
+       }
+
+       @Override
+       public void run() {
+               // item selected.
+               // ignore.
+       }
+
+       @Override
+       public String move(int x, int y) {
+               setSelectedIndex(getSelectedIndex() + x);
+               // TODO: y?
+               return null;
+       }
+
+       /**
+        * Return the text representation of the selected line.
+        * 
+        * @param index
+        *            the line index
+        * @param width
+        *            the max width of the line
+        * 
+        * @return the text representation
+        */
+       protected String getLabel(int index, int width) {
+               return "" + lines.getItems().get(index);
+       }
+}