mirror of
https://github.com/mamedev/mame.git
synced 2024-11-16 07:48:32 +01:00
emu/rendlay.cpp, ui/ui.cpp: Allow layout views to control pointer display.
This commit is contained in:
parent
7662be246f
commit
8e7af961c6
11 changed files with 101 additions and 27 deletions
|
@ -587,9 +587,6 @@ driver.is_bios_root (read-only)
|
|||
driver.requires_artwork (read-only)
|
||||
A Boolean indicating whether the system requires external artwork to be
|
||||
usable.
|
||||
driver.clickable_artwork (read-only)
|
||||
A Boolean indicating whether the system requires clickable artwork features
|
||||
to be usable.
|
||||
driver.unofficial (read-only)
|
||||
A Boolean indicating whether this is an unofficial but common user
|
||||
modification to a system.
|
||||
|
|
|
@ -754,6 +754,10 @@ manager.machine.video.snapshot_target
|
|||
Properties
|
||||
~~~~~~~~~~
|
||||
|
||||
target.ui_container (read-only)
|
||||
The :ref:`render container <luascript-ref-rendercontainer>` for drawing user
|
||||
interface elements over this render target, or ``nil`` for hidden render
|
||||
targets (targets that are not shown to the user directly).
|
||||
target.index (read-only)
|
||||
The 1-based index of the render target. This has O(n) complexity.
|
||||
target.width (read-only)
|
||||
|
@ -810,6 +814,9 @@ Instantiation
|
|||
manager.machine.render.ui_container
|
||||
Gets the render container used to draw the user interface, including menus,
|
||||
sliders and pop-up messages.
|
||||
manager.machine.render.targets[index].ui_container
|
||||
Gets the render container used to draw user interface elements over a
|
||||
particular render target.
|
||||
manager.machine.screens[tag].container
|
||||
Gets the render container used to draw a given screen.
|
||||
|
||||
|
@ -1145,10 +1152,16 @@ view.bounds (read-only)
|
|||
effective bounds of the view in its current configuration. The coordinates
|
||||
are in view units, which are arbitrary but assumed to have square aspect
|
||||
ratio.
|
||||
view.has_art
|
||||
view.has_art (read-only)
|
||||
A Boolean indicating whether the view has any non-screen items, including
|
||||
items that are not visible because the user has hidden the item collection
|
||||
that they belong to.
|
||||
view.show_pointers (read/write)
|
||||
A Boolean that sets whether mouse and pon pointers should be displayed for
|
||||
the view.
|
||||
view.hide_inactive_pointers (read/write)
|
||||
A Boolean that sets whether mouse pointers for the view should be hidden
|
||||
after a period of inactivity.
|
||||
|
||||
|
||||
.. _luascript-ref-renderlayitem:
|
||||
|
|
|
@ -690,6 +690,11 @@ element. This means a view can reference elements and groups that appear after
|
|||
it in the file, and parameters from the enclosing scope will have their final
|
||||
values from the end of the ``mamelayout`` element.
|
||||
|
||||
A ``view`` element may have a ``showpointers`` attribute to set whether mouse
|
||||
and pen pointers should be shown for the view. If present, the value must be
|
||||
either ``yes`` or ``no``. If the ``showpointers`` attribute is not present, pen
|
||||
and mouse pointers are shown for views that contain items bound to I/O ports.
|
||||
|
||||
The following child elements are allowed inside a ``view`` element:
|
||||
|
||||
bounds
|
||||
|
|
|
@ -409,6 +409,7 @@ class LayoutChecker(Minifyer):
|
|||
self.views[attrs['name']] = self.format_location()
|
||||
elif not self.VARPATTERN.match(attrs['name']):
|
||||
self.handle_error('Element view has duplicate name "%s" (previous %s)' % (attrs['name'], self.views[attrs['name']]))
|
||||
self.check_bool_attribute(name, attrs, 'showpointers', None)
|
||||
self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler))
|
||||
self.variable_scopes.append({ })
|
||||
self.item_ids = { }
|
||||
|
|
|
@ -4000,7 +4000,17 @@ layout_view::layout_view(
|
|||
, m_elemmap(elemmap)
|
||||
, m_defvismask(0U)
|
||||
, m_has_art(false)
|
||||
, m_show_ptr(false)
|
||||
, m_ptr_time_out(true) // FIXME: add attribute for this
|
||||
, m_exp_show_ptr(-1)
|
||||
{
|
||||
// check for explicit pointer display setting
|
||||
if (viewnode.get_attribute_string_ptr("showpointers"))
|
||||
{
|
||||
m_show_ptr = env.get_attribute_bool(viewnode, "showpointers", false);
|
||||
m_exp_show_ptr = m_show_ptr ? 1 : 0;
|
||||
}
|
||||
|
||||
// parse the layout
|
||||
m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0;
|
||||
view_environment local(env, m_name.c_str());
|
||||
|
@ -4178,6 +4188,7 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
|
|||
// loop over items and filter by visibility mask
|
||||
bool first = true;
|
||||
bool scrfirst = true;
|
||||
bool haveinput = false;
|
||||
for (item &curitem : m_items)
|
||||
{
|
||||
if ((visibility_mask & curitem.visibility_mask()) == curitem.visibility_mask())
|
||||
|
@ -4209,9 +4220,15 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
|
|||
// accumulate interactive elements
|
||||
if (!curitem.clickthrough() || curitem.has_input())
|
||||
m_interactive_items.emplace_back(curitem);
|
||||
if (curitem.has_input())
|
||||
haveinput = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if show pointers isn't explicitly, update it based on visible items
|
||||
if (0 > m_exp_show_ptr)
|
||||
m_show_ptr = haveinput;
|
||||
|
||||
// if we have an explicit bounds, override it
|
||||
if (m_expbounds.x1 > m_expbounds.x0)
|
||||
m_bounds = m_expbounds;
|
||||
|
@ -4282,6 +4299,29 @@ void layout_view::recompute(u32 visibility_mask, bool zoom_to_screen)
|
|||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_show_pointers - set whether pointers
|
||||
// should be displayed
|
||||
//-------------------------------------------------
|
||||
|
||||
void layout_view::set_show_pointers(bool value) noexcept
|
||||
{
|
||||
m_show_ptr = value;
|
||||
m_exp_show_ptr = value ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_pointers_time_out - set whether pointers
|
||||
// should be hidden after inactivity
|
||||
//-------------------------------------------------
|
||||
|
||||
void layout_view::set_hide_inactive_pointers(bool value) noexcept
|
||||
{
|
||||
m_ptr_time_out = value;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_prepare_items_callback - set handler called
|
||||
// before adding items to render target
|
||||
|
|
|
@ -527,6 +527,12 @@ public:
|
|||
const visibility_toggle_vector &visibility_toggles() const { return m_vistoggles; }
|
||||
u32 default_visibility_mask() const { return m_defvismask; }
|
||||
bool has_art() const { return m_has_art; }
|
||||
bool show_pointers() const { return m_show_ptr; }
|
||||
bool hide_inactive_pointers() const { return m_ptr_time_out; }
|
||||
|
||||
// setters
|
||||
void set_show_pointers(bool value) noexcept;
|
||||
void set_hide_inactive_pointers(bool value) noexcept ATTR_COLD;
|
||||
|
||||
// set handlers
|
||||
void set_prepare_items_callback(prepare_items_delegate &&handler) ATTR_COLD;
|
||||
|
@ -621,6 +627,9 @@ private:
|
|||
render_bounds m_expbounds; // explicit bounds of the view
|
||||
u32 m_defvismask; // default visibility mask
|
||||
bool m_has_art; // true if the layout contains non-screen elements
|
||||
bool m_show_ptr; // whether pointers should be displayed
|
||||
bool m_ptr_time_out; // whether pointers should be hidden after inactivity
|
||||
s8 m_exp_show_ptr; // explicitly configured pointer visibility
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1502,7 +1502,6 @@ void lua_engine::initialize()
|
|||
game_driver_type["no_cocktail"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_COCKTAIL) != 0; });
|
||||
game_driver_type["is_bios_root"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::IS_BIOS_ROOT) != 0; });
|
||||
game_driver_type["requires_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::REQUIRES_ARTWORK) != 0; });
|
||||
game_driver_type["clickable_artwork"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::CLICKABLE_ARTWORK) != 0; });
|
||||
game_driver_type["unofficial"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::UNOFFICIAL) != 0; });
|
||||
game_driver_type["no_sound_hw"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::NO_SOUND_HW) != 0; });
|
||||
game_driver_type["mechanical"] = sol::property([] (game_driver const &driver) { return (driver.flags & machine_flags::MECHANICAL) != 0; });
|
||||
|
|
|
@ -994,6 +994,8 @@ void lua_engine::initialize_render(sol::table &emu)
|
|||
layout_view_type["effective_aspect"] = sol::property(&layout_view::effective_aspect);
|
||||
layout_view_type["bounds"] = sol::property(&layout_view::bounds);
|
||||
layout_view_type["has_art"] = sol::property(&layout_view::has_art);
|
||||
layout_view_type["show_pointers"] = sol::property(&layout_view::show_pointers, &layout_view::set_show_pointers);
|
||||
layout_view_type["hide_inactive_pointers"] = sol::property(&layout_view::hide_inactive_pointers, &layout_view::set_hide_inactive_pointers);
|
||||
|
||||
|
||||
auto layout_view_item_type = sol().registry().new_usertype<layout_view_item>("layout_item", sol::no_constructor);
|
||||
|
@ -1100,6 +1102,7 @@ void lua_engine::initialize_render(sol::table &emu)
|
|||
|
||||
|
||||
auto target_type = sol().registry().new_usertype<render_target>("target", sol::no_constructor);
|
||||
target_type["ui_container"] = sol::property(&render_target::ui_container);
|
||||
target_type["index"] = sol::property([] (render_target const &t) { return t.index() + 1; });
|
||||
target_type["width"] = sol::property(&render_target::width);
|
||||
target_type["height"] = sol::property(&render_target::height);
|
||||
|
|
|
@ -4202,7 +4202,6 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
|
|||
|
||||
str << ((flags.machine_flags() & machine_flags::MECHANICAL) ? _("Mechanical System\tYes\n") : _("Mechanical System\tNo\n"));
|
||||
str << ((flags.machine_flags() & machine_flags::REQUIRES_ARTWORK) ? _("Requires Artwork\tYes\n") : _("Requires Artwork\tNo\n"));
|
||||
str << ((flags.machine_flags() & machine_flags::CLICKABLE_ARTWORK) ? _("Requires Clickable Artwork\tYes\n") : _("Requires Clickable Artwork\tNo\n"));
|
||||
if (flags.machine_flags() & machine_flags::NO_COCKTAIL)
|
||||
str << _("Support Cocktail\tNo\n");
|
||||
str << ((flags.machine_flags() & machine_flags::IS_BIOS_ROOT) ? _("System is BIOS\tYes\n") : _("System is BIOS\tNo\n"));
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "render.h"
|
||||
#include "cheat.h"
|
||||
#include "rendfont.h"
|
||||
#include "rendlay.h"
|
||||
#include "romload.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
@ -165,7 +166,13 @@ enum class mame_ui_manager::ui_callback_type : int
|
|||
|
||||
struct mame_ui_manager::active_pointer
|
||||
{
|
||||
active_pointer(ui_event const &event) : target(event.target), type(event.pointer_type), ptrid(event.pointer_id), x(-1.0F), y(-1.0F)
|
||||
active_pointer(ui_event const &event)
|
||||
: target(event.target)
|
||||
, updated(std::chrono::steady_clock::time_point::min())
|
||||
, type(event.pointer_type)
|
||||
, ptrid(event.pointer_id)
|
||||
, x(-1.0F)
|
||||
, y(-1.0F)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -175,6 +182,7 @@ struct mame_ui_manager::active_pointer
|
|||
}
|
||||
|
||||
render_target *target;
|
||||
std::chrono::steady_clock::time_point updated;
|
||||
osd::ui_event_handler::pointer type;
|
||||
u16 ptrid;
|
||||
float x, y;
|
||||
|
@ -198,8 +206,6 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
|
|||
, m_popup_text_end(0)
|
||||
, m_mouse_bitmap(32, 32)
|
||||
, m_mouse_arrow_texture(nullptr)
|
||||
, m_mouse_show(false)
|
||||
, m_update_pointers(false)
|
||||
, m_pointers_changed(false)
|
||||
, m_target_font_height(0)
|
||||
, m_has_warnings(false)
|
||||
|
@ -240,7 +246,6 @@ void mame_ui_manager::init()
|
|||
return 0;
|
||||
}));
|
||||
m_non_char_keys_down = std::make_unique<uint8_t[]>((std::size(non_char_keys) + 7) / 8);
|
||||
m_mouse_show = machine().system().flags & machine_flags::CLICKABLE_ARTWORK ? true : false;
|
||||
|
||||
// request notification callbacks
|
||||
machine().add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(&mame_ui_manager::frame_update, this));
|
||||
|
@ -733,7 +738,7 @@ bool mame_ui_manager::update_and_render(render_container &container)
|
|||
// display the internal pointers
|
||||
bool const pointer_update = m_pointers_changed;
|
||||
m_pointers_changed = false;
|
||||
if (m_mouse_show || (is_menu_active() && machine().options().ui_mouse()))
|
||||
if (!is_menu_active() || machine().options().ui_mouse())
|
||||
{
|
||||
const float cursor_size = 0.6 * get_line_height();
|
||||
for (auto const &pointer : m_display_pointers)
|
||||
|
@ -1128,12 +1133,12 @@ void mame_ui_manager::process_ui_events()
|
|||
{
|
||||
if (osd::ui_event_handler::pointer::TOUCH != event.pointer_type)
|
||||
{
|
||||
m_update_pointers = true;
|
||||
auto pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
|
||||
if ((m_active_pointers.end() == pos) || (pos->target != event.target) || (pos->ptrid != event.pointer_id))
|
||||
pos = m_active_pointers.emplace(pos, event);
|
||||
else
|
||||
assert(pos->type == event.pointer_type);
|
||||
pos->updated = std::chrono::steady_clock::now();
|
||||
event.target->map_point_container(event.pointer_x, event.pointer_y, *event.target->ui_container(), pos->x, pos->y);
|
||||
}
|
||||
|
||||
|
@ -1150,10 +1155,7 @@ void mame_ui_manager::process_ui_events()
|
|||
{
|
||||
auto const pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
|
||||
if (m_active_pointers.end() != pos)
|
||||
{
|
||||
m_update_pointers = true;
|
||||
m_active_pointers.erase(pos);
|
||||
}
|
||||
|
||||
event.target->pointer_left(
|
||||
event.pointer_type, event.pointer_id, event.pointer_device,
|
||||
|
@ -1168,10 +1170,7 @@ void mame_ui_manager::process_ui_events()
|
|||
{
|
||||
auto const pos(std::lower_bound(m_active_pointers.begin(), m_active_pointers.end(), std::make_pair(event.target, event.pointer_id)));
|
||||
if (m_active_pointers.end() != pos)
|
||||
{
|
||||
m_update_pointers = true;
|
||||
m_active_pointers.erase(pos);
|
||||
}
|
||||
|
||||
event.target->pointer_aborted(
|
||||
event.pointer_type, event.pointer_id, event.pointer_device,
|
||||
|
@ -1379,15 +1378,20 @@ uint32_t mame_ui_manager::handler_ingame(render_container &container)
|
|||
|
||||
// process UI events and update pointers if necessary
|
||||
process_ui_events();
|
||||
if (m_update_pointers)
|
||||
display_pointer_vector pointers;
|
||||
pointers.reserve(m_active_pointers.size());
|
||||
auto const now(std::chrono::steady_clock::now());
|
||||
for (auto const &pointer : m_active_pointers)
|
||||
{
|
||||
display_pointer_vector pointers;
|
||||
pointers.reserve(m_active_pointers.size());
|
||||
for (auto const &pointer : m_active_pointers)
|
||||
pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
|
||||
set_pointers(pointers.begin(), pointers.end());
|
||||
m_update_pointers = false;
|
||||
layout_view const &view(pointer.target->current_view());
|
||||
if (view.show_pointers())
|
||||
{
|
||||
// TODO: make timeout configurable
|
||||
if (!view.hide_inactive_pointers() || (osd::ui_event_handler::pointer::PEN == pointer.type) || ((now - pointer.updated) <= std::chrono::seconds(3)))
|
||||
pointers.emplace_back(display_pointer{ *pointer.target, pointer.type, pointer.x, pointer.y });
|
||||
}
|
||||
}
|
||||
set_pointers(pointers.begin(), pointers.end());
|
||||
|
||||
if (!ui_disabled)
|
||||
{
|
||||
|
@ -2400,6 +2404,12 @@ bool mame_ui_manager::set_ui_event_handler(std::function<bool ()> &&handler)
|
|||
if (ui_callback_type::GENERAL != m_handler_callback_type)
|
||||
return false;
|
||||
|
||||
for (auto *target = machine().render().first_target(); target; target = target->next())
|
||||
{
|
||||
if (!target->hidden())
|
||||
target->forget_pointers();
|
||||
}
|
||||
|
||||
set_handler(
|
||||
ui_callback_type::CUSTOM,
|
||||
handler_callback_func(
|
||||
|
|
|
@ -298,8 +298,6 @@ private:
|
|||
display_pointer_vector m_display_pointers;
|
||||
bitmap_argb32 m_mouse_bitmap;
|
||||
render_texture * m_mouse_arrow_texture;
|
||||
bool m_mouse_show;
|
||||
bool m_update_pointers;
|
||||
bool m_pointers_changed;
|
||||
|
||||
ui_options m_ui_options;
|
||||
|
|
Loading…
Reference in a new issue