Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/dmview/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ static void show_view(service_t* s, char* path)
Dmod_Free(path);
return;
}
bool was_shown = s->view != NULL;
libdmview_close(s->view);
s->view = NULL;
if (s->view_path != NULL)
Expand All @@ -400,6 +401,8 @@ static void show_view(service_t* s, char* path)
if (path == NULL)
{
DMOD_LOG_WARN("dmview: no view for %s (DMVIEW_VIEWS, DMVIEW_DEFAULT)\n", s->name);
if (!was_shown)
return; /* What the display shows - a splash screen - stays */
dmdrvi_gfx_fill_rect_t all = { 0, 0, s->info.width, s->info.height, 0xFF000000u };
(void)Dmod_Ioctl(s->gfx, DMDRVI_IOCTL_GFX_FILL_RECT, &all);
present(s, NULL);
Expand Down
24 changes: 23 additions & 1 deletion src/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,28 @@ static void redraw(struct libdmview* v, int32_t target, const rect_t* area)
run(v, b->begin * DMV_CODE_WORD, true);
}

/*
* A box that changed but is not seen - a screen of a page behind the one
* shown, its opacity 0 - draws nothing, yet redrawing it redraws what is
* seen beneath it (a page's animations ran under the shown page all the
* time). Unseen: a box around it was not seen when last drawn (when that
* one's opacity changes, it is redrawn itself, with all inside it), or it
* was not seen itself and its OPACITY still makes it so.
*/
static bool stays_unseen(struct libdmview* v, const rbox_t* b)
{
for (int32_t p = b->parent; p != ROOT; p = v->boxes[p].parent)
{
if (v->boxes[p].seen == 0)
return true;
}
if (b->seen != 0)
return false;
const uint8_t* insn = v->code + b->begin * DMV_CODE_WORD;
const uint8_t* next = insn + insn[1];
return next[0] == DMV_OP_OPACITY && v16(v, next, 0, OPOFF(OPACITY, 0)) <= 0;
}

void exec_draw(struct libdmview* v, rect_t* changed)
{
rect_t screen = { 0, 0, v->surface_w, v->surface_h };
Expand All @@ -766,7 +788,7 @@ void exec_draw(struct libdmview* v, rect_t* changed)
rbox_t* b = &v->boxes[i];
if ((b->flags & BOXF_DIRTY) == 0)
continue;
if ((b->flags & BOXF_VISIBLE) == 0)
if ((b->flags & BOXF_VISIBLE) == 0 || stays_unseen(v, b))
{
b->flags &= (uint8_t)~BOXF_DIRTY;
continue;
Expand Down
10 changes: 9 additions & 1 deletion tests/fixtures/hidden.dmvs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
; Two screens one on another, as a page's views: the one below shown, with
; a button; the one on top hidden by its opacity ($top), with a box taking
; no contact over the button - and a button of its own elsewhere.
; no contact over the button - and a button of its own elsewhere. $tick
; changes what the hidden screen shows: a bar's width, a box's place.
.view hidden
.entry draw

.var $top, int, 0
.var $below, int, 0
.var $above, int, 0
.var $tick, int, 1

draw:
FILL #000000
Expand All @@ -25,6 +27,12 @@ draw:
ON CLICK, press_above
FILL #00FF00
END
BOX @bar, 0, 28, 64, 4
RECT 0, 0, $tick, 4, #FFFFFF
END
BOX @mover, $tick, 24, 4, 4
FILL #FFFF00
END
END
RET

Expand Down
8 changes: 8 additions & 0 deletions tests/libdmview_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,10 @@ DMOD_TEST_STEP(libdmview_hidden_boxes_take_no_contact)
return;
DMOD_TEST_EXPECT_EQ(libdmview_render(g_view, &g_s32, NULL), 1);

/* What the hidden screen shows changes: nothing is drawn */
DMOD_TEST_EXPECT_EQ(libdmview_set_int(g_view, "tick", 9), 0);
DMOD_TEST_EXPECT_EQ(libdmview_render(g_view, &g_s32, NULL), 0);

/* The screen on top is not seen: the button beneath it is clicked */
touch(1, 15, 15, 10);
touch(0, 0, 0, 20);
Expand All @@ -755,6 +759,10 @@ DMOD_TEST_STEP(libdmview_hidden_boxes_take_no_contact)
/* Shown: it covers the button, its own takes the contact */
DMOD_TEST_EXPECT_EQ(libdmview_set_int(g_view, "top", 255), 0);
DMOD_TEST_EXPECT_EQ(libdmview_render(g_view, &g_s32, NULL), 1);
DMOD_TEST_EXPECT_EQ(px(1, 29), 0xFFFFFFFFu); /* The bar as $tick has it now */
DMOD_TEST_EXPECT_EQ(px(9, 25), 0xFFFFFF00u);
DMOD_TEST_EXPECT_EQ(libdmview_set_int(g_view, "tick", 20), 0);
DMOD_TEST_EXPECT_EQ(libdmview_render(g_view, &g_s32, NULL), 1); /* Seen: drawn */
touch(1, 15, 15, 50);
touch(0, 0, 0, 60);
DMOD_TEST_EXPECT_EQ(libdmview_get_int(g_view, "below", &value), 0);
Expand Down
Loading