b57bdc41fce373325a1a9a764fd77f2db18b33ab
[fanfix.git] / src / be / nikiroo / fanfix / reader / ui / GuiReaderViewer.java
1 package be.nikiroo.fanfix.reader.ui;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Font;
6 import java.awt.LayoutManager;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9
10 import javax.swing.BorderFactory;
11 import javax.swing.BoxLayout;
12 import javax.swing.JButton;
13 import javax.swing.JFrame;
14 import javax.swing.JLabel;
15 import javax.swing.JPanel;
16 import javax.swing.SwingConstants;
17
18 import be.nikiroo.fanfix.bundles.StringIdGui;
19 import be.nikiroo.fanfix.data.Chapter;
20 import be.nikiroo.fanfix.data.MetaData;
21 import be.nikiroo.fanfix.data.Story;
22 import be.nikiroo.fanfix.library.BasicLibrary;
23
24 /**
25 * An internal, Swing-based {@link Story} viewer.
26 * <p>
27 * Works on both text and image document (see {@link MetaData#isImageDocument()}
28 * ).
29 *
30 * @author niki
31 */
32 public class GuiReaderViewer extends JFrame {
33 private static final long serialVersionUID = 1L;
34
35 private Story story;
36 private MetaData meta;
37 private JLabel title;
38 private JLabel chapterLabel;
39 private GuiReaderPropertiesPane descPane;
40 private int currentChapter = -42; // cover = -1
41 private GuiReaderViewerPanel mainPanel;
42 private JButton[] navButtons;
43
44 /**
45 * Create a new {@link Story} viewer.
46 *
47 * @param lib
48 * the {@link BasicLibrary} to load the cover from
49 * @param story
50 * the {@link Story} to display
51 */
52 public GuiReaderViewer(BasicLibrary lib, Story story) {
53 setTitle(GuiReader.trans(StringIdGui.TITLE_STORY, story.getMeta()
54 .getLuid(), story.getMeta().getTitle()));
55
56 setSize(800, 600);
57
58 this.story = story;
59 this.meta = story.getMeta();
60
61 initGuiBase(lib);
62 initGuiNavButtons();
63
64 setChapter(-1);
65 }
66
67 /**
68 * Initialise the base panel with everything but the navigation buttons.
69 *
70 * @param lib
71 * the {@link BasicLibrary} to use to retrieve the cover image in
72 * the description panel
73 */
74 private void initGuiBase(BasicLibrary lib) {
75 setLayout(new BorderLayout());
76
77 title = new JLabel();
78 title.setFont(new Font(Font.SERIF, Font.BOLD,
79 title.getFont().getSize() * 3));
80 title.setText(meta.getTitle());
81 title.setHorizontalAlignment(SwingConstants.CENTER);
82 title.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
83 add(title, BorderLayout.NORTH);
84
85 JPanel contentPane = new JPanel(new BorderLayout());
86 add(contentPane, BorderLayout.CENTER);
87
88 descPane = new GuiReaderPropertiesPane(lib, meta);
89 contentPane.add(descPane, BorderLayout.NORTH);
90
91 mainPanel = new GuiReaderViewerPanel(story);
92 contentPane.add(mainPanel, BorderLayout.CENTER);
93 }
94
95 /**
96 * Create the 4 navigation buttons in {@link GuiReaderViewer#navButtons} and
97 * initialise them.
98 */
99 private void initGuiNavButtons() {
100 JPanel navButtonsPane = new JPanel();
101 LayoutManager layout = new BoxLayout(navButtonsPane, BoxLayout.X_AXIS);
102 navButtonsPane.setLayout(layout);
103
104 navButtons = new JButton[4];
105
106 navButtons[0] = createNavButton("<<", new ActionListener() {
107 @Override
108 public void actionPerformed(ActionEvent e) {
109 setChapter(-1);
110 }
111 });
112 navButtons[1] = createNavButton(" < ", new ActionListener() {
113 @Override
114 public void actionPerformed(ActionEvent e) {
115 setChapter(currentChapter - 1);
116 }
117 });
118 navButtons[2] = createNavButton(" > ", new ActionListener() {
119 @Override
120 public void actionPerformed(ActionEvent e) {
121 setChapter(currentChapter + 1);
122 }
123 });
124 navButtons[3] = createNavButton(">>", new ActionListener() {
125 @Override
126 public void actionPerformed(ActionEvent e) {
127 setChapter(story.getChapters().size() - 1);
128 }
129 });
130
131 for (JButton navButton : navButtons) {
132 navButtonsPane.add(navButton);
133 }
134
135 add(navButtonsPane, BorderLayout.SOUTH);
136
137 chapterLabel = new JLabel("");
138 navButtonsPane.add(chapterLabel);
139 }
140
141 /**
142 * Create a single navigation button.
143 *
144 * @param text
145 * the text to display
146 * @param action
147 * the action to take on click
148 * @return the button
149 */
150 private JButton createNavButton(String text, ActionListener action) {
151 JButton navButton = new JButton(text);
152 navButton.addActionListener(action);
153 navButton.setForeground(Color.BLUE);
154 return navButton;
155 }
156
157 /**
158 * Set the current chapter, 0-based.
159 * <p>
160 * Chapter -1 is reserved for the description page.
161 *
162 * @param chapter
163 * the chapter number to set
164 */
165 private void setChapter(int chapter) {
166 navButtons[0].setEnabled(chapter >= 0);
167 navButtons[1].setEnabled(chapter >= 0);
168 navButtons[2].setEnabled(chapter + 1 < story.getChapters().size());
169 navButtons[3].setEnabled(chapter + 1 < story.getChapters().size());
170
171 if (chapter >= -1 && chapter < story.getChapters().size()
172 && chapter != currentChapter) {
173 currentChapter = chapter;
174
175 Chapter chap;
176 if (chapter == -1) {
177 chap = meta.getResume();
178 descPane.setVisible(true);
179 } else {
180 chap = story.getChapters().get(chapter);
181 descPane.setVisible(false);
182 }
183
184 String chapterDisplay = GuiReader.trans(
185 StringIdGui.CHAPTER_HTML_UNNAMED, chap.getNumber(), story
186 .getChapters().size());
187 if (chap.getName() != null && !chap.getName().trim().isEmpty()) {
188 chapterDisplay = GuiReader.trans(
189 StringIdGui.CHAPTER_HTML_NAMED, chap.getNumber(), story
190 .getChapters().size(), chap.getName());
191 }
192
193 chapterLabel.setText("<HTML>" + chapterDisplay + "</HTML>");
194
195 mainPanel.setChapter(chap);
196 }
197 }
198 }