Open lokxii opened 2 months ago
And I observe that calling notcurses_refresh()
after notcurses_render()
causes the ncvisual object to disappear
I think I can just detect and destroy out of bounds ncplanes. But this seems inefficient
you can just hide the plane on which the ncvisual has been blitted, unless i'm misunderstanding you?
an ncvisual is not a drawn object. it's just memory holding an image.
until you blit it, it's not visible. after you blit it, the ncvisual itself has nothing to do with what is seen. you can freely change it if you want; what's visible remains the same unless you reblit it.
so to hide what's been drawn, you hide the ncplane. to destroy what's been drawn, you destroy the ncplane. etc.
and know you can freely reblit the ncvisual onto the plane (if it's transparent, you'll want to clear the plane first). like to play multiple frames of an animation, it's:
blit render clear plane blit next frame render clear plane blit next frame render
let me know if this isn't clear!
I forgot to mention that I blited ncvisual to a child plane (using NCVISUAL_OPTION_CHILDPLANE
and setting .n = parent_plane
), and then I moved the parent plane. The ncvisual stays on screen even when the parent plane is moved off screen completely
i also tried to call ncplane_erase()
and then reblit the ncvisual on an off screen plane, the image stays on screen.
I forgot to mention that I blited ncvisual to a child plane (using
NCVISUAL_OPTION_CHILDPLANE
and setting.n = parent_plane
), and then I moved the parent plane. The ncvisual stays on screen even when the parent plane is moved off screen completely
hrmmmm, that seems like an error. if you can put together a minimum example, i'll look into it.
this is strange. does e.g. ncplayer
work like you'd expect on your setup?
int main() {
const char* path = "some_picture.png";
setlocale(LC_ALL, "");
notcurses* nc = NULL;
notcurses_options opt = {
.loglevel = NCLOGLEVEL_INFO,
.flags = NCOPTION_NO_QUIT_SIGHANDLERS | NCOPTION_SUPPRESS_BANNERS
};
if ((nc = notcurses_init(&opt, NULL)) == NULL) {
exit(EXIT_FAILURE);
}
ncplane* stdplane = notcurses_stdplane(nc);
ncplane_options plane_opt = {
.y = 0, .x = 0,
.rows = 2, .cols = 4,
};
ncplane* plane = ncplane_create(stdplane, &plane_opt);
ncvisual* ncv = ncvisual_from_file(path);
if (!ncv) {
exit(EXIT_FAILURE);
}
ncvisual_options vopts = {
.n = plane,
.blitter = NCBLIT_PIXEL,
// .flags = NCVISUAL_OPTION_CHILDPLANE,
};
ncvgeom geom;
ncvisual_geom(nc, ncv, &vopts, &geom);
ncvisual_resize(ncv, 2 * 2 * geom.cdimx, 4 * geom.cdimx);
ncvisual_blit(nc, ncv, &vopts);
auto in_range = [=](int y, int x) {
unsigned int h, w;
notcurses_stddim_yx(nc, &h, &w);
return y >= 0 && y <= h && x >= 0 && x <= w;
};
ncinput ni;
bool flag = true;
while (flag) {
notcurses_render(nc);
if (notcurses_get_blocking(nc, &ni) == -1) {
continue;
}
if (ni.evtype != NCTYPE_PRESS) {
continue;
}
switch (ni.id) {
case 'q': flag = false; break;
case 'j': ncplane_move_rel(plane, 5, 0); break;
case 'k': ncplane_move_rel(plane, -5, 0); break;
case 'l': ncplane_move_rel(plane, 0, 10); break;
case 'h': ncplane_move_rel(plane, 0, -10); break;
}
ncplane_erase(plane);
ncvisual_blit(nc, ncv, &vopts);
}
notcurses_stop(nc);
}
It's the same if I blit on a child plane or blit on the parent plane.
My solution now is to check if the child plane with ncvisual is off screen, destroy or recreate the plane accordingly. But this adds significant complexity to my project that will handle a lot of images.
yeah that shouldn't be necessary. btw what terminal are you running in? it'll be important to know whether you're using the sixel protocol or kitty. the code here is kinda fragile and you may well be hitting a bug.
kitty
ncplanes can be hidden by rendering off screen. But when you blit an ncvisual object to an ncplane, and move the ncplane off screen, the ncvisual object stays on the screen. Is there anyway to properly hide an ncvisual object