Skip to content

Commit

Permalink
Don't render UI layers under direction chooser (stoneychips, #11525)
Browse files Browse the repository at this point in the history
This fixes a webtiles bug where evoking items from their inventory item
description would lead to the inventory menu obscuring the direction
chooser. This also fixes a secondary bug on local tiles where evoking
items from their inventory item description and then pressing v to
describe a cell would cause the inventory menu to appear under the
description popup.

Briefly, there are two main render loops for local tiles: the directn
loop (which does not render UI popups), and the new UI loop (which does
render the background direction chooser view). Effectively, either all
popups or no popups are rendered, depending on which render loop is
running on the top of the stack (they can be nested). For xv, that's the
UI loop on top of the directn loop; for inv -> item -> evoke, that's the
directn loop on top of the UI loop.

This approach doesn't work on webtiles because it uses HTML to render
the UI, and so the render loops are effectively "running in parallel".
It was buggy on local tiles when describing cells after evoking an item
from the inventory. The fix is to add "cutoff points" which prevent the
rendering of any UI layers already pushed. Local UI and tileweb have
separate UI stacks, and so have their own cutoff point API, in case
non-UI code modifies the tileweb UI stack in the future.

The addition of the cutoff point to show_map() is currently unnecessary,
since there is currently no way to show the map from a popup view, but
this might change in the future.
  • Loading branch information
aidanholm committed Jul 21, 2018
1 parent 88f5e90 commit 058c00f
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 1 deletion.
4 changes: 4 additions & 0 deletions crawl-ref/source/directn.cc
Expand Up @@ -2010,6 +2010,10 @@ void direction_chooser::finalize_moves()

bool direction_chooser::choose_direction()
{
#ifdef USE_TILE
ui::cutoff_point ui_cutoff_point;
#endif

if (restricts == DIR_DIR)
return choose_compass();

Expand Down
14 changes: 14 additions & 0 deletions crawl-ref/source/tileweb.cc
Expand Up @@ -654,6 +654,20 @@ void TilesFramework::ui_state_change(const string& type, unsigned state_slot)
tiles.finish_message();
}

void TilesFramework::push_ui_cutoff()
{
int cutoff = static_cast<int>(m_menu_stack.size());
m_ui_cutoff_stack.push_back(cutoff);
send_message("{\"msg\":\"ui_cutoff\",\"cutoff\":%d}", cutoff);
}

void TilesFramework::pop_ui_cutoff()
{
m_ui_cutoff_stack.pop_back();
int cutoff = m_ui_cutoff_stack.empty() ? 0 : m_ui_cutoff_stack.back();
send_message("{\"msg\":\"ui_cutoff\",\"cutoff\":%d}", cutoff);
}

static void _send_text_cursor(bool enabled)
{
tiles.send_message("{\"msg\":\"text_cursor\",\"enabled\":%s}",
Expand Down
3 changes: 3 additions & 0 deletions crawl-ref/source/tileweb.h
Expand Up @@ -137,6 +137,8 @@ class TilesFramework
void pop_ui_layout();
void pop_all_ui_layouts();
void ui_state_change(const string& type, unsigned state_slot);
void push_ui_cutoff();
void pop_ui_cutoff();

void send_exit_reason(const string& type, const string& message = "");
void send_dump_info(const string& type, const string& filename);
Expand Down Expand Up @@ -241,6 +243,7 @@ class TilesFramework

WebtilesUIState m_ui_state;
WebtilesUIState m_last_ui_state;
vector<int> m_ui_cutoff_stack;

unsigned int m_last_tick_redraw;
bool m_need_redraw;
Expand Down
26 changes: 25 additions & 1 deletion crawl-ref/source/ui.cc
Expand Up @@ -13,6 +13,7 @@
#include "cio.h"
#include "macro.h"
# include "state.h"
#include "tileweb.h"

#ifdef USE_TILE_LOCAL
# include "glwrapper.h"
Expand Down Expand Up @@ -84,6 +85,7 @@ static struct UIRoot

bool needs_paint;
vector<KeymapContext> keymap_stack;
vector<int> cutoff_stack;

protected:
int m_w, m_h;
Expand Down Expand Up @@ -1457,7 +1459,10 @@ void UIRoot::render()

push_scissor(m_region);
#ifdef USE_TILE_LOCAL
m_root.render();
int cutoff = cutoff_stack.empty() ? 0 : cutoff_stack.back();
ASSERT(cutoff <= static_cast<int>(m_root.num_children()));
for (int i = cutoff; i < static_cast<int>(m_root.num_children()); i++)
m_root.get_child(i)->render();
#else
// Render only the top of the UI stack on console
if (m_root.num_children() > 0)
Expand Down Expand Up @@ -1576,6 +1581,25 @@ static void clear_text_region(i4 region)
}
#endif

#ifdef USE_TILE
void push_cutoff()
{
int cutoff = static_cast<int>(ui_root.num_children());
ui_root.cutoff_stack.push_back(cutoff);
#ifdef USE_TILE_WEB
tiles.push_ui_cutoff();
#endif
}

void pop_cutoff()
{
ui_root.cutoff_stack.pop_back();
#ifdef USE_TILE_WEB
tiles.pop_ui_cutoff();
#endif
}
#endif

void push_layout(shared_ptr<Widget> root, KeymapContext km)
{
ui_root.push_child(move(root), km);
Expand Down
12 changes: 12 additions & 0 deletions crawl-ref/source/ui.h
Expand Up @@ -575,6 +575,18 @@ class Dungeon : public Widget
};
#endif

#ifdef USE_TILE
void push_cutoff();
void pop_cutoff();

class cutoff_point
{
public:
cutoff_point() { push_cutoff(); }
~cutoff_point() { pop_cutoff(); }
};
#endif

void push_layout(shared_ptr<Widget> root, KeymapContext km = KMC_DEFAULT);
void pop_layout();
void pump_events(int wait_event_timeout = INT_MAX);
Expand Down
4 changes: 4 additions & 0 deletions crawl-ref/source/viewmap.cc
Expand Up @@ -33,6 +33,7 @@
#include "tileview.h"
#include "tiles-build-specific.h"
#include "travel.h"
#include "ui.h"
#include "unicode.h"
#include "view.h"
#include "viewchar.h"
Expand Down Expand Up @@ -629,6 +630,9 @@ bool show_map(level_pos &lpos,
tiles.do_map_display();
#endif

#ifdef USE_TILE
ui::cutoff_point ui_cutoff_point;
#endif
#ifdef USE_TILE_WEB
tiles_ui_control ui(UI_VIEW_MAP);
#endif
Expand Down
9 changes: 9 additions & 0 deletions crawl-ref/source/webserver/game_data/static/game.js
Expand Up @@ -191,6 +191,14 @@ function ($, comm, client, dungeon_renderer, display, minimap, enums, messages,
set_ui_state(data.state);
}

function handle_set_ui_cutoff(data)
{
var popups = document.querySelectorAll("#ui-stack > .ui-popup");
Array.from(popups).forEach(function (p, i) {
p.classList.toggle("hidden", i <= data.cutoff);
});
}

function set_input_mode(mode)
{
if (mode == input_mode) return;
Expand Down Expand Up @@ -240,6 +248,7 @@ function ($, comm, client, dungeon_renderer, display, minimap, enums, messages,
"version": handle_version,
"layout": handle_set_layout,
"ui_state": handle_set_ui_state,
"ui_cutoff": handle_set_ui_cutoff,
"input_mode": handle_set_input_mode,
});
});

0 comments on commit 058c00f

Please sign in to comment.