commit
edb3e9878a
|
|
@ -1 +1,2 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
|
0.02: Make font size selectable
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@ Very basic text reader with an integrated file selector.
|
||||||
## Controls
|
## Controls
|
||||||
|
|
||||||
Bangle.js 2
|
Bangle.js 2
|
||||||
- tap the right side of the screen to flip to the next page
|
- tap the bottom right corner of the screen to flip to the next page
|
||||||
- tap the left side of the screen to flip to the previous page
|
- tap the bottom left corner of the screen to flip to the previous page
|
||||||
|
- tap the top left corner of the screen to toggle font size and go back to page 1
|
||||||
- exit by pressing the physical button
|
- exit by pressing the physical button
|
||||||
|
|
||||||
## Creator
|
## Creator
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,61 @@
|
||||||
|
/* ui library 0.1.4 -- forked/modified for txtreader */
|
||||||
|
let ui = {
|
||||||
|
display: 0,
|
||||||
|
drawMsg: function(msg) {
|
||||||
|
g.reset().setFont("Vector", 35)
|
||||||
|
.setColor(1, 1, 1)
|
||||||
|
.fillRect(0, this.wi, this.w, this.y2)
|
||||||
|
.setColor(0, 0, 0)
|
||||||
|
.drawString(msg, 5, 30)
|
||||||
|
.flip();
|
||||||
|
},
|
||||||
|
drawBusy: function() {
|
||||||
|
this.drawMsg("\n.oO busy");
|
||||||
|
},
|
||||||
|
nextScreen: function() {},
|
||||||
|
prevScreen: function() {},
|
||||||
|
onSwipe: function(dir) {
|
||||||
|
this.nextScreen();
|
||||||
|
},
|
||||||
|
wi: 24,
|
||||||
|
y2: 176,
|
||||||
|
h: 152,
|
||||||
|
w: 176,
|
||||||
|
last_b: 0,
|
||||||
|
topLeft: function() { this.drawMsg("Unimpl"); },
|
||||||
|
topRight: function() { this.drawMsg("Unimpl"); },
|
||||||
|
touchHandler: function(d) {
|
||||||
|
let x = Math.floor(d.x);
|
||||||
|
let y = Math.floor(d.y);
|
||||||
|
|
||||||
|
if (d.b != 1 || this.last_b != 0) {
|
||||||
|
this.last_b = d.b;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("touch", x, y, this.h, this.w);
|
||||||
|
|
||||||
|
if ((x<this.w/2) && (y<this.y2/2))
|
||||||
|
this.topLeft();
|
||||||
|
if ((x>this.w/2) && (y<this.y2/2))
|
||||||
|
this.topRight();
|
||||||
|
if ((x<this.w/2) && (y>this.y2/2)) {
|
||||||
|
print("prev");
|
||||||
|
this.prevScreen();
|
||||||
|
}
|
||||||
|
if ((x>this.w/2) && (y>this.y2/2)) {
|
||||||
|
print("next");
|
||||||
|
this.nextScreen();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
init: function() {
|
||||||
|
this.h = this.y2 - this.wi;
|
||||||
|
this.drawBusy();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
ui.init();
|
||||||
|
|
||||||
function showFileSelector() {
|
function showFileSelector() {
|
||||||
let files = require("Storage").list().filter(f => f.endsWith('.txt'));
|
let files = require("Storage").list().filter(f => f.endsWith('.txt'));
|
||||||
|
|
||||||
|
|
@ -18,6 +76,8 @@ function showFileSelector() {
|
||||||
E.showMenu(menuItems);
|
E.showMenu(menuItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var big = 0;
|
||||||
|
|
||||||
function onFileSelected(file) {
|
function onFileSelected(file) {
|
||||||
const chunkSize = 1024;
|
const chunkSize = 1024;
|
||||||
let currentOffset = 0;
|
let currentOffset = 0;
|
||||||
|
|
@ -25,27 +85,39 @@ function onFileSelected(file) {
|
||||||
let history = [];
|
let history = [];
|
||||||
|
|
||||||
function displayText(offset, pageNumber) {
|
function displayText(offset, pageNumber) {
|
||||||
|
let border = 10;
|
||||||
|
let char_h = 10;
|
||||||
|
let char_w = 6;
|
||||||
g.clear();
|
g.clear();
|
||||||
|
if (!big) {
|
||||||
g.setFont("6x8", 1);
|
g.setFont("6x8", 1);
|
||||||
|
} else {
|
||||||
|
g.setFont("12x20", 1);
|
||||||
|
}
|
||||||
|
char_h = g.getFontHeight();
|
||||||
|
char_w = g.stringWidth("w");
|
||||||
|
|
||||||
g.setColor(g.theme.fg);
|
g.setColor(g.theme.fg);
|
||||||
g.drawString("Page " + pageNumber, 10, 2);
|
g.drawString("Page " + pageNumber, border, 2);
|
||||||
//g.drawString("Offset " + offset, 60, 2);
|
//g.drawString("Offset " + offset, 60, 2);
|
||||||
g.drawString(file, g.getWidth() - file.length * 6, 2);
|
g.drawString(file, g.getWidth() - file.length * char_w, 2);
|
||||||
|
// This can be used as a feedback that touch was registered
|
||||||
|
//g.flip();
|
||||||
|
|
||||||
var text = require("Storage").read(file, offset, chunkSize);
|
var text = require("Storage").read(file, offset, chunkSize);
|
||||||
var lines = text.split("\n");
|
var lines = text.split("\n");
|
||||||
var y = 15; // Text start, top row reserved for page number
|
var y = 5+char_h; // Text start, top row reserved for page number
|
||||||
var linesDisplayed = 0; // Lines per page
|
var linesDisplayed = 0; // Lines per page
|
||||||
var totalCharsDisplayed = 0; // Total characters per page
|
var totalCharsDisplayed = 0; // Total characters per page
|
||||||
|
|
||||||
for (var i = 0; i < lines.length; i++) {
|
for (var i = 0; i < lines.length; i++) {
|
||||||
var wrappedLines = g.wrapString(lines[i], g.getWidth() - 20);
|
var wrappedLines = g.wrapString(lines[i], g.getWidth() - 2*border);
|
||||||
for (var j = 0; j < wrappedLines.length; j++) {
|
for (var j = 0; j < wrappedLines.length; j++) {
|
||||||
g.drawString(wrappedLines[j], 10, y);
|
g.drawString(wrappedLines[j], border, y);
|
||||||
y += 10; // Move down for the next line
|
y += char_h; // Move down for the next line
|
||||||
linesDisplayed++;
|
linesDisplayed++;
|
||||||
totalCharsDisplayed += wrappedLines[j].length + (j < wrappedLines.length - 1 ? 0 : 1); // Add newline character for the last wrapped line
|
totalCharsDisplayed += wrappedLines[j].length + (j < wrappedLines.length - 1 ? 0 : 1); // Add newline character for the last wrapped line
|
||||||
if (y >= g.getHeight() - 10) {
|
if (y >= g.getHeight() - char_h) {
|
||||||
// If we run out of space, stop drawing
|
// If we run out of space, stop drawing
|
||||||
return { nextOffset: offset + totalCharsDisplayed, linesDisplayed: linesDisplayed };
|
return { nextOffset: offset + totalCharsDisplayed, linesDisplayed: linesDisplayed };
|
||||||
}
|
}
|
||||||
|
|
@ -54,13 +126,7 @@ function onFileSelected(file) {
|
||||||
return null; // No more lines to display
|
return null; // No more lines to display
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial display
|
function nextPage() {
|
||||||
var result = displayText(currentOffset, currentPage);
|
|
||||||
history.push({ offset: currentOffset, linesDisplayed: result.linesDisplayed });
|
|
||||||
|
|
||||||
// Handle touch events
|
|
||||||
Bangle.on('touch', function(button) {
|
|
||||||
if (button === 2) { // Right side of the screen (next page)
|
|
||||||
var nextOffset = displayText(currentOffset, currentPage + 1);
|
var nextOffset = displayText(currentOffset, currentPage + 1);
|
||||||
if (nextOffset !== null) {
|
if (nextOffset !== null) {
|
||||||
currentOffset = nextOffset.nextOffset;
|
currentOffset = nextOffset.nextOffset;
|
||||||
|
|
@ -70,10 +136,12 @@ function onFileSelected(file) {
|
||||||
} else {
|
} else {
|
||||||
currentOffset = 0;
|
currentOffset = 0;
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
|
let result = displayText(currentOffset, currentPage);
|
||||||
history = [{ offset: currentOffset, linesDisplayed: result.linesDisplayed }];
|
history = [{ offset: currentOffset, linesDisplayed: result.linesDisplayed }];
|
||||||
displayText(currentOffset, currentPage);
|
|
||||||
}
|
}
|
||||||
} else if (button === 1) { // Left side of the screen (previous page)
|
}
|
||||||
|
|
||||||
|
function prevPage() {
|
||||||
if (currentPage > 1) {
|
if (currentPage > 1) {
|
||||||
history.pop(); // Remove current page from history
|
history.pop(); // Remove current page from history
|
||||||
var previousPage = history[history.length - 1];
|
var previousPage = history[history.length - 1];
|
||||||
|
|
@ -82,7 +150,30 @@ function onFileSelected(file) {
|
||||||
displayText(currentOffset, currentPage);
|
displayText(currentOffset, currentPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
function zoom() {
|
||||||
|
g.clear();
|
||||||
|
big = !big;
|
||||||
|
firstDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function firstDraw() {
|
||||||
|
currentOffset = 0;
|
||||||
|
currentPage = 1;
|
||||||
|
history = [];
|
||||||
|
|
||||||
|
// Initial display
|
||||||
|
var result = displayText(currentOffset, currentPage);
|
||||||
|
history.push({ offset: currentOffset, linesDisplayed: result.linesDisplayed });
|
||||||
|
}
|
||||||
|
|
||||||
|
ui.init();
|
||||||
|
ui.prevScreen = prevPage;
|
||||||
|
ui.nextScreen = nextPage;
|
||||||
|
ui.topLeft = zoom;
|
||||||
|
firstDraw();
|
||||||
|
|
||||||
|
Bangle.on("drag", (b) => ui.touchHandler(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
showFileSelector();
|
showFileSelector();
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "txtreader",
|
"id": "txtreader",
|
||||||
"name": "txtreader",
|
"name": "txtreader",
|
||||||
"shortName": "txtreader",
|
"shortName": "txtreader",
|
||||||
"version": "0.01",
|
"version": "0.02",
|
||||||
"description": "Basic text reader with pages and a file selector.",
|
"description": "Basic text reader with pages and a file selector.",
|
||||||
"icon": "txtreader.png",
|
"icon": "txtreader.png",
|
||||||
"screenshots": [{"url":"screenshot_txtreader.png"}],
|
"screenshots": [{"url":"screenshot_txtreader.png"}],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue