1 package be
.nikiroo
.fanfix
.reader
.tui
;
3 import java
.util
.ArrayList
;
11 import jexer
.event
.TResizeEvent
;
12 import jexer
.event
.TResizeEvent
.Type
;
13 import be
.nikiroo
.fanfix
.data
.Chapter
;
14 import be
.nikiroo
.fanfix
.data
.MetaData
;
15 import be
.nikiroo
.fanfix
.data
.Paragraph
;
16 import be
.nikiroo
.fanfix
.data
.Paragraph
.ParagraphType
;
17 import be
.nikiroo
.fanfix
.data
.Story
;
18 import be
.nikiroo
.fanfix
.library
.BasicLibrary
;
20 class TuiReaderStoryWindow
extends TWindow
{
21 private BasicLibrary lib
;
22 private MetaData meta
;
24 private TText textField
;
25 private int chapter
= -1;
26 private List
<TButton
> navigationButtons
;
27 private TLabel currentChapter
;
29 // chapter: -1 for "none" (0 is desc)
30 public TuiReaderStoryWindow(TuiReaderApplication app
, BasicLibrary lib
,
31 MetaData meta
, int chapter
) {
32 super(app
, desc(meta
), 0, 0, 60, 18, CENTERED
| RESIZABLE
);
37 app
.setStatusBar(this, desc(meta
));
39 textField
= new TText(this, "", 0, 0, getWidth() - 2, getHeight() - 2);
41 navigationButtons
= new ArrayList
<TButton
>(5);
43 // -3 because 0-based and 2 for borders
44 int row
= getHeight() - 3;
46 navigationButtons
.add(addButton(" ", 0, row
, null)); // for bg colour
50 navigationButtons
.add(addButton("<< ", 0, row
, new TAction() {
56 navigationButtons
.add(addButton("< ", 4, row
, new TAction() {
59 setChapter(TuiReaderStoryWindow
.this.chapter
- 1);
62 navigationButtons
.add(addButton("> ", 7, row
, new TAction() {
65 setChapter(TuiReaderStoryWindow
.this.chapter
+ 1);
68 navigationButtons
.add(addButton(">> ", 10, row
, new TAction() {
71 setChapter(getStory().getChapters().size());
75 navigationButtons
.get(0).setEnabled(false);
76 navigationButtons
.get(1).setEnabled(false);
77 navigationButtons
.get(2).setEnabled(false);
79 currentChapter
= addLabel("", 14, row
);
80 currentChapter
.setWidth(getWidth() - 10);
85 public void onResize(TResizeEvent resize
) {
86 super.onResize(resize
);
88 // Resize the text field TODO: why setW/setH/reflow not enough for the
90 textField
.onResize(new TResizeEvent(Type
.WIDGET
, resize
.getWidth() - 2,
91 resize
.getHeight() - 2));
93 // -3 because 0-based and 2 for borders
94 int row
= getHeight() - 3;
96 String name
= currentChapter
.getLabel();
97 while (name
.length() < resize
.getWidth() - currentChapter
.getX()) {
100 currentChapter
.setLabel(name
);
101 currentChapter
.setWidth(resize
.getWidth() - 10);
102 currentChapter
.setY(row
);
104 for (TButton button
: navigationButtons
) {
110 * Display the current chapter in the window, or the {@link Story} info
114 * the chapter (including "0" which is the description) or "-1"
115 * to display the info page instead
117 private void setChapter(int chapter
) {
118 if (chapter
> getStory().getChapters().size()) {
119 chapter
= getStory().getChapters().size();
122 if (chapter
!= this.chapter
) {
123 this.chapter
= chapter
;
125 int max
= getStory().getChapters().size();
126 navigationButtons
.get(0).setEnabled(chapter
> -1);
127 navigationButtons
.get(1).setEnabled(chapter
> -1);
128 navigationButtons
.get(2).setEnabled(chapter
> -1);
129 navigationButtons
.get(3).setEnabled(chapter
< max
);
130 navigationButtons
.get(4).setEnabled(chapter
< max
);
132 StringBuilder builder
= new StringBuilder();
135 appendInfoPage(builder
);
137 appendChapterPage(builder
);
140 setText(builder
.toString());
143 setCurrentChapterText();
147 * Append the info page about the current {@link Story}.
150 * the builder to append to
152 private StringBuilder
appendInfoPage(StringBuilder builder
) {
153 MetaData meta
= getStory().getMeta();
155 // TODO: use a ttable?
157 appendTitle(builder
, meta
.getTitle(), 1).append("\n");
160 builder
.append("Author: ").append(meta
.getAuthor()).append("\n");
161 builder
.append("Publication date: ").append(meta
.getDate())
163 builder
.append("Word count: ").append(meta
.getWords()).append("\n");
169 * Append the current chapter.
172 * the builder to append to
174 private void appendChapterPage(StringBuilder builder
) {
177 chap
= getStory().getMeta().getResume();
178 } else if (chapter
> 0) {
179 chap
= getStory().getChapters().get(chapter
- 1);
183 String chapName
= chap
== null ?
"[No RESUME]" : chap
.getName();
186 String
.format("Chapter %d: %s", chapter
, chapName
), 1);
187 builder
.append("\n");
190 for (Paragraph para
: chap
) {
191 if (para
.getType() == ParagraphType
.BREAK
) {
192 builder
.append("\n");
194 builder
.append(para
.getContent()).append("\n");
195 if (para
.getType() == ParagraphType
.BREAK
) {
196 builder
.append("\n");
202 private Story
getStory() {
204 // TODO: progress bar?
205 story
= lib
.getStory(meta
.getLuid(), null);
211 * Display the given text on the window.
214 * the text to display
216 private void setText(String text
) {
217 textField
.setText(text
);
218 textField
.reflowData();
223 * Set the current chapter area to the correct value.
225 private void setCurrentChapterText() {
228 name
= " " + getStory().getMeta().getTitle();
229 } else if (chapter
== 0) {
230 Chapter resume
= getStory().getMeta().getResume();
231 if (resume
!= null) {
232 name
= String
.format(" %s", resume
.getName());
235 name
= "[No RESUME]";
238 int max
= getStory().getChapters().size();
239 Chapter chap
= getStory().getChapters().get(chapter
- 1);
240 name
= String
.format(" %d/%d: %s", chapter
, max
, chap
.getName());
243 int width
= getWidth() - currentChapter
.getX();
244 while (name
.length() < width
) {
248 if (name
.length() > width
) {
249 name
= name
.substring(0, width
);
252 currentChapter
.setLabel(name
);
256 private static String
desc(MetaData meta
) {
257 return String
.format("%s: %s", meta
.getLuid(), meta
.getTitle());
261 * Append a title (on its own 2 lines).
264 * the {@link StringBuilder} to append to
268 * the title level, 1 being the highest level, 2 second level and
271 private static StringBuilder
appendTitle(StringBuilder builder
,
272 String title
, int level
) {
292 int fullPad
= title
.length() / hr
.length();
293 int rest
= title
.length() - (fullPad
* hr
.length());
295 builder
.append(title
).append("\n");
296 for (int i
= 0; i
< title
.length() / hr
.length(); i
++) {
301 builder
.append(hr
.substring(0, rest
));
304 builder
.append("\n");