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.utils.DelayWorker;
-import be.nikiroo.fanfix_swing.gui.utils.ListModel;
-import be.nikiroo.fanfix_swing.gui.utils.ListModel.Predicate;
import be.nikiroo.utils.compat.JList6;
import be.nikiroo.utils.compat.ListCellRenderer6;
-import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
-import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
+import be.nikiroo.utils.ui.DelayWorker;
+import be.nikiroo.utils.ui.ListModel;
+import be.nikiroo.utils.ui.ListModel.Predicate;
+import be.nikiroo.utils.ui.ListenerPanel;
+import be.nikiroo.utils.ui.UIUtils;
public class BooksPanel extends ListenerPanel {
static public final String INVALIDATE_CACHE = "invalidate_cache";
list = initList();
setListMode(listMode);
- add(UiHelper.scroll(list), BorderLayout.CENTER);
+ add(UIUtils.scroll(list, false), BorderLayout.CENTER);
}
// null or empty -> all sources
--- /dev/null
+package be.nikiroo.fanfix_swing.gui;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.library.BasicLibrary;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo.Type;
+import be.nikiroo.fanfix_swing.gui.utils.DataNodeBook;
+import be.nikiroo.fanfix_swing.gui.utils.DataTreeAuthors;
+import be.nikiroo.fanfix_swing.gui.utils.DataTreeSources;
+import be.nikiroo.fanfix_swing.gui.utils.DataTreeTag;
+import be.nikiroo.utils.ui.BreadCrumbsBar;
+import be.nikiroo.utils.ui.DataNode;
+import be.nikiroo.utils.ui.DataTree;
+
+public class BreadCrumbsPanel extends BreadCrumbsBar<DataNodeBook> {
+ public BreadCrumbsPanel() {
+ super(new DataTree<DataNodeBook>() {
+ @Override
+ protected DataNode<DataNodeBook> extractData() throws IOException {
+ List<? extends DataNode<DataNodeBook>> children = null;
+
+ children = new DataTreeSources().loadData().getChildren();
+ DataNode<DataNodeBook> sources = new DataNode<DataNodeBook>(
+ children, new DataNodeBook(Type.SOURCE, "Sources", true,
+ !children.isEmpty()));
+ children = new DataTreeAuthors().loadData().getChildren();
+ DataNode<DataNodeBook> authors = new DataNode<DataNodeBook>(
+ children, new DataNodeBook(Type.AUTHOR, "Authors", true,
+ !children.isEmpty()));
+ children = new DataTreeTag().loadData().getChildren();
+ DataNode<DataNodeBook> tags = new DataNode<DataNodeBook>(
+ children, new DataNodeBook(Type.TAG, "Tags", true,
+ !children.isEmpty()));
+
+ return new DataNode<DataNodeBook>(
+ Arrays.asList(sources, authors, tags),
+ new DataNodeBook(null, false));
+ }
+
+ @Override
+ protected boolean checkFilter(String filter,
+ DataNodeBook userData) {
+ return userData.toString().contains(filter.toLowerCase());
+ }
+ });
+ }
+
+ public BookInfo getHighlight() {
+ DataNode<DataNodeBook> node = getSelectedNode();
+
+ if (node != null && node.getUserData() != null) {
+ BasicLibrary lib = Instance.getInstance().getLibrary();
+
+ DataNodeBook book = node.getUserData();
+ if (book.getType() != null) {
+ switch (book.getType()) {
+ case SOURCE:
+ return BookInfo.fromSource(lib,
+ book.isRoot() ? null : book.getPath());
+ case AUTHOR:
+ return BookInfo.fromAuthor(lib,
+ book.isRoot() ? null : book.getPath());
+ case TAG:
+ return BookInfo.fromTag(lib,
+ book.isRoot() ? null : book.getPath());
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return null;
+ }
+}
import be.nikiroo.fanfix_swing.gui.browser.BasicTab;
import be.nikiroo.fanfix_swing.gui.browser.SourceTab;
import be.nikiroo.fanfix_swing.gui.browser.TagsTab;
-import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
+import be.nikiroo.utils.ui.ListenerPanel;
/**
* Panel dedicated to browse the stories through different means: by authors, by
* Return a special "all" {@link BookInfo} of the correct type when nothing
* is selected.
*
- * @return the {@link BookInfo} to highlight, can be NULL
+ * @return the {@link BookInfo} to highlight, cannot be NULL
*/
public BookInfo getHighlight() {
String selected1 = null;
}
// ...what?
- return null;
+ return BookInfo.fromSource(lib, selected1);
}
/**
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
-import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSplitPane;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo;
import be.nikiroo.fanfix_swing.gui.importer.ImporterFrame;
import be.nikiroo.utils.Version;
private BooksPanel books;
private DetailsPanel details;
private BrowserPanel browser;
+ private BreadCrumbsPanel goBack;
private ImporterFrame importer = new ImporterFrame();
public MainFrame(boolean sidePanel, boolean detailsPanel) {
setSize(800, 600);
setJMenuBar(createMenuBar());
- sidePanel = true;
- detailsPanel = true;
+ // TODO: setSidePanel() and setDetailsPanel();
browser = new BrowserPanel();
books = new BooksPanel(true);
+ details = new DetailsPanel();
+ goBack = new BreadCrumbsPanel();
JComponent other = null;
boolean orientationH = true;
other = browser;
} else if (sidePanel && detailsPanel) {
JComponent side = browser;
- details = new DetailsPanel();
other = split(side, details, false, 0.5, 1);
} else if (!sidePanel && !detailsPanel) {
orientationH = false;
- other = new JLabel("<< Go back");
+ other = goBack;
+ goBack.setVertical(false);
} else if (!sidePanel && detailsPanel) {
- JComponent goBack = new JLabel("<< Go back");
- details = new DetailsPanel();
other = split(goBack, details, false, 0.5, 1);
+ goBack.setVertical(true);
}
browser.addActionListener(new ActionListener() {
details.setBook(browser.getHighlight());
}
});
+ goBack.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ BookInfo book = goBack.getHighlight();
+ List<String> sources = new ArrayList<String>();
+ List<String> authors = new ArrayList<String>();
+ List<String> tags = new ArrayList<String>();
+
+ if (book != null && book.getMainInfo() != null) {
+ switch (book.getType()) {
+ case SOURCE:
+ sources.add(book.getMainInfo());
+ break;
+ case AUTHOR:
+ authors.add(book.getMainInfo());
+ break;
+ case TAG:
+ tags.add(book.getMainInfo());
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ books.loadData(sources, authors, tags);
+ details.setBook(book);
+ }
+ });
books.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setTitle(Instance.getInstance().getTransGui().getString(
StringIdGui.TITLE_STORY, meta.getLuid(), meta.getTitle()));
- PropertiesPane desc = new PropertiesPane(lib, meta);
+ PropertiesPanel desc = new PropertiesPanel(lib, meta);
setSize(800, (int) desc.getPreferredSize().getHeight()
+ 2 * desc.getBorderThickness());
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
-import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
import be.nikiroo.fanfix_swing.images.IconGenerator;
import be.nikiroo.fanfix_swing.images.IconGenerator.Icon;
import be.nikiroo.fanfix_swing.images.IconGenerator.Size;
+import be.nikiroo.utils.ui.ListenerPanel;
/**
* A generic search/filter bar.
import javax.swing.tree.TreePath;
import be.nikiroo.fanfix_swing.gui.SearchBar;
-import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
-import be.nikiroo.fanfix_swing.gui.utils.TreeCellSpanner;
-import be.nikiroo.fanfix_swing.gui.utils.TreeSnapshot;
-import be.nikiroo.fanfix_swing.gui.utils.UiHelper;
import be.nikiroo.fanfix_swing.images.IconGenerator;
import be.nikiroo.fanfix_swing.images.IconGenerator.Icon;
import be.nikiroo.fanfix_swing.images.IconGenerator.Size;
+import be.nikiroo.utils.ui.ListenerPanel;
+import be.nikiroo.utils.ui.TreeCellSpanner;
+import be.nikiroo.utils.ui.TreeSnapshot;
+import be.nikiroo.utils.ui.UIUtils;
public abstract class BasicTab<T> extends ListenerPanel {
private int totalCount = 0;
}
});
- add(UiHelper.scroll(tree), BorderLayout.CENTER);
+ add(UIUtils.scroll(tree, false), BorderLayout.CENTER);
searchBar = new SearchBar();
add(searchBar, BorderLayout.NORTH);
import be.nikiroo.fanfix.supported.BasicSupport;
import be.nikiroo.fanfix_swing.Actions;
import be.nikiroo.fanfix_swing.gui.SearchBar;
-import be.nikiroo.fanfix_swing.gui.utils.ListModel;
-import be.nikiroo.fanfix_swing.gui.utils.ListModel.Predicate;
import be.nikiroo.utils.Progress;
import be.nikiroo.utils.compat.JList6;
+import be.nikiroo.utils.ui.ListModel;
+import be.nikiroo.utils.ui.ListModel.Predicate;
public class ImporterFrame extends JFrame {
private ListModel<ImporterItem> data;
import javax.swing.SwingUtilities;
import be.nikiroo.fanfix_swing.gui.utils.CoverImager;
-import be.nikiroo.fanfix_swing.gui.utils.ListModel;
-import be.nikiroo.fanfix_swing.gui.utils.ListModel.Hoverable;
-import be.nikiroo.fanfix_swing.gui.utils.ListenerPanel;
import be.nikiroo.utils.Progress;
import be.nikiroo.utils.Progress.ProgressListener;
+import be.nikiroo.utils.ui.ListModel;
+import be.nikiroo.utils.ui.ListenerPanel;
+import be.nikiroo.utils.ui.ListModel.Hoverable;
public class ImporterItem extends ListenerPanel implements Hoverable {
static public final String CHANGE = "change";
--- /dev/null
+package be.nikiroo.fanfix_swing.gui.utils;
+
+import be.nikiroo.fanfix_swing.gui.book.BookInfo;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo.Type;
+
+public class DataNodeBook {
+ private Type type;
+ private String subname;
+ private String name;
+ private boolean children;
+ private boolean root;
+
+ private String display;
+
+ // root node
+ public DataNodeBook(Type type, boolean children) {
+ this(type, null, null, children);
+ this.root = true;
+ }
+
+ public DataNodeBook(Type type, String name, boolean root,
+ boolean children) {
+ this(type, name, null, children);
+ this.root = root;
+ }
+
+ // no root, no children, empty path
+ public DataNodeBook(Type type, String name) {
+ this(type, name, null, false);
+ this.root = false;
+ }
+
+ // name empty = main value for the group
+ // not root
+ public DataNodeBook(Type type, String name, String subname,
+ boolean children) {
+ this.type = type;
+ this.name = name == null ? "" : name;
+ this.subname = subname == null ? "" : subname;
+ this.children = children;
+ this.root = false;
+ }
+
+ public BookInfo.Type getType() {
+ return type;
+ }
+
+ public String getPath() {
+ String slash = "";
+ if (!name.isEmpty()) {
+ if (children || !subname.isEmpty()) {
+ slash = "/";
+ }
+ }
+
+ return name + slash + subname;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDisplay() {
+ if (display != null)
+ return display;
+
+ if (!subname.isEmpty()) {
+ return subname;
+ }
+
+ return name;
+ }
+
+ public void setDisplay(String display) {
+ this.display = display;
+ }
+
+ public boolean isRoot() {
+ return root;
+ }
+
+ @Override
+ public String toString() {
+ return getDisplay();
+ }
+}
--- /dev/null
+package be.nikiroo.fanfix_swing.gui.utils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo.Type;
+import be.nikiroo.utils.ui.DataNode;
+import be.nikiroo.utils.ui.DataTree;
+
+public class DataTreeAuthors extends DataTree<DataNodeBook> {
+ @Override
+ protected boolean checkFilter(String filter, DataNodeBook userData) {
+ return userData.toString().toLowerCase().contains(filter.toLowerCase());
+ }
+
+ @Override
+ protected DataNode<DataNodeBook> extractData() throws IOException {
+ List<DataNode<DataNodeBook>> nodes = new ArrayList<DataNode<DataNodeBook>>();
+
+ // TODO: getResult() -> getTagList, getAuthorList... ?
+ List<String> authors = Instance.getInstance().getLibrary().getAuthors();
+ for (String author : authors) {
+ nodes.add(new DataNode<DataNodeBook>(null,
+ new DataNodeBook(Type.AUTHOR, author)));
+ }
+
+ return new DataNode<DataNodeBook>(nodes,
+ new DataNodeBook(Type.AUTHOR, !nodes.isEmpty()));
+ }
+}
--- /dev/null
+package be.nikiroo.fanfix_swing.gui.utils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo.Type;
+import be.nikiroo.utils.ui.DataNode;
+import be.nikiroo.utils.ui.DataTree;
+
+public class DataTreeSources extends DataTree<DataNodeBook> {
+ @Override
+ protected boolean checkFilter(String filter, DataNodeBook userData) {
+ // TODO
+ return userData.toString().toLowerCase().contains(filter.toLowerCase());
+ }
+
+ @Override
+ protected DataNode<DataNodeBook> extractData() throws IOException {
+ List<DataNode<DataNodeBook>> nodes = new ArrayList<DataNode<DataNodeBook>>();
+
+ Map<String, List<String>> sourcesGrouped = Instance.getInstance()
+ .getLibrary().getSourcesGrouped();
+
+ List<String> sources = new ArrayList<String>(sourcesGrouped.keySet());
+ sort(sources);
+ for (String source : sources) {
+ List<String> children = sourcesGrouped.get(source);
+ boolean hasChildren = (children.size() > 1) || (children.size() == 1
+ && !children.get(0).trim().isEmpty());
+
+ List<DataNode<DataNodeBook>> subnodes = new ArrayList<DataNode<DataNodeBook>>();
+ if (hasChildren) {
+ sort(children);
+ for (String subSource : children) {
+ boolean baseSubSource = subSource.isEmpty()
+ && children.size() > 1;
+ DataNodeBook book = new DataNodeBook(Type.SOURCE, source,
+ subSource, false);
+ if (baseSubSource)
+ book.setDisplay("*");
+ subnodes.add(new DataNode<DataNodeBook>(null, book));
+ }
+ }
+
+ nodes.add(new DataNode<DataNodeBook>(subnodes,
+ new DataNodeBook(Type.SOURCE, source, "", hasChildren)));
+ }
+
+ return new DataNode<DataNodeBook>(nodes,
+ new DataNodeBook(Type.SOURCE, !nodes.isEmpty()));
+ }
+}
--- /dev/null
+package be.nikiroo.fanfix_swing.gui.utils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import be.nikiroo.fanfix.Instance;
+import be.nikiroo.fanfix.data.MetaData;
+import be.nikiroo.fanfix.library.MetaResultList;
+import be.nikiroo.fanfix_swing.gui.book.BookInfo.Type;
+import be.nikiroo.utils.ui.DataNode;
+import be.nikiroo.utils.ui.DataTree;
+
+public class DataTreeTag extends DataTree<DataNodeBook> {
+ @Override
+ protected boolean checkFilter(String filter, DataNodeBook userData) {
+ return userData.toString().toLowerCase().contains(filter.toLowerCase());
+ }
+
+ @Override
+ protected DataNode<DataNodeBook> extractData() throws IOException {
+ List<DataNode<DataNodeBook>> nodes = new ArrayList<DataNode<DataNodeBook>>();
+
+ List<String> tagList = new ArrayList<String>();
+ MetaResultList metas = Instance.getInstance().getLibrary().getList();
+ // TODO: getTagList, getAuthorList... ?
+ for (MetaData meta : metas.getMetas()) {
+ List<String> tags = meta.getTags();
+ if (tags != null) {
+ for (String tag : tags) {
+ if (!tagList.contains(tag)) {
+ tagList.add(tag);
+ }
+ }
+ }
+ }
+ sort(tagList);
+
+ for (String tag : tagList) {
+ nodes.add(new DataNode<DataNodeBook>(null,
+ new DataNodeBook(Type.TAG, tag)));
+ }
+
+ return new DataNode<DataNodeBook>(nodes,
+ new DataNodeBook(Type.TAG, !nodes.isEmpty()));
+ }
+}