More panelreels work #52 (#92)

* setup_signals: handle SIGSEGV with restore

* wresize(): fix keep parameter to ncplane_resize() #52

* ncplane_resize: set new lenx/leny on keep #80

* hrmrmm

* ncplane_resize(): fix numerous confusions

* panelreel-demo: don't allow us to go off the left edge

* panelreel: place tablets correctly #52

* panelreel: set background on focused element
pull/93/head
Nick Black 5 years ago committed by GitHub
parent 426f632300
commit 0b967ae528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -82,6 +82,7 @@ tabletup(struct ncplane* w, int begx, int begy, int maxx, int maxy,
// lower-right corner always returns an error unless scrollok() is used
ncplane_putc(w, &c);
}
cell_release(w, &c);
if(--idx == 0){
break;
}
@ -109,6 +110,7 @@ tabletdown(struct ncplane* w, int begx, int begy, int maxx, int maxy,
// lower-right corner always returns an error unless scrollok() is used
ncplane_putc(w, &c);
}
cell_release(w, &c);
}
return y - begy;
}
@ -253,6 +255,7 @@ panelreel_demo_core(struct notcurses* nc, int efd, tabletctx** tctxs){
.boff = 0,
};
cell_set_fg(&popts.focusedattr, 58, 150, 221);
cell_set_bg(&popts.focusedattr, 97, 214, 214);
cell_set_fg(&popts.tabletattr, 19, 161, 14);
cell_set_fg(&popts.borderattr, 136, 23, 152);
struct ncplane* w = notcurses_stdplane(nc);
@ -291,7 +294,7 @@ panelreel_demo_core(struct notcurses* nc, int efd, tabletctx** tctxs){
case 'a': newtablet = new_tabletctx(pr, &id); break;
case 'b': newtablet = new_tabletctx(pr, &id); break;
case 'c': newtablet = new_tabletctx(pr, &id); break;
case 'h': --x; if(panelreel_move(pr, x, y)){ ++x; } break;
case 'h': if(x > 0) { --x; if(panelreel_move(pr, x, y)){ ++x; } } break;
case 'l': ++x; if(panelreel_move(pr, x, y)){ --x; } break;
case 'k': panelreel_prev(pr); break;
case 'j': panelreel_next(pr); break;

@ -90,7 +90,7 @@ sigwinch_handler(int signo){
}
// this wildly unsafe handler will attempt to restore the screen upon
// reception of a SIGINT or SIGQUIT. godspeed you, black emperor!
// reception of SIGINT, SIGSEGV, or SIGQUIT. godspeed you, black emperor!
static void
fatal_handler(int signo){
notcurses* nc = atomic_load(&signal_nc);
@ -129,7 +129,11 @@ setup_signals(notcurses* nc, bool no_quit_sigs, bool no_winch_sig){
sigaddset(&sa.sa_mask, SIGINT);
sigaddset(&sa.sa_mask, SIGQUIT);
sa.sa_flags = SA_RESETHAND; // don't try twice
if(sigaction(SIGINT, &sa, &oldact) || sigaction(SIGQUIT, &sa, &oldact)){
int ret = 0;
ret |= sigaction(SIGINT, &sa, &oldact);
ret |= sigaction(SIGQUIT, &sa, &oldact);
ret |= sigaction(SIGSEGV, &sa, &oldact);
if(ret){
atomic_store(&signal_nc, NULL);
fprintf(stderr, "Error installing fatal signal handlers (%s)\n",
strerror(errno));
@ -393,24 +397,31 @@ ncplane* notcurses_newplane(notcurses* nc, int rows, int cols,
int ncplane_resize(ncplane* n, int keepy, int keepx, int keepleny,
int keeplenx, int yoff, int xoff, int ylen, int xlen){
if(n == n->nc->stdscr){
fprintf(stderr, "Can't resize standard plane\n");
return -1;
}
if(keepy < 0 || keepx < 0){ // can't retain negative size
if(keepleny < 0 || keeplenx < 0){ // can't retain negative size
fprintf(stderr, "Can't retain negative size %dx%d\n", keepleny, keeplenx);
return -1;
}
if(ylen <= 0 || xlen <= 0){ // can't resize to trivial or negative size
fprintf(stderr, "Can't achieve negative size %dx%d\n", ylen, xlen);
return -1;
}
if((!keepy && keepx) || (keepy && !keepx)){ // both must be 0
if((!keepleny && keeplenx) || (keepleny && !keeplenx)){ // both must be 0
fprintf(stderr, "Can't keep zero dimensions %dx%d\n", keepleny, keeplenx);
return -1;
}
if(ylen < keepleny || xlen < keeplenx){ // can't be smaller than our keep
fprintf(stderr, "Can't violate space %dx%d vs %dx%d\n", keepleny, keeplenx, ylen, xlen);
return -1;
}
fprintf(stderr, "NCPLANE(RESIZING) to %dx%d at %d/%d (keeping %dx%d from %d/%d)\n",
ylen, xlen, yoff, xoff, keepleny, keeplenx, keepy, keepx);
// we're good to resize. we'll need alloc up a new framebuffer, and copy in
// those elements we're retaining, zeroing out the rest. alternatively, if
// we've shrunk, we will be filling the new structure.
int keptarea = keepy * keepx;
int keptarea = keepleny * keeplenx;
int newarea = ylen * xlen;
cell* fb = malloc(sizeof(*fb) * newarea);
if(fb == NULL){
@ -425,8 +436,10 @@ int ncplane_resize(ncplane* n, int keepy, int keepx, int keepleny,
}
cell* preserved = n->fb;
n->fb = fb;
fprintf(stderr, "ABS: %d %d\n", n->absy, n->absx);
n->absy = n->absy + keepy - yoff;
n->absx = n->absx + keepx - xoff;
fprintf(stderr, "ABS: %d %d\n", n->absy, n->absx);
// if we're keeping nothing, dump the old egcspool. otherwise, we go ahead
// and keep it. perhaps we ought compact it?
if(keptarea == 0){ // keep nothing, resize/move only
@ -448,7 +461,7 @@ int ncplane_resize(ncplane* n, int keepy, int keepx, int keepleny,
for(itery = 0 ; itery < ylen ; ++itery){
int copyoff = itery * xlen; // our target at any given time
// if we have nothing copied to this line, zero it out in one go
if(itery < keepy + yoff || itery > keepy + keepleny - 1 + yoff){
if(itery < keepy || itery > keepy + keepleny - 1){
memset(fb + copyoff, 0, sizeof(*fb) * xlen);
continue;
}
@ -460,14 +473,16 @@ int ncplane_resize(ncplane* n, int keepy, int keepx, int keepleny,
copied += -xoff;
}
const int sourceidx = fbcellidx(n, sourceline, keepx);
memcpy(fb + copyoff, preserved + sourceidx, sizeof(*fb) * keepx);
copyoff += keepx;
copied += keepx;
memcpy(fb + copyoff, preserved + sourceidx, sizeof(*fb) * keeplenx);
copyoff += keeplenx;
copied += keeplenx;
if(xlen > copied){
memset(fb + copyoff, 0, sizeof(*fb) * (xlen - copied));
}
++sourceline;
}
n->lenx = xlen;
n->leny = ylen;
free(preserved);
return 0;
}

@ -52,11 +52,10 @@ window_coordinates(const ncplane* w, int* begy, int* begx, int* leny, int* lenx)
// FIXME compatability wrapper for libpanel
int wresize(ncplane* n, int leny, int lenx){
int y, x;
ncplane_yx(n, &y, &x);
int dimy, dimx;
ncplane_dim_yx(n, &dimy, &dimx);
return ncplane_resize(n, 0, 0, dimy, dimx, y, x, leny, lenx);
int keepy = dimy > leny ? leny : dimy;
return ncplane_resize(n, 0, 0, keepy, dimx, 0, 0, leny, lenx);
}
// bchrs: 6-element array of wide border characters + attributes FIXME
@ -76,8 +75,8 @@ draw_borders(ncplane* w, unsigned nobordermask, const cell* attr,
if(ncplane_rounded_box_cells(w, &ul, &ur, &ll, &lr, &hl, &vl)){
return -1;
}
fprintf(stderr, "drawing borders %d/%d->%d/%d, mask: %04x, clipping: %c%c\n",
begx, begy, maxx, maxy, nobordermask,
fprintf(stderr, "drawing borders %p %d/%d->%d/%d, mask: %04x, clipping: %c%c\n",
w, begx, begy, maxx, maxy, nobordermask,
cliphead ? 'T' : 't', clipfoot ? 'F' : 'f');
ul.attrword = attr->attrword; ul.channels = attr->channels;
ur.attrword = attr->attrword; ur.channels = attr->channels;
@ -228,7 +227,7 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
int lenx, leny, begy, begx;
ncplane* fp = t->p;
if(tablet_columns(pr, &begx, &begy, &lenx, &leny, frontiery, direction)){
//fprintf(stderr, "no room: %p:%p base %d/%d len %d/%d\n", t, fp, begx, begy, lenx, leny);
fprintf(stderr, "no room: %p:%p base %d/%d len %d/%d\n", t, fp, begx, begy, lenx, leny);
// fprintf(stderr, "FRONTIER DONE!!!!!!\n");
if(fp){
// fprintf(stderr, "HIDING %p at frontier %d (dir %d) with %d\n", t, frontiery, direction, leny);
@ -287,8 +286,8 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
// fprintf(stderr, "calling! lenx/leny: %d/%d cbx/cby: %d/%d cbmaxx/cbmaxy: %d/%d dir: %d\n",
// lenx, leny, cbx, cby, cbmaxx, cbmaxy, direction);
int ll = t->cbfxn(fp, cbx, cby, cbmaxx, cbmaxy, cbdir, t->curry);
//fprintf(stderr, "RETURNRETURNRETURN %p %d (%d, %d, %d) DIR %d\n",
// t, ll, cby, cbmaxy, leny, direction);
fprintf(stderr, "RETURNRETURNRETURN %p %d (%d, %d, %d) DIR %d\n",
t, ll, cby, cbmaxy, leny, direction);
if(ll != leny){
if(ll == leny - 1){ // only has one border visible (partially off-screen)
++ll; // account for that border
@ -296,17 +295,17 @@ panelreel_draw_tablet(const panelreel* pr, tablet* t, int frontiery,
if(direction < 0){
cliphead = true;
ncplane_move_yx(fp, begy + leny - ll, begx);
// fprintf(stderr, "MOVEDOWN CLIPPED RESIZED (-1) from %d to %d\n", leny, ll);
fprintf(stderr, "MOVEDOWN CLIPPED RESIZED (-1) from %d to %d\n", leny, ll);
}else{
clipfoot = true;
// fprintf(stderr, "RESIZED (-1) from %d to %d\n", leny, ll);
fprintf(stderr, "RESIZED (-1) from %d to %d\n", leny, ll);
}
}else{ // both borders are visible
ll += 2; // account for both borders
// fprintf(stderr, "RESIZING (-2) from %d to %d\n", leny, ll);
fprintf(stderr, "RESIZING (-2) from %d to %d\n", leny, ll);
wresize(fp, ll, lenx);
if(direction < 0){
// fprintf(stderr, "MOVEDOWN UNCLIPPED (skip %d)\n", leny - ll);
fprintf(stderr, "MOVEDOWN UNCLIPPED (skip %d)\n", leny - ll);
ncplane_move_yx(fp, begy + leny - ll, begx);
}
}
@ -597,7 +596,7 @@ panelreel* panelreel_create(ncplane* w, const panelreel_options* popts, int efd)
return pr;
}
// we've just added a new tablet. it need be inserted at the correct place in
// we've just added a new tablet. it needs be inserted at the correct place in
// the reel. this will naturally fall out of things if the panelreel is full; we
// can just call panelreel_redraw(). otherwise, we need make ourselves at least
// minimally visible, to satisfy the preconditions of
@ -618,12 +617,11 @@ insert_new_panel(struct notcurses* nc, panelreel* pr, tablet* t){
pr->all_visible = false;
return t;
}
fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, leny, lenx);
// fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, leny, lenx);
if((t->p = notcurses_newplane(nc, leny, lenx, begy, begx, NULL)) == NULL){
pr->all_visible = false;
return t;
}
fprintf(stderr, "created first tablet!\n");
return t;
}
// we're not the only tablet, alas.
@ -638,6 +636,7 @@ fprintf(stderr, "created first tablet!\n");
pr->all_visible = false;
return t;
}
// fprintf(stderr, "newwin: %d/%d + %d/%d\n", begy, begx, 2, lenx);
if((t->p = notcurses_newplane(nc, 2, lenx, begy, begx, NULL)) == NULL){
pr->all_visible = false;
return t;

Loading…
Cancel
Save