@@ 13,9 13,15 @@ typedef struct Slide {
char *lines[];
} Slide;
+typedef struct GalleryCell {
+ Image *img;
+ Rectangle location;
+} GalleryCell;
+
enum {
MenuNext = 0,
MenuPrev,
+ MenuGoto,
MenuExit,
MenuN
};
@@ 23,6 29,7 @@ enum {
char *menuitems[] = {
[MenuNext] = "Next Slide",
[MenuPrev] = "Prev Slide",
+ [MenuGoto] = "Goto Slide",
[MenuExit] = "Exit",
nil
};
@@ 44,9 51,10 @@ char *mimetab[] = {
int checkonly, lightmode, nslides, cslide, xm, ym;
char *file, *contents, *offset, *tfname, *hfname;
-Image *bg,*fg,*tmp, **images;
-Font *tfont, *hfont;
+Image *bg,*fg,*tmp;
+Font *tfont, *hfont, *nfont;
Slide **slides;
+GalleryCell *cells;
Point
SPt(int x, int y)
@@ 66,12 74,10 @@ imagecenter(Image* img)
return divpt(addpt(img->r.min, img->r.max), 2);
}
-double
-imageradius(Image* img)
+Point
+rectdims(Rectangle r)
{
- Point dims;
- dims = divpt(subpt(img->r.max, img->r.min), 2);
- return 1.4 + sqrt(dims.x*dims.x + dims.y*dims.y);
+ return subpt(r.max, r.min);
}
char *
@@ 324,28 330,31 @@ resizeimage(Image *img, Point sdims)
void
loadimages(void){
const Slide *s;
- Image **nextimg, *cimg;
+ GalleryCell *nextcell;
+ Image *cimg;
Point sdims;
- int i, j, cols, rows;
+ int i, j, cols, coln, rows, rowstart;
- if(images != nil)
+ if(cells != nil)
return;
s = slides[cslide];
- images = calloc(s->nlines, sizeof(Image*));
- nextimg = images;
+ cells = calloc(s->nlines, sizeof(GalleryCell));
+ nextcell = cells;
cols = 0;
i = 0;
while(i < s->nlines && *(s->lines[i]) == '\0') i++;
- for(; i < s->nlines; i++){
+ while(i < s->nlines){
cols++;
- while(i < s->nlines && *(s->lines[i]) != '\0') i++;
- while(i < s->nlines && *(s->lines[i]) == '\0') i++;
+ while(i < s->nlines && *(s->lines[i]) != '\0') i++;
+ while(i < s->nlines && *(s->lines[i]) == '\0') i++;
}
+ coln = -1;
rows = 0;
+ rowstart = 0;
for(i = 0; i < s->nlines; i++){
if(*(s->lines[i]) == '\0'){
@@ 353,9 362,13 @@ loadimages(void){
continue;
}
if(rows == 0){
+ coln++;
j = i;
- while(j < s->nlines && *(s->lines[j++]) != '\0')
+ rowstart = i;
+ while(j < s->nlines && *(s->lines[j]) != '\0'){
+ j++;
rows++;
+ }
}
sdims = subpt(screen->r.max, screen->r.min);
@@ 367,36 380,40 @@ loadimages(void){
sysfatal("couldn't convert '%s': %r", s->lines[i]);
waitpid();
- *nextimg = resizeimage(cimg, sdims);
- if(*nextimg == nil)
+ nextcell->img = resizeimage(cimg, sdims);
+ if(nextcell->img == nil)
sysfatal("couldn't scale '%s': %r", s->lines[i]);
freeimage(cimg);
+
+ nextcell->location = Rpt(Pt(0,0), sdims);
+ nextcell->location = rectaddpt(nextcell->location, Pt(sdims.x * coln, sdims.y * (i - rowstart)));
+ nextcell->location = rectaddpt(nextcell->location, screen->r.min);
- nextimg++;
+ nextcell++;
}
}
void
freeimages(void){
const Slide *s;
- Image **p;
+ GalleryCell *p;
int i;
- if(images == nil)
+ if(cells == nil)
return;
s = slides[cslide];
- p = images;
+ p = cells;
for(i = 0; i < s->nlines; i++){
if(*(s->lines[i]) == '\0')
continue;
- freeimage(*p);
+ freeimage(p->img);
p++;
}
- free(images);
- images = nil;
+ free(cells);
+ cells = nil;
}
void
rmtmp(void)
@@ 411,8 428,10 @@ void
render(void)
{
int i, voff, height, width;
- Point p, center, prog0, prog1, smin, smax;
+ char buf[32];
+ Point p, center, prog0, prog1, smin, smax, imin, imax;
const Slide *s;
+ GalleryCell *cell;
if(cslide < 0)
cslide = 0;
@@ 425,14 444,11 @@ render(void)
smin = screen->r.min;
smax = screen->r.max;
- draw(screen, screen->r, bg, nil, SPt(0, 0));
+ if(strcmp(s->cmd, "blank") == 0)
+ draw(screen, screen->r, bg, nil, SPt(0, 0));
+ else if(strcmp(s->cmd, "text") == 0){
+ draw(screen, screen->r, bg, nil, SPt(0, 0));
- prog0 = Pt(smin.x, smax.y);
- prog1 = Pt(smin.x + cslide + (smax.x - smin.x) / (nslides - 1) * cslide, smax.y);
- if(cslide != 0)
- line(screen, prog0, prog1, Endsquare, Enddisc, 5, fg, Pt(0,0));
-
- if(strcmp(s->cmd, "text") == 0){
voff = ym;
if(s->arg != nil){
string(screen, SPt(xm, ym), fg, Pt(0, 0), hfont, s->arg);
@@ 444,6 460,8 @@ render(void)
voff += tfont->height;
}
}else if(strcmp(s->cmd, "title") == 0){
+ draw(screen, screen->r, bg, nil, SPt(0, 0));
+
height = hfont->height + tfont->height * s->nlines;
voff = center.y - (height / 2);
@@ 462,8 480,34 @@ render(void)
}else if(strcmp(s->cmd, "gallery") == 0){
loadimages();
- p = divpt(subpt(subpt(screen->r.max, screen->r.min), subpt(images[0]->r.max, images[0]->r.min)), -2);
- draw(screen, screen->r, images[0], nil, p);
+ draw(screen, screen->r, bg, nil, SPt(0, 0));
+
+ cell = cells;
+
+ for(i = 0; i < s->nlines; i++){
+ if(*(s->lines[i]) == '\0')
+ continue;
+
+ imin = cell->img->r.min;
+ imax = cell->img->r.max;
+
+ p = divpt(subpt(rectdims(cell->img->r), rectdims(cell->location)), 2);
+
+ draw(screen, cell->location, cell->img, nil, p);
+
+ cell++;
+ }
+ }
+
+ if(cslide != 0){
+ prog0 = Pt(smin.x, smax.y);
+ prog1 = Pt(smin.x + cslide + (smax.x - smin.x) / (nslides - 1) * cslide, smax.y);
+
+ line(screen, Pt(smin.x, smax.y), smax, Endsquare, Endsquare, 5, bg, Pt(0,0));
+ line(screen, prog0, prog1, Endsquare, Enddisc, 5, fg, Pt(0,0));
+
+ sprint(buf, "Slide %d", cslide);
+ stringbg(screen, Pt(5, smax.y - 5 - nfont->height), fg, Pt(0,0), nfont, buf, bg, Pt(0,0));
}
}
@@ 487,7 531,7 @@ void
main(int argc, char *argv[])
{
int etype, fd, i, linum;
- char slabel[32];
+ char slabel[32], ask[32];
Event e;
Mouse m, lastm;
Dir *d;
@@ 524,6 568,9 @@ main(int argc, char *argv[])
if(argc != 1)
usage();
+ fmtinstall('P', Pfmt);
+ fmtinstall('R', Rfmt);
+
file = argv[0];
if((fd = open(file, OREAD)) < 0)
@@ 550,6 597,7 @@ main(int argc, char *argv[])
exits(nil);
atexit(rmtmp);
+ atexit(freeimages);
slides = malloc(nslides*sizeof(Slide*));
for(i = 0; i < nslides; i++){
@@ 587,9 635,11 @@ main(int argc, char *argv[])
hfont = openfont(display, hfname);
if(hfont == nil)
sysfatal("couldn't open font '%s'", hfname);
+ nfont = openfont(display, "/lib/font/bit/vga/unicode.font");
+ if(nfont == nil)
+ sysfatal("couldn't open font '/lib/bit/vga/unicode.font'");
-
- einit(Emouse);
+ einit(Emouse|Ekeyboard);
for(;;){
render();
@@ 606,25 656,51 @@ main(int argc, char *argv[])
cslide++;
}
- menu.lasthit = -1;
- if(m.buttons & 2)
+ if(m.buttons & 2){
emenuhit(2, &m, &menu);
- switch(menu.lasthit){
- case MenuNext:
+ switch(menu.lasthit){
+ case MenuNext:
+ freeimages();
+ cslide++;
+ break;
+ case MenuPrev:
+ freeimages();
+ cslide--;
+ break;
+ case MenuGoto:
+ sprintf(ask, "%d", cslide);
+ if(eenter("Go to", ask, sizeof(ask), &m) <= 0)
+ break;
+ freeimages();
+ if(strncmp(ask, "end", 3) == 0)
+ cslide = nslides;
+ else
+ cslide = atoi(ask);
+ break;
+ case MenuExit:
+ exits(nil);
+ break;
+ }
+ }
+
+ lastm = m;
+ }else if(etype == Ekeyboard){
+ switch(e.kbdc){
+ case 0xf012:
+ case ' ':
freeimages();
cslide++;
break;
- case MenuPrev:
+ case 0xf011:
freeimages();
cslide--;
break;
- case MenuExit:
+ case 0x7f:
+ case 'q':
exits(nil);
break;
}
-
- lastm = m;
}
}
}