summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-10-17 06:58:12 +1100
committer Vas Crabb <vas@vastheman.com>2021-10-17 06:58:12 +1100
commit22f52553f746c9ade11ecb8a0873507682d0f1cb (patch)
tree0e147d0ba4465a0c8cbb6a2a2088f036c87e3bd6 /src/frontend/mame
parentaa3ae2cf17d832eaa6e70e4506da44bac1a31508 (diff)
frontend: Cleaned up rendering of info views.
Put the description for systems in the info box - it's useful for the fruit machines with very long names that are truncated in the list. Also stopped truncating manufactuer and parent name in the info box. Made the text layout class capable of handling lines containing combinatations of left/centre/right-justified text and got rid of the legacy UI manager text wrapping function. Made the system/software selection menus and the info viewer share the same code for formatting info text. This means the multi-column layout works properly in the info viewer now, and the code is a lot simpler. Also the system/software selection menus don't have to redo the text layout every frame now. Made the info viewer update the text layout if the output aspect ratio changes, and cleaned up more legacy code. The lines in the info viewer are no longer bogus "menu items", and there's a lot less special-case code to support it in the base menu class. This commit includes an update to the Chinese translations from YuiFAN.
Diffstat (limited to 'src/frontend/mame')
-rw-r--r--src/frontend/mame/cheat.cpp19
-rw-r--r--src/frontend/mame/luaengine.cpp10
-rw-r--r--src/frontend/mame/ui/analogipt.cpp3
-rw-r--r--src/frontend/mame/ui/auditmenu.cpp6
-rw-r--r--src/frontend/mame/ui/confswitch.cpp2
-rw-r--r--src/frontend/mame/ui/custui.cpp88
-rw-r--r--src/frontend/mame/ui/datmenu.cpp348
-rw-r--r--src/frontend/mame/ui/datmenu.h33
-rw-r--r--src/frontend/mame/ui/dirmenu.cpp12
-rw-r--r--src/frontend/mame/ui/inifile.cpp2
-rw-r--r--src/frontend/mame/ui/inputmap.cpp8
-rw-r--r--src/frontend/mame/ui/menu.cpp184
-rw-r--r--src/frontend/mame/ui/menu.h10
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp4
-rw-r--r--src/frontend/mame/ui/optsmenu.cpp2
-rw-r--r--src/frontend/mame/ui/selector.cpp4
-rw-r--r--src/frontend/mame/ui/selmenu.cpp210
-rw-r--r--src/frontend/mame/ui/selmenu.h2
-rw-r--r--src/frontend/mame/ui/simpleselgame.cpp6
-rw-r--r--src/frontend/mame/ui/sliders.cpp24
-rw-r--r--src/frontend/mame/ui/slotopt.cpp2
-rw-r--r--src/frontend/mame/ui/sndmenu.cpp2
-rw-r--r--src/frontend/mame/ui/state.cpp4
-rw-r--r--src/frontend/mame/ui/submenu.cpp4
-rw-r--r--src/frontend/mame/ui/text.cpp494
-rw-r--r--src/frontend/mame/ui/text.h95
-rw-r--r--src/frontend/mame/ui/ui.cpp70
-rw-r--r--src/frontend/mame/ui/ui.h5
-rw-r--r--src/frontend/mame/ui/utils.cpp6
29 files changed, 920 insertions, 739 deletions
diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp
index f4a567db28f..2946d2c2257 100644
--- a/src/frontend/mame/cheat.cpp
+++ b/src/frontend/mame/cheat.cpp
@@ -431,12 +431,12 @@ cheat_script::script_entry::script_entry(
// extract other attributes
m_line = entrynode.get_attribute_int("line", 0);
- m_justify = ui::text_layout::LEFT;
+ m_justify = ui::text_layout::text_justify::LEFT;
char const *const align(entrynode.get_attribute_string("align", "left"));
if (!std::strcmp(align, "center"))
- m_justify = ui::text_layout::CENTER;
+ m_justify = ui::text_layout::text_justify::CENTER;
else if (!std::strcmp(align, "right"))
- m_justify = ui::text_layout::RIGHT;
+ m_justify = ui::text_layout::text_justify::RIGHT;
else if (std::strcmp(align, "left"))
throw emu_fatalerror("%s.xml(%d): invalid alignment '%s' specified\n", filename, entrynode.line, align);
@@ -547,9 +547,9 @@ void cheat_script::script_entry::save(emu_file &cheatfile) const
if (m_line != 0)
cheatfile.printf(" line=\"%d\"", m_line);
- if (m_justify == ui::text_layout::CENTER)
+ if (m_justify == ui::text_layout::text_justify::CENTER)
cheatfile.printf(" align=\"center\"");
- else if (m_justify == ui::text_layout::RIGHT)
+ else if (m_justify == ui::text_layout::text_justify::RIGHT)
cheatfile.printf(" align=\"right\"");
if (m_arglist.size() == 0)
@@ -1236,10 +1236,13 @@ void cheat_manager::render_text(mame_ui_manager &mui, render_container &containe
if (!m_output[linenum].empty())
{
// output the text
- mui.draw_text_full(container, m_output[linenum],
+ mui.draw_text_full(
+ container,
+ m_output[linenum],
0.0f, float(linenum) * mui.get_line_height(), 1.0f,
- m_justify[linenum], ui::text_layout::NEVER, mame_ui_manager::OPAQUE_,
- rgb_t::white(), rgb_t::black(), nullptr, nullptr);
+ m_justify[linenum], ui::text_layout::word_wrapping::NEVER,
+ mame_ui_manager::OPAQUE_, rgb_t::white(), rgb_t::black(),
+ nullptr, nullptr);
}
}
}
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 78521783541..a76c46fb1d5 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -85,7 +85,7 @@ void do_draw_text(lua_State *L, screen_device &sdev, sol::object &xobj, float y,
{
float const sc_width(sdev.visible_area().width());
float const sc_height(sdev.visible_area().height());
- auto justify = ui::text_layout::LEFT;
+ auto justify = ui::text_layout::text_justify::LEFT;
float x = 0;
if (xobj.is<float>())
{
@@ -95,11 +95,11 @@ void do_draw_text(lua_State *L, screen_device &sdev, sol::object &xobj, float y,
{
char const *const justifystr(xobj.as<char const *>());
if (!strcmp(justifystr, "left"))
- justify = ui::text_layout::LEFT;
+ justify = ui::text_layout::text_justify::LEFT;
else if (!strcmp(justifystr, "right"))
- justify = ui::text_layout::RIGHT;
+ justify = ui::text_layout::text_justify::RIGHT;
else if (!strcmp(justifystr, "center"))
- justify = ui::text_layout::CENTER;
+ justify = ui::text_layout::text_justify::CENTER;
}
else
{
@@ -111,7 +111,7 @@ void do_draw_text(lua_State *L, screen_device &sdev, sol::object &xobj, float y,
sdev.container(),
msg,
x, y, (1.0f - x),
- justify, ui::text_layout::WORD,
+ justify, ui::text_layout::word_wrapping::WORD,
mame_ui_manager::OPAQUE_, fgcolor, bgcolor);
}
diff --git a/src/frontend/mame/ui/analogipt.cpp b/src/frontend/mame/ui/analogipt.cpp
index d1df77c5647..2f1d1a7128d 100644
--- a/src/frontend/mame/ui/analogipt.cpp
+++ b/src/frontend/mame/ui/analogipt.cpp
@@ -90,7 +90,8 @@ void menu_analog::custom_render(void *selectedref, float top, float bottom, floa
ui().draw_text_full(
container(),
data.field.get().name(),
- nameleft, liney, namewidth, ui::text_layout::LEFT, ui::text_layout::NEVER,
+ nameleft, liney, namewidth,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, fgcolor, ui().colors().text_bg_color());
ioport_value cur(0U);
diff --git a/src/frontend/mame/ui/auditmenu.cpp b/src/frontend/mame/ui/auditmenu.cpp
index 717973d9cfc..afe54aeaf69 100644
--- a/src/frontend/mame/ui/auditmenu.cpp
+++ b/src/frontend/mame/ui/auditmenu.cpp
@@ -80,7 +80,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
draw_text_box(
&m_prompt, &m_prompt + 1,
x, x2, y2 + ui().box_tb_border(), y2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
break;
@@ -102,7 +102,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
ui().draw_text_box(
container(),
std::move(text).str(),
- ui::text_layout::CENTER,
+ text_layout::text_justify::CENTER,
0.5f, 0.5f,
ui().colors().background_color());
}
@@ -115,7 +115,7 @@ void menu_audit::custom_render(void *selectedref, float top, float bottom, float
_("Cancel audit?\n\nPress %1$s to cancel\nPress %2$s to continue"),
ui().get_general_input_setting(IPT_UI_SELECT),
ui().get_general_input_setting(IPT_UI_CANCEL)),
- ui::text_layout::CENTER,
+ text_layout::text_justify::CENTER,
0.5f, 0.5f,
UI_RED_COLOR);
break;
diff --git a/src/frontend/mame/ui/confswitch.cpp b/src/frontend/mame/ui/confswitch.cpp
index d45f8f0242c..be1346171d3 100644
--- a/src/frontend/mame/ui/confswitch.cpp
+++ b/src/frontend/mame/ui/confswitch.cpp
@@ -335,7 +335,7 @@ void menu_settings_dip_switches::custom_render(void *selectedref, float top, flo
container(),
group.name,
nameleft, liney + (lineheight * (DIP_SWITCH_HEIGHT - 1.0f) / 2.0f), namewidth,
- ui::text_layout::RIGHT, ui::text_layout::NEVER,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
// draw the group outline
diff --git a/src/frontend/mame/ui/custui.cpp b/src/frontend/mame/ui/custui.cpp
index 69b3a3b0b3b..76d5b282534 100644
--- a/src/frontend/mame/ui/custui.cpp
+++ b/src/frontend/mame/ui/custui.cpp
@@ -199,7 +199,7 @@ void menu_custom_ui::custom_render(void *selectedref, float top, float bottom, f
draw_text_box(
std::begin(text), std::end(text),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -491,7 +491,7 @@ void menu_font_ui::custom_render(void *selectedref, float top, float bottom, flo
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
if (uintptr_t(selectedref) == INFOS_SIZE)
@@ -500,7 +500,7 @@ void menu_font_ui::custom_render(void *selectedref, float top, float bottom, flo
draw_text_box(
std::begin(bottomtext), std::end(bottomtext),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::LEFT, ui::text_layout::NEVER, false,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_GREEN_COLOR, m_info_size);
}
}
@@ -613,7 +613,7 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
// bottom text
@@ -622,7 +622,7 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
draw_text_box(
std::begin(bottomtext), std::end(bottomtext),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
// compute maxwidth
@@ -630,8 +630,12 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
const float lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
float width;
- ui().draw_text_full(container(), topbuf, 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
+ ui().draw_text_full(
+ container(),
+ topbuf,
+ 0.0f, 0.0f, 1.0f,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
float maxwidth = width + 2.0f * lr_border;
std::string sampletxt[5];
@@ -644,8 +648,12 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
for (auto & elem: sampletxt)
{
- ui().draw_text_full(container(), elem, 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
+ ui().draw_text_full(
+ container(),
+ elem,
+ 0.0f, 0.0f, 1.0f,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * lr_border;
maxwidth = std::max(maxwidth, width);
}
@@ -666,8 +674,12 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
y2 -= ui().box_tb_border();
// draw the text within it
- ui().draw_text_full(container(), topbuf, x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(), nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ topbuf,
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(), nullptr, nullptr);
// compute our bounds for menu preview
float line_height = ui().get_line_height();
@@ -685,30 +697,50 @@ void menu_colors_ui::custom_render(void *selectedref, float top, float bottom, f
y1 += ui().box_tb_border();
// draw normal text
- ui().draw_text_full(container(), sampletxt[0], x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, m_color_table[MUI_TEXT_COLOR].color, m_color_table[MUI_TEXT_BG_COLOR].color, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ sampletxt[0],
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, m_color_table[MUI_TEXT_COLOR].color, m_color_table[MUI_TEXT_BG_COLOR].color, nullptr, nullptr);
y1 += line_height;
// draw subitem text
- ui().draw_text_full(container(), sampletxt[1], x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, m_color_table[MUI_SUBITEM_COLOR].color, m_color_table[MUI_TEXT_BG_COLOR].color, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ sampletxt[1],
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, m_color_table[MUI_SUBITEM_COLOR].color, m_color_table[MUI_TEXT_BG_COLOR].color, nullptr, nullptr);
y1 += line_height;
// draw selected text
highlight(x1, y1, x2, y1 + line_height, m_color_table[MUI_SELECTED_BG_COLOR].color);
- ui().draw_text_full(container(), sampletxt[2], x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, m_color_table[MUI_SELECTED_COLOR].color, m_color_table[MUI_SELECTED_BG_COLOR].color, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ sampletxt[2],
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, m_color_table[MUI_SELECTED_COLOR].color, m_color_table[MUI_SELECTED_BG_COLOR].color, nullptr, nullptr);
y1 += line_height;
// draw mouse over text
highlight(x1, y1, x2, y1 + line_height, m_color_table[MUI_MOUSEOVER_BG_COLOR].color);
- ui().draw_text_full(container(), sampletxt[3], x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, m_color_table[MUI_MOUSEOVER_COLOR].color, m_color_table[MUI_MOUSEOVER_BG_COLOR].color, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ sampletxt[3],
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, m_color_table[MUI_MOUSEOVER_COLOR].color, m_color_table[MUI_MOUSEOVER_BG_COLOR].color, nullptr, nullptr);
y1 += line_height;
// draw clone text
- ui().draw_text_full(container(), sampletxt[4], x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, m_color_table[MUI_CLONE_COLOR].color, m_color_table[MUI_TEXT_BG_COLOR].color, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ sampletxt[4],
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, m_color_table[MUI_CLONE_COLOR].color, m_color_table[MUI_TEXT_BG_COLOR].color, nullptr, nullptr);
}
@@ -890,8 +922,12 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
float width, maxwidth = origx2 - origx1;
// top text
- ui().draw_text_full(container(), m_title, 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
- mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width);
+ ui().draw_text_full(
+ container(),
+ m_title,
+ 0.0f, 0.0f, 1.0f,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width);
const float lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
width += 2 * lr_border;
maxwidth = std::max(maxwidth, width);
@@ -915,7 +951,7 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
container(),
m_title,
x1, y1, x2 - x1,
- ui::text_layout::CENTER, ui::text_layout::NEVER,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color());
std::string sampletxt(_("Color preview:"));
@@ -923,7 +959,7 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
container(),
sampletxt,
0.0f, 0.0f, 1.0f,
- ui::text_layout::CENTER, ui::text_layout::NEVER,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
&width);
width += 2 * lr_border;
@@ -947,7 +983,7 @@ void menu_rgb_ui::custom_render(void *selectedref, float top, float bottom, floa
container(),
sampletxt,
x1, y1, width - lr_border,
- ui::text_layout::CENTER, ui::text_layout::NEVER,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, rgb_t::white(), rgb_t::black());
x1 += width + (lr_border * 2.0f);
diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp
index a707c76459e..f25ece6015a 100644
--- a/src/frontend/mame/ui/datmenu.cpp
+++ b/src/frontend/mame/ui/datmenu.cpp
@@ -35,10 +35,11 @@ namespace ui {
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_system_info *system)
: menu(mui, container)
- , m_actual(0)
, m_system(!system ? &system_list::instance().systems()[driver_list::find(mui.machine().system().name)] : system)
, m_swinfo(nullptr)
, m_issoft(false)
+ , m_layout()
+ , m_actual(0)
{
for (device_image_interface& image : image_interface_enumerator(mui.machine().root_device()))
@@ -71,23 +72,24 @@ menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_software_info *swinfo, const ui_system_info *system)
: menu(mui, container)
- , m_actual(0)
, m_system(!system ? &system_list::instance().systems()[driver_list::find(mui.machine().system().name)] : system)
, m_swinfo(swinfo)
+ , m_issoft(true)
+ , m_layout()
+ , m_actual(0)
, m_list(swinfo->listname)
, m_short(swinfo->shortname)
, m_long(swinfo->longname)
, m_parent(swinfo->parentname)
- , m_issoft(true)
{
- if (swinfo != nullptr && !swinfo->infotext.empty())
+ if (swinfo && !swinfo->infotext.empty())
m_items_list.emplace_back(_("Software List Info"), 0, "");
std::vector<std::string> lua_list;
if (mame_machine_manager::instance()->lua()->call_plugin("data_list", std::string(m_short).append(1, ',').append(m_list).c_str(), lua_list))
{
int count = 1;
- for(std::string &item : lua_list)
+ for (std::string &item : lua_list)
{
std::string version;
mame_machine_manager::instance()->lua()->call_plugin("data_version", count - 1, version);
@@ -106,24 +108,109 @@ menu_dats_view::~menu_dats_view()
}
//-------------------------------------------------
-// handle
+// add text to layout
//-------------------------------------------------
-void menu_dats_view::handle()
+void menu_dats_view::add_info_text(text_layout &layout, std::string_view text, rgb_t color, float size)
{
- const event *menu_event = process(FLAG_UI_DATS);
- if (menu_event != nullptr)
+ char justify = 'l'; // left justify by default
+ if ((text.length() > 3) && (text[0] == '#') && (text[1] == 'j'))
{
- if (menu_event->iptkey == IPT_UI_LEFT && m_actual > 0)
+ auto const eol = text.find('\n');
+ if ((std::string_view::npos != eol) && (2 < eol))
{
- m_actual--;
- reset(reset_options::SELECT_FIRST);
+ justify = text[2];
+ text.remove_prefix(eol + 1);
}
+ }
- if (menu_event->iptkey == IPT_UI_RIGHT && m_actual < m_items_list.size() - 1)
+ if ('2' == justify)
+ {
+ while (!text.empty())
{
- m_actual++;
- reset(reset_options::SELECT_FIRST);
+ // pop a line from the front
+ auto const eol = text.find('\n');
+ std::string_view const line = (std::string_view::npos != eol)
+ ? text.substr(0, eol + 1)
+ : text;
+ text.remove_prefix(line.length());
+
+ // split on the first tab
+ auto const split = line.find('\t');
+ if (std::string_view::npos != split)
+ {
+ layout.add_text(line.substr(0, split), text_layout::text_justify::LEFT, color, rgb_t::transparent(), size);
+ layout.add_text(" ", text_layout::text_layout::text_justify::LEFT, color, rgb_t::transparent(), size);
+ layout.add_text(line.substr(split + 1), text_layout::text_justify::RIGHT, color, rgb_t::transparent(), size);
+ }
+ else
+ {
+ layout.add_text(line, text_layout::text_justify::LEFT, color, rgb_t::transparent(), size);
+ }
+ }
+ }
+ else
+ {
+ // use the same alignment for all the text
+ auto const j =
+ ('c' == justify) ? text_layout::text_justify::CENTER :
+ ('r' == justify) ? text_layout::text_justify::RIGHT :
+ text_layout::text_justify::LEFT;
+ layout.add_text(text, j, color, rgb_t::transparent(), size);
+ }
+
+}
+
+//-------------------------------------------------
+// handle
+//-------------------------------------------------
+
+void menu_dats_view::handle()
+{
+ event const *const menu_event = process(PROCESS_LR_ALWAYS | PROCESS_CUSTOM_NAV);
+ if (menu_event)
+ {
+ switch (menu_event->iptkey)
+ {
+ case IPT_UI_LEFT:
+ if (m_actual > 0)
+ {
+ m_actual--;
+ reset(reset_options::SELECT_FIRST);
+ }
+ break;
+
+ case IPT_UI_RIGHT:
+ if ((m_actual + 1) < m_items_list.size())
+ {
+ m_actual++;
+ reset(reset_options::SELECT_FIRST);
+ }
+ break;
+
+ case IPT_UI_UP:
+ --top_line;
+ break;
+
+ case IPT_UI_DOWN:
+ ++top_line;
+ break;
+
+ case IPT_UI_PAGE_UP:
+ top_line -= m_visible_lines - 3;
+ break;
+
+ case IPT_UI_PAGE_DOWN:
+ top_line += m_visible_lines - 3;
+ break;
+
+ case IPT_UI_HOME:
+ top_line = 0;
+ break;
+
+ case IPT_UI_END:
+ top_line = m_layout->lines() - m_visible_lines;
+ break;
}
}
}
@@ -138,9 +225,8 @@ void menu_dats_view::populate(float &customtop, float &custombottom)
if (!paused)
machine().pause();
- (m_issoft == true) ? get_data_sw() : get_data();
+ m_layout = std::nullopt;
- item_append(menu_item_type::SEPARATOR, (FLAG_UI_DATS | FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW));
customtop = 2.0f * ui().get_line_height() + 4.0f * ui().box_tb_border();
custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border();
@@ -162,7 +248,6 @@ void menu_dats_view::draw(uint32_t flags)
float const visible_left = (1.0f - visible_width) * 0.5f;
float const extra_height = 2.0f * line_height;
float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
- int const visible_items = item_count() - 2;
// determine effective positions taking into account the hilighting arrows
float const effective_width = visible_width - 2.0f * gutter_width;
@@ -179,116 +264,104 @@ void menu_dats_view::draw(uint32_t flags)
// compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
- // compute left box size
- float x1 = visible_left;
- float y1 = visible_top - ui().box_tb_border();
- float x2 = x1 + visible_width;
- float y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
- float line = visible_top + float(m_visible_lines) * line_height;
+ // compute text box size
+ float const x1 = visible_left;
+ float const y1 = visible_top - ui().box_tb_border();
+ float const x2 = x1 + visible_width;
+ float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
+ float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
+ float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
+ float const separator = visible_top + float(m_visible_lines) * line_height;
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
+ if (!m_layout || (m_layout->width() != effective_width))
+ {
+ std::string buffer;
+ if (m_issoft)
+ get_data_sw(buffer);
+ else
+ get_data(buffer);
+ m_layout.emplace(ui().create_layout(container(), effective_width));
+ add_info_text(*m_layout, buffer, ui().colors().text_color());
+ }
+ int const visible_items = m_layout->lines();
m_visible_lines = (std::min)(visible_items, m_visible_lines);
top_line = (std::max)(0, top_line);
if (top_line + m_visible_lines >= visible_items)
top_line = visible_items - m_visible_lines;
clear_hover();
- int const n_loop = (std::min)(visible_items, m_visible_lines);
- for (int linenum = 0; linenum < n_loop; linenum++)
+ if (top_line)
{
- float const line_y = visible_top + float(linenum) * line_height;
- int const itemnum = top_line + linenum;
- menu_item const &pitem = item(itemnum);
- std::string_view const itemtext = pitem.text;
- float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float const line_y0 = line_y;
- float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float const line_y1 = line_y + line_height;
-
+ // if we're on the top line, display the up arrow
rgb_t fgcolor = ui().colors().text_color();
- rgb_t bgcolor = ui().colors().text_bg_color();
-
- if (!linenum && top_line)
- {
- // if we're on the top line, display the up arrow
- if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1))
- {
- fgcolor = ui().colors().mouseover_color();
- bgcolor = ui().colors().mouseover_bg_color();
- highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
- set_hover(HOVER_ARROW_UP);
- }
- draw_arrow(
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
- fgcolor, ROT0);
- }
- else if ((linenum == m_visible_lines - 1) && (itemnum != visible_items - 1))
- {
- // if we're on the bottom line, display the down arrow
- if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1))
- {
- fgcolor = ui().colors().mouseover_color();
- bgcolor = ui().colors().mouseover_bg_color();
- highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
- set_hover(HOVER_ARROW_DOWN);
- }
- draw_arrow(
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
- fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
- }
- else if (pitem.subtext.empty())
+ if (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
{
- // draw dats text
- ui().draw_text_full(
- container(), itemtext,
- effective_left, line_y, effective_width,
- ui::text_layout::LEFT, ui::text_layout::NEVER,
- mame_ui_manager::NORMAL, fgcolor, bgcolor,
- nullptr, nullptr);
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, visible_top,
+ line_x1, visible_top + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_UP);
}
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, visible_top + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, visible_top + 0.75f * line_height,
+ fgcolor, ROT0);
}
-
- for (size_t count = visible_items; count < item_count(); count++)
+ if ((top_line + m_visible_lines) < visible_items)
{
- menu_item const &pitem = item(count);
- std::string_view const itemtext = pitem.text;
- float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float const line_y0 = line;
- float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float const line_y1 = line + line_height;
- rgb_t const fgcolor = ui().colors().selected_color();
- rgb_t const bgcolor = ui().colors().selected_bg_color();
-
- if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
- set_hover(count);
-
- if (pitem.type == menu_item_type::SEPARATOR)
- {
- container().add_line(
- visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
- UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- }
- else
+ // if we're on the bottom line, display the down arrow
+ float const line_y = visible_top + float(m_visible_lines - 1) * line_height;
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, line_y, line_x1, line_y + line_height))
{
- highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
- ui().draw_text_full(
- container(), itemtext,
- effective_left, line, effective_width,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
- mame_ui_manager::NORMAL, fgcolor, bgcolor,
- nullptr, nullptr);
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, line_y,
+ line_x1, line_y + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_DOWN);
}
- line += line_height;
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
+ fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
}
+ // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
+ m_visible_items = m_visible_lines - (top_line ? 1 : 0) - (top_line + m_visible_lines != visible_items);
+ m_layout->emit(
+ container(),
+ top_line ? (top_line + 1) : 0, m_visible_items,
+ effective_left, visible_top + (top_line ? line_height : 0.0f));
+
+ // add visual separator before the "return to prevous menu" item
+ container().add_line(
+ visible_left, separator + (0.5f * line_height),
+ visible_left + visible_width, separator + (0.5f * line_height),
+ UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+
+ menu_item const &pitem = item(0);
+ std::string_view const itemtext = pitem.text;
+ float const line_y0 = separator + line_height;
+ float const line_y1 = line_y0 + line_height;
+
+ if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
+ set_hover(0);
+
+ highlight(line_x0, line_y0, line_x1, line_y1, ui().colors().selected_bg_color());
+ ui().draw_text_full(
+ container(), itemtext,
+ effective_left, line_y0, effective_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL,
+ ui().colors().selected_color(), ui().colors().selected_bg_color(),
+ nullptr, nullptr);
+
// if there is something special to add, do it by calling the virtual method
custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- m_visible_items = m_visible_lines - (top_line != 0) - (top_line + m_visible_lines != visible_items);
}
//-------------------------------------------------
@@ -299,11 +372,15 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
{
float maxwidth = origx2 - origx1;
float width;
- std::string_view driver = m_issoft ? m_swinfo->longname : m_system->description;
+ std::string_view const driver = m_issoft ? m_swinfo->longname : m_system->description;
float const lr_border = ui().box_lr_border() * machine().render().ui_aspect(&container());
- ui().draw_text_full(container(), driver, 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
- mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
+ ui().draw_text_full(
+ container(),
+ driver,
+ 0.0f, 0.0f, 1.0f,
+ ui::text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
width += 2 * lr_border;
maxwidth = std::max(maxwidth, width);
@@ -325,7 +402,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
container(),
driver,
x1, y1, x2 - x1,
- ui::text_layout::CENTER, ui::text_layout::NEVER,
+ text_layout::text_justify::CENTER, ui::text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color());
maxwidth = 0;
@@ -335,7 +412,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
container(),
elem.label,
0.0f, 0.0f, 1.0f,
- ui::text_layout::CENTER, ui::text_layout::NEVER,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
&width, nullptr);
maxwidth += width;
@@ -369,7 +446,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
container(),
elem.label,
x1, y1, 1.0f,
- ui::text_layout::LEFT, ui::text_layout::NEVER,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NONE, fcolor, bcolor,
&width, nullptr);
@@ -386,7 +463,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
container(),
elem.label,
x1, y1, 1.0f,
- ui::text_layout::LEFT, ui::text_layout::NEVER,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, fcolor, bcolor,
&width, nullptr);
x1 += width + space;
@@ -394,9 +471,14 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
}
// bottom
- std::string revision;
- revision.assign(_("Revision: ")).append(m_items_list[m_actual].revision);
- ui().draw_text_full(container(), revision, 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &width, nullptr);
+ std::string const revision(util::string_format(_("Revision: %1$s"), m_items_list[m_actual].revision));
+ ui().draw_text_full(
+ container(),
+ revision,
+ 0.0f, 0.0f, 1.0f,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
+ &width, nullptr);
width += 2 * lr_border;
maxwidth = std::max(origx2 - origx1, width);
@@ -419,7 +501,7 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
container(),
revision,
x1, y1, x2 - x1,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color());
}
@@ -448,43 +530,17 @@ bool menu_dats_view::custom_mouse_down()
// load data from DATs
//-------------------------------------------------
-void menu_dats_view::get_data()
+void menu_dats_view::get_data(std::string &buffer)
{
- std::vector<int> xstart, xend;
- std::string buffer;
mame_machine_manager::instance()->lua()->call_plugin("data", m_items_list[m_actual].option, buffer);
-
- float const aspect = machine().render().ui_aspect(&container());
- float const line_height = ui().get_line_height();
- float const gutter_width = 0.52f * line_height * aspect;
- float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
- float const effective_width = visible_width - 2.0f * gutter_width;
-
- auto lines = ui().wrap_text(container(), buffer, 0.0f, 0.0f, effective_width, xstart, xend);
- for (int x = 0; x < lines; ++x)
- {
- std::string tempbuf(buffer.substr(xstart[x], xend[x] - xstart[x]));
- if ((tempbuf[0] != '#') || x)
- item_append(std::move(tempbuf), (FLAG_UI_DATS | FLAG_DISABLE), (void *)(uintptr_t)(x + 1));
- }
}
-void menu_dats_view::get_data_sw()
+void menu_dats_view::get_data_sw(std::string &buffer)
{
- std::vector<int> xstart;
- std::vector<int> xend;
- std::string buffer;
if (m_items_list[m_actual].option == 0)
buffer = m_swinfo->infotext;
else
mame_machine_manager::instance()->lua()->call_plugin("data", m_items_list[m_actual].option - 1, buffer);
-
- auto lines = ui().wrap_text(container(), buffer, 0.0f, 0.0f, 1.0f - (4.0f * ui().box_lr_border() * machine().render().ui_aspect(&container())), xstart, xend);
- for (int x = 0; x < lines; ++x)
- {
- std::string tempbuf(buffer.substr(xstart[x], xend[x] - xstart[x]));
- item_append(std::move(tempbuf), (FLAG_UI_DATS | FLAG_DISABLE), (void *)(uintptr_t)(x + 1));
- }
}
} // namespace ui
diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h
index 45de4f423a5..33e3d160b84 100644
--- a/src/frontend/mame/ui/datmenu.h
+++ b/src/frontend/mame/ui/datmenu.h
@@ -15,8 +15,11 @@
#pragma once
#include "ui/menu.h"
+#include "ui/text.h"
+#include <optional>
#include <string>
+#include <utility>
#include <vector>
@@ -37,31 +40,37 @@ public:
menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_system_info *system = nullptr);
virtual ~menu_dats_view() override;
+ static void add_info_text(text_layout &layout, std::string_view text, rgb_t color, float size = 1.0f);
+
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual bool custom_mouse_down() override;
private:
+ struct list_items
+ {
+ list_items(std::string &&l, int i, std::string &&rev) : label(std::move(l)), option(i), revision(std::move(rev)) { }
+
+ std::string label;
+ int option;
+ std::string revision;
+ };
+
// draw dats menu
virtual void draw(uint32_t flags) override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
+ void get_data(std::string &buffer);
+ void get_data_sw(std::string &buffer);
+
+ ui_system_info const *const m_system;
+ ui_software_info const *const m_swinfo;
+ bool const m_issoft;
+ std::optional<text_layout> m_layout;
int m_actual;
- const ui_system_info *m_system;
- const ui_software_info *m_swinfo;
std::string m_list, m_short, m_long, m_parent;
- void get_data();
- void get_data_sw();
- bool m_issoft;
- struct list_items
- {
- list_items(std::string l, int i, std::string rev) { label = l; option = i; revision = rev; }
- std::string label;
- int option;
- std::string revision;
- };
std::vector<list_items> m_items_list;
};
diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp
index a361bfd325f..f610189b771 100644
--- a/src/frontend/mame/ui/dirmenu.cpp
+++ b/src/frontend/mame/ui/dirmenu.cpp
@@ -122,7 +122,7 @@ void menu_directory::custom_render(void *selectedref, float top, float bottom, f
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -200,12 +200,12 @@ void menu_display_actual::custom_render(void *selectedref, float top, float bott
float const maxwidth(draw_text_box(
std::begin(m_folders), std::end(m_folders),
origx1, origx2, origy1 - (3.0f * ui().box_tb_border()) - (m_folders.size() * lineheight), origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f));
draw_text_box(
std::begin(m_heading), std::end(m_heading),
0.5f * (1.0f - maxwidth), 0.5f * (1.0f + maxwidth), origy1 - top, origy1 - top + lineheight + (2.0f * ui().box_tb_border()),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -426,7 +426,7 @@ void menu_add_change_folder::custom_render(void *selectedref, float top, float b
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
// bottom text
@@ -434,7 +434,7 @@ void menu_add_change_folder::custom_render(void *selectedref, float top, float b
draw_text_box(
std::begin(bottomtext), std::end(bottomtext),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
@@ -518,7 +518,7 @@ void menu_remove_folder::custom_render(void *selectedref, float top, float botto
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
diff --git a/src/frontend/mame/ui/inifile.cpp b/src/frontend/mame/ui/inifile.cpp
index 77b1cf47945..87cdd9329b1 100644
--- a/src/frontend/mame/ui/inifile.cpp
+++ b/src/frontend/mame/ui/inifile.cpp
@@ -268,7 +268,7 @@ favorite_manager::favorite_manager(ui_options &options)
// need to populate this, it isn't displayed anywhere else
tmpmatches.infotext.append(tmpmatches.longname);
- tmpmatches.infotext.append("\t\n\n");
+ tmpmatches.infotext.append(1, '\n');
tmpmatches.infotext.append(_("swlist-info", "Software list/item"));
tmpmatches.infotext.append(1, '\n');
tmpmatches.infotext.append(tmpmatches.listname);
diff --git a/src/frontend/mame/ui/inputmap.cpp b/src/frontend/mame/ui/inputmap.cpp
index 4d2c2c9bb8d..08cbab0facc 100644
--- a/src/frontend/mame/ui/inputmap.cpp
+++ b/src/frontend/mame/ui/inputmap.cpp
@@ -282,7 +282,7 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float
draw_text_box(
std::begin(text), std::end(text),
x1, x2, y2 + ui().box_tb_border(), y2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
else
@@ -299,7 +299,7 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float
draw_text_box(
std::begin(text), std::end(text),
x1, x2, y2 + ui().box_tb_border(), y2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_RED_COLOR, 1.0f);
}
else if (selectedref)
@@ -311,7 +311,7 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float
draw_text_box(
std::begin(text), std::end(text),
x1, x2, y2 + ui().box_tb_border(), y2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
else
@@ -322,7 +322,7 @@ void menu_input::custom_render(void *selectedref, float top, float bottom, float
draw_text_box(
std::begin(text), std::end(text),
x1, x2, y2 + ui().box_tb_border(), y2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
}
diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp
index 5b2bb73b7ad..ffbd52fa620 100644
--- a/src/frontend/mame/ui/menu.cpp
+++ b/src/frontend/mame/ui/menu.cpp
@@ -446,8 +446,13 @@ void menu::draw(uint32_t flags)
// first draw the FPS counter
if (ui().show_fps_counter())
{
- ui().draw_text_full(container(), machine().video().speed_text(), 0.0f, 0.0f, 1.0f,
- ui::text_layout::RIGHT, ui::text_layout::WORD, mame_ui_manager::OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ machine().video().speed_text(),
+ 0.0f, 0.0f, 1.0f,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::WORD,
+ mame_ui_manager::OPAQUE_, rgb_t::white(), rgb_t::black(),
+ nullptr, nullptr);
}
bool const customonly = (flags & PROCESS_CUSTOM_ONLY);
@@ -627,8 +632,13 @@ void menu::draw(uint32_t flags)
container().add_line(visible_left, line_y0 + 0.5f * line_height, visible_left + ((visible_width - heading_width) / 2) - lr_border, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
container().add_line(visible_left + visible_width - ((visible_width - heading_width) / 2) + lr_border, line_y0 + 0.5f * line_height, visible_left + visible_width, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
- ui().draw_text_full(container(), itemtext, effective_left, line_y0, effective_width,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ itemtext,
+ effective_left, line_y0, effective_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL, fgcolor, bgcolor,
+ nullptr, nullptr);
}
else
{
@@ -637,8 +647,13 @@ void menu::draw(uint32_t flags)
float item_width, subitem_width;
// draw the left-side text
- ui().draw_text_full(container(), itemtext, effective_left, line_y0, effective_width,
- ui::text_layout::LEFT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, &item_width, nullptr);
+ ui().draw_text_full(
+ container(),
+ itemtext,
+ effective_left, line_y0, effective_width,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL, fgcolor, bgcolor,
+ &item_width, nullptr);
if (pitem.flags & FLAG_COLOR_BOX)
{
@@ -679,8 +694,13 @@ void menu::draw(uint32_t flags)
fgcolor2 = rgb_t(0xff,0xff,0x00);
// draw the subitem right-justified
- ui().draw_text_full(container(), subitem_text, effective_left + item_width, line_y0, effective_width - item_width,
- ui::text_layout::RIGHT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, subitem_invert ? fgcolor3 : fgcolor2, bgcolor, &subitem_width, nullptr);
+ ui().draw_text_full(
+ container(),
+ subitem_text,
+ effective_left + item_width, line_y0, effective_width - item_width,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL, subitem_invert ? fgcolor3 : fgcolor2, bgcolor,
+ &subitem_width, nullptr);
}
// apply arrows
@@ -720,8 +740,13 @@ void menu::draw(uint32_t flags)
float target_width, target_height;
// compute the multi-line target width/height
- ui().draw_text_full(container(), pitem.subtext, 0, 0, visible_width * 0.75f,
- ui::text_layout::RIGHT, ui::text_layout::WORD, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &target_width, &target_height);
+ ui().draw_text_full(
+ container(),
+ pitem.subtext,
+ 0, 0, visible_width * 0.75f,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::WORD,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
+ &target_width, &target_height);
// determine the target location
float const target_x = visible_left + visible_width - target_width - lr_border;
@@ -730,14 +755,19 @@ void menu::draw(uint32_t flags)
target_y = line_y - target_height - ui().box_tb_border();
// add a box around that
- ui().draw_outlined_box(container(), target_x - lr_border,
- target_y - ui().box_tb_border(),
- target_x + target_width + lr_border,
- target_y + target_height + ui().box_tb_border(),
+ ui().draw_outlined_box(
+ container(),
+ target_x - lr_border, target_y - ui().box_tb_border(),
+ target_x + target_width + lr_border, target_y + target_height + ui().box_tb_border(),
subitem_invert ? ui().colors().selected_bg_color() : ui().colors().background_color());
- ui().draw_text_full(container(), pitem.subtext, target_x, target_y, target_width,
- ui::text_layout::RIGHT, ui::text_layout::WORD, mame_ui_manager::NORMAL, ui().colors().selected_color(), ui().colors().selected_bg_color(), nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ pitem.subtext,
+ target_x, target_y, target_width,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::WORD,
+ mame_ui_manager::NORMAL, ui().colors().selected_color(), ui().colors().selected_bg_color(),
+ nullptr, nullptr);
}
// if there is something special to add, do it by calling the virtual method
@@ -767,8 +797,13 @@ void menu::draw_text_box()
float target_x, target_y;
// compute the multi-line target width/height
- ui().draw_text_full(container(), text, 0, 0, 1.0f - 2.0f * lr_border - 2.0f * gutter_width,
- ui::text_layout::LEFT, ui::text_layout::WORD, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), &target_width, &target_height);
+ ui().draw_text_full(
+ container(),
+ text,
+ 0, 0, 1.0f - 2.0f * lr_border - 2.0f * gutter_width,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::WORD,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
+ &target_width, &target_height);
target_height += 2.0f * line_height;
if (target_height > 1.0f - 2.0f * ui().box_tb_border())
target_height = floorf((1.0f - 2.0f * ui().box_tb_border()) / line_height) * line_height;
@@ -792,23 +827,33 @@ void menu::draw_text_box()
target_y = 1.0f - ui().box_tb_border() - target_height;
// add a box around that
- ui().draw_outlined_box(container(), target_x - lr_border - gutter_width,
- target_y - ui().box_tb_border(),
- target_x + target_width + gutter_width + lr_border,
- target_y + target_height + ui().box_tb_border(),
- (m_items[0].flags & FLAG_REDTEXT) ? UI_RED_COLOR : ui().colors().background_color());
- ui().draw_text_full(container(), text, target_x, target_y, target_width,
- ui::text_layout::LEFT, ui::text_layout::WORD, mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(), nullptr, nullptr);
+ ui().draw_outlined_box(
+ container(),
+ target_x - lr_border - gutter_width, target_y - ui().box_tb_border(),
+ target_x + target_width + gutter_width + lr_border, target_y + target_height + ui().box_tb_border(),
+ (m_items[0].flags & FLAG_REDTEXT) ? UI_RED_COLOR : ui().colors().background_color());
+ ui().draw_text_full(
+ container(),
+ text,
+ target_x, target_y, target_width,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::WORD,
+ mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(),
+ nullptr, nullptr);
// draw the "return to prior menu" text with a hilight behind it
highlight(
- target_x + 0.5f * UI_LINE_WIDTH,
- target_y + target_height - line_height,
- target_x + target_width - 0.5f * UI_LINE_WIDTH,
- target_y + target_height,
- ui().colors().selected_bg_color());
- ui().draw_text_full(container(), backtext, target_x, target_y + target_height - line_height, target_width,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, ui().colors().selected_color(), ui().colors().selected_bg_color(), nullptr, nullptr);
+ target_x + 0.5f * UI_LINE_WIDTH,
+ target_y + target_height - line_height,
+ target_x + target_width - 0.5f * UI_LINE_WIDTH,
+ target_y + target_height,
+ ui().colors().selected_bg_color());
+ ui().draw_text_full(
+ container(),
+ backtext,
+ target_x, target_y + target_height - line_height, target_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL, ui().colors().selected_color(), ui().colors().selected_bg_color(),
+ nullptr, nullptr);
// artificially set the hover to the last item so a double-click exits
m_hover = m_items.size() - 1;
@@ -875,27 +920,33 @@ void menu::handle_events(uint32_t flags, event &ev)
}
else if (m_hover == HOVER_ARROW_UP)
{
- if (flags & FLAG_UI_DATS)
+ if (flags & PROCESS_CUSTOM_NAV)
+ {
+ ev.iptkey = IPT_UI_PAGE_UP;
+ stop = true;
+ }
+ else
{
+ m_selected -= m_visible_items;
+ if (m_selected < 0)
+ m_selected = 0;
top_line -= m_visible_items - (last_item_visible() ? 1 : 0);
- return;
}
- m_selected -= m_visible_items;
- if (m_selected < 0)
- m_selected = 0;
- top_line -= m_visible_items - (last_item_visible() ? 1 : 0);
}
else if (m_hover == HOVER_ARROW_DOWN)
{
- if ((flags & FLAG_UI_DATS) != 0)
+ if (flags & PROCESS_CUSTOM_NAV)
+ {
+ ev.iptkey = IPT_UI_PAGE_DOWN;
+ stop = true;
+ }
+ else
{
+ m_selected += m_visible_lines - 2 + is_first_selected();
+ if (m_selected > m_items.size() - 1)
+ m_selected = m_items.size() - 1;
top_line += m_visible_lines - 2;
- return;
}
- m_selected += m_visible_lines - 2 + is_first_selected();
- if (m_selected > m_items.size() - 1)
- m_selected = m_items.size() - 1;
- top_line += m_visible_lines - 2;
}
else if (m_hover == HOVER_UI_LEFT)
{
@@ -931,13 +982,15 @@ void menu::handle_events(uint32_t flags, event &ev)
{
if (local_menu_event.zdelta > 0)
{
- if ((flags & FLAG_UI_DATS) != 0)
+ if (flags & PROCESS_CUSTOM_NAV) // FIXME: DAT menu logic - let the derived class handle this
{
top_line -= local_menu_event.num_lines;
return;
}
- if (is_first_selected())
+ else if (is_first_selected())
+ {
select_last_item();
+ }
else
{
m_selected -= local_menu_event.num_lines;
@@ -949,13 +1002,15 @@ void menu::handle_events(uint32_t flags, event &ev)
}
else
{
- if ((flags & FLAG_UI_DATS))
+ if (flags & PROCESS_CUSTOM_NAV) // FIXME: DAT menu logic - let the derived class handle this
{
top_line += local_menu_event.num_lines;
return;
}
- if (is_last_selected())
+ else if (is_last_selected())
+ {
select_first_item();
+ }
else
{
m_selected += local_menu_event.num_lines;
@@ -1024,11 +1079,8 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
validate_selection(1);
// swallow left/right keys if they are not appropriate
- bool ignoreleft = !(flags & PROCESS_LR_ALWAYS) && !(selected_item().flags & FLAG_LEFT_ARROW);
- bool ignoreright = !(flags & PROCESS_LR_ALWAYS) && !(selected_item().flags & FLAG_RIGHT_ARROW);
-
- if ((m_items[0].flags & FLAG_UI_DATS))
- ignoreleft = ignoreright = false;
+ bool const ignoreleft = !(flags & PROCESS_LR_ALWAYS) && !(selected_item().flags & FLAG_LEFT_ARROW);
+ bool const ignoreright = !(flags & PROCESS_LR_ALWAYS) && !(selected_item().flags & FLAG_RIGHT_ARROW);
// accept left/right keys as-is with repeat
if (!ignoreleft && exclusive_input_pressed(iptkey, IPT_UI_LEFT, (flags & PROCESS_LR_REPEAT) ? 6 : 0))
@@ -1039,13 +1091,14 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
// up backs up by one item
if (exclusive_input_pressed(iptkey, IPT_UI_UP, 6))
{
- if ((m_items[0].flags & FLAG_UI_DATS))
+ if (flags & PROCESS_CUSTOM_NAV)
{
- top_line--;
return;
}
- if (is_first_selected())
+ else if (is_first_selected())
+ {
select_last_item();
+ }
else
{
--m_selected;
@@ -1059,13 +1112,14 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
// down advances by one item
if (exclusive_input_pressed(iptkey, IPT_UI_DOWN, 6))
{
- if ((m_items[0].flags & FLAG_UI_DATS))
+ if (flags & PROCESS_CUSTOM_NAV)
{
- top_line++;
return;
}
- if (is_last_selected())
+ else if (is_last_selected())
+ {
select_first_item();
+ }
else
{
++m_selected;
@@ -1079,6 +1133,8 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
// page up backs up by m_visible_items
if (exclusive_input_pressed(iptkey, IPT_UI_PAGE_UP, 6))
{
+ if (flags & PROCESS_CUSTOM_NAV)
+ return;
m_selected -= m_visible_items;
top_line -= m_visible_items - (last_item_visible() ? 1 : 0);
if (m_selected < 0)
@@ -1089,6 +1145,8 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
// page down advances by m_visible_items
if (exclusive_input_pressed(iptkey, IPT_UI_PAGE_DOWN, 6))
{
+ if (flags & PROCESS_CUSTOM_NAV)
+ return;
m_selected += m_visible_lines - 2 + is_first_selected();
top_line += m_visible_lines - 2;
@@ -1099,11 +1157,19 @@ void menu::handle_keys(uint32_t flags, int &iptkey)
// home goes to the start
if (exclusive_input_pressed(iptkey, IPT_UI_HOME, 0))
+ {
+ if (flags & PROCESS_CUSTOM_NAV)
+ return;
select_first_item();
+ }
// end goes to the last
if (exclusive_input_pressed(iptkey, IPT_UI_END, 0))
+ {
+ if (flags & PROCESS_CUSTOM_NAV)
+ return;
select_last_item();
+ }
// pause enables/disables pause
if (!ignorepause && exclusive_input_pressed(iptkey, IPT_UI_PAUSE, 0))
diff --git a/src/frontend/mame/ui/menu.h b/src/frontend/mame/ui/menu.h
index e0f5cbf9f0d..d8fcbcd25ea 100644
--- a/src/frontend/mame/ui/menu.h
+++ b/src/frontend/mame/ui/menu.h
@@ -45,7 +45,6 @@ public:
FLAG_MULTILINE = 1U << 3,
FLAG_REDTEXT = 1U << 4,
FLAG_DISABLE = 1U << 5,
- FLAG_UI_DATS = 1U << 6,
FLAG_UI_HEADING = 1U << 7,
FLAG_COLOR_BOX = 1U << 8
};
@@ -109,10 +108,11 @@ protected:
PROCESS_NOKEYS = 1 << 0,
PROCESS_LR_ALWAYS = 1 << 1,
PROCESS_LR_REPEAT = 1 << 2,
- PROCESS_CUSTOM_ONLY = 1 << 3,
- PROCESS_ONLYCHAR = 1 << 4,
- PROCESS_NOINPUT = 1 << 5,
- PROCESS_NOIMAGE = 1 << 6
+ PROCESS_CUSTOM_NAV = 1 << 3,
+ PROCESS_CUSTOM_ONLY = 1 << 4,
+ PROCESS_ONLYCHAR = 1 << 5,
+ PROCESS_NOINPUT = 1 << 6,
+ PROCESS_NOIMAGE = 1 << 7
};
// options for reset
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index 182094ddfa9..135963406ad 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -840,7 +840,7 @@ void menu_machine_configure::custom_render(void *selectedref, float top, float b
draw_text_box(
std::begin(text), std::end(text),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -963,7 +963,7 @@ void menu_plugins_configure::custom_render(void *selectedref, float top, float b
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
diff --git a/src/frontend/mame/ui/optsmenu.cpp b/src/frontend/mame/ui/optsmenu.cpp
index 88486463ab9..998c8d17c23 100644
--- a/src/frontend/mame/ui/optsmenu.cpp
+++ b/src/frontend/mame/ui/optsmenu.cpp
@@ -149,7 +149,7 @@ void menu_simple_game_options::custom_render(void *selectedref, float top, float
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
diff --git a/src/frontend/mame/ui/selector.cpp b/src/frontend/mame/ui/selector.cpp
index 4f7751713c3..bbc1bf357c5 100644
--- a/src/frontend/mame/ui/selector.cpp
+++ b/src/frontend/mame/ui/selector.cpp
@@ -119,7 +119,7 @@ void menu_selector::custom_render(void *selectedref, float top, float bottom, fl
draw_text_box(
std::begin(tempbuf), std::end(tempbuf),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
// get the text for 'UI Select'
@@ -127,7 +127,7 @@ void menu_selector::custom_render(void *selectedref, float top, float bottom, fl
draw_text_box(
std::begin(tempbuf), std::end(tempbuf),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index ba9facc7d25..11ddcf94ff0 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -321,7 +321,7 @@ void menu_select_launch::software_parts::custom_render(void *selectedref, float
draw_text_box(
std::begin(text), std::end(text),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -427,7 +427,7 @@ void menu_select_launch::bios_selection::custom_render(void *selectedref, float
draw_text_box(
std::begin(text), std::end(text),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -527,6 +527,7 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c
, m_info_view(-1)
, m_items_list()
, m_info_buffer()
+ , m_info_layout()
, m_cache(mui.get_session_data<menu_select_launch, cache_wrapper>(machine()))
, m_is_swlist(is_swlist)
, m_focus(focused_menu::MAIN)
@@ -653,7 +654,7 @@ void menu_select_launch::custom_render(void *selectedref, float top, float botto
draw_text_box(
tempbuf, tempbuf + 3,
origx1, origx2, origy1 - top, y1,
- ui::text_layout::CENTER, ui::text_layout::NEVER, true,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, true,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
// draw toolbar
@@ -760,7 +761,7 @@ void menu_select_launch::custom_render(void *selectedref, float top, float botto
draw_text_box(
std::begin(tempbuf), std::end(tempbuf),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::NEVER, true,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, true,
ui().colors().text_color(), color, 1.0f);
// is favorite? draw the star
@@ -948,7 +949,7 @@ void menu_select_launch::draw_info_arrow(int ub, float origx1, float origx2, flo
bool menu_select_launch::draw_error_text()
{
if (m_ui_error)
- ui().draw_text_box(container(), m_error_text, ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
+ ui().draw_text_box(container(), m_error_text, text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
return m_ui_error;
}
@@ -1039,7 +1040,7 @@ float menu_select_launch::draw_left_panel(
ui().draw_text_full(
container(), str,
x1t, y1, x2 - x1,
- ui::text_layout::LEFT, ui::text_layout::NEVER,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, fgcolor, bgcolor,
nullptr, nullptr, text_size);
y1 += line_height_max;
@@ -1276,7 +1277,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
m_cache.cache_toolbar(machine(), x_size, y2 - y1);
// add backtrack button
- rgb_t color(0xefefefef);
+ rgb_t color(0xffcccccc);
if (mouse_in_rect(backtrack_pos, y1, x2, y2))
{
set_hover(HOVER_BACKTRACK);
@@ -1285,7 +1286,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
ui().draw_text_box(
container(),
have_parent ? _("Return to previous menu") : _("Exit"),
- ui::text_layout::RIGHT, 1.0f - lr_border, ypos,
+ text_layout::text_justify::RIGHT, 1.0f - lr_border, ypos,
ui().colors().background_color());
}
container().add_quad(
@@ -1299,7 +1300,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
for (int z = 0; toolbar_count > z; ++z, x1 += x_spacing)
{
x2 = x1 + x_size;
- color = rgb_t (0xefefefef);
+ color = rgb_t (0xffcccccc);
if (mouse_in_rect(x1, y1, x2, y2))
{
set_hover(HOVER_B_FAV + toolbar_bitmaps[z]);
@@ -1308,7 +1309,7 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
ui().draw_text_box(
container(),
_(hover_msg[toolbar_bitmaps[z]]),
- ui::text_layout::CENTER, (x1 + x2) * 0.5f, ypos,
+ text_layout::text_justify::CENTER, (x1 + x2) * 0.5f, ypos,
ui().colors().background_color());
}
container().add_quad(
@@ -2064,7 +2065,7 @@ void menu_select_launch::draw(uint32_t flags)
container(),
itemtext,
effective_left + icon_offset, line_y, effective_width - icon_offset,
- ui::text_layout::LEFT, ui::text_layout::TRUNCATE,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::TRUNCATE,
mame_ui_manager::NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor,
nullptr, nullptr);
}
@@ -2079,7 +2080,7 @@ void menu_select_launch::draw(uint32_t flags)
container(),
subitem_text,
effective_left + icon_offset, line_y, ui().get_string_width(pitem.subtext),
- ui::text_layout::RIGHT, ui::text_layout::NEVER,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NONE, item_invert ? fgcolor3 : fgcolor, bgcolor,
&subitem_width, nullptr);
subitem_width += gutter_width;
@@ -2091,7 +2092,7 @@ void menu_select_launch::draw(uint32_t flags)
container(),
itemtext,
effective_left + icon_offset, line_y, effective_width - icon_offset - subitem_width,
- ui::text_layout::LEFT, ui::text_layout::TRUNCATE,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::TRUNCATE,
mame_ui_manager::NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor,
&item_width, nullptr);
@@ -2100,7 +2101,7 @@ void menu_select_launch::draw(uint32_t flags)
container(),
subitem_text,
effective_left + icon_offset + item_width, line_y, effective_width - icon_offset - item_width,
- ui::text_layout::RIGHT, ui::text_layout::NEVER,
+ text_layout::text_justify::RIGHT, text_layout::word_wrapping::NEVER,
mame_ui_manager::NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor,
nullptr, nullptr);
}
@@ -2138,13 +2139,21 @@ void menu_select_launch::draw(uint32_t flags)
if (pitem.type == menu_item_type::SEPARATOR)
{
- container().add_line(visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
- UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+ container().add_line(
+ visible_left, line + 0.5f * line_height,
+ visible_left + visible_width, line + 0.5f * line_height,
+ UI_LINE_WIDTH,
+ ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
else
{
- ui().draw_text_full(container(), itemtext, effective_left, line, effective_width, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
- mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ ui().draw_text_full(
+ container(),
+ itemtext,
+ effective_left, line, effective_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL, fgcolor, bgcolor,
+ nullptr, nullptr);
}
line += line_height;
}
@@ -2273,7 +2282,9 @@ float menu_select_launch::draw_right_box_title(float x1, float y1, float x2, flo
{
fgcolor = rgb_t(0xff, 0xff, 0x00);
bgcolor = rgb_t(0xff, 0xff, 0xff);
- ui().draw_textured_box(container(), x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
+ ui().draw_textured_box(
+ container(),
+ x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
bgcolor, rgb_t(43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
}
else if (bgcolor == ui().colors().mouseover_bg_color())
@@ -2282,8 +2293,12 @@ float menu_select_launch::draw_right_box_title(float x1, float y1, float x2, flo
bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
}
- ui().draw_text_full(container(), buffer[cells], x1 + UI_LINE_WIDTH, y1, midl - UI_LINE_WIDTH,
- ui::text_layout::CENTER, ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
+ ui().draw_text_full(
+ container(),
+ buffer[cells],
+ x1 + UI_LINE_WIDTH, y1, midl - UI_LINE_WIDTH,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
x1 += midl;
}
@@ -2386,7 +2401,7 @@ std::string menu_select_launch::arts_render_common(float origx1, float origy1, f
float text_length;
ui().draw_text_full(container(),
_("selmenu-artwork", arts_info[x].first), origx1, origy1, origx2 - origx1,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
&text_length, nullptr);
title_size = (std::max)(text_length + 0.01f, title_size);
}
@@ -2412,7 +2427,7 @@ std::string menu_select_launch::arts_render_common(float origx1, float origy1, f
ui().draw_text_full(container(),
snaptext, origx1, origy1 + ui().box_tb_border(), origx2 - origx1,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor,
nullptr, nullptr, tmp_size);
draw_common_arrow(origx1, origy1 + ui().box_tb_border(), origx2, origy2, m_image_view, FIRST_VIEW, LAST_VIEW, title_size);
@@ -2682,8 +2697,6 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
{
float const line_height = ui().get_line_height();
float text_size = ui().options().infos_size();
- std::vector<int> xstart;
- std::vector<int> xend;
const char *first = "";
ui_software_info const *software;
ui_system_info const *system;
@@ -2698,6 +2711,7 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
if ((m_info_software != software) || (m_info_view != ui_globals::cur_sw_dats_view))
{
m_info_buffer.clear();
+ m_info_layout = std::nullopt;
if (software == m_info_software)
{
m_info_view = ui_globals::cur_sw_dats_view;
@@ -2734,6 +2748,7 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
if (&driver != m_info_driver || ui_globals::curdats_view != m_info_view)
{
m_info_buffer.clear();
+ m_info_layout = std::nullopt;
if (&driver == m_info_driver)
{
m_info_view = ui_globals::curdats_view;
@@ -2783,7 +2798,7 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
ui().draw_text_full(
container(), name,
origx1, origy1, origx2 - origx1,
- ui::text_layout::CENTER, ui::text_layout::NEVER,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
mame_ui_manager::NONE, ui().colors().text_color(), ui().colors().text_bg_color(),
&txt_length, nullptr);
txt_length += 0.01f;
@@ -2807,37 +2822,33 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
if (bgcolor != ui().colors().text_bg_color())
{
- ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
- origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
+ ui().draw_textured_box(
+ container(),
+ origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
+ origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43),
+ hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(1));
}
- ui().draw_text_full(container(), snaptext, origx1, origy1, origx2 - origx1, ui::text_layout::CENTER,
- ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size);
+ ui().draw_text_full(
+ container(),
+ snaptext,
+ origx1, origy1, origx2 - origx1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER,
+ mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size);
- char justify = 'l'; // left justify
- if ((m_info_buffer.length() >= 3) && (m_info_buffer[0] == '#'))
+ sc = origx2 - origx1 - (2.0f * gutter_width);
+ if (!m_info_layout || (m_info_layout->width() != sc))
{
- if (m_info_buffer[1] == 'j')
- justify = m_info_buffer[2];
+ m_info_layout.emplace(
+ ui().create_layout(
+ container(),
+ sc,
+ text_layout::text_justify::LEFT, text_layout::word_wrapping::WORD));
+ menu_dats_view::add_info_text(*m_info_layout, m_info_buffer, ui().colors().text_color(), text_size);
+ m_total_lines = m_info_layout->lines();
}
draw_common_arrow(origx1, origy1, origx2, origy2, m_info_view, 0, total - 1, title_size);
- if (justify == 'f')
- {
- m_total_lines = ui().wrap_text(
- container(), m_info_buffer,
- 0.0f, 0.0f, 1.0f - (2.0f * gutter_width),
- xstart, xend,
- text_size);
- }
- else
- {
- m_total_lines = ui().wrap_text(
- container(), m_info_buffer,
- origx1, origy1, origx2 - origx1 - (2.0f * gutter_width),
- xstart, xend,
- text_size);
- }
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
if (m_total_lines < r_visible_lines)
@@ -2847,82 +2858,23 @@ void menu_select_launch::infos_render(float origx1, float origy1, float origx2,
if (m_topline_datsview + r_visible_lines >= m_total_lines)
m_topline_datsview = m_total_lines - r_visible_lines;
+ // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
+ m_right_visible_lines = r_visible_lines
+ - (m_topline_datsview ? 1 : 0)
+ - ((m_topline_datsview + r_visible_lines < m_total_lines) ? 1 : 0);
+
if (mouse_in_rect(origx1 + gutter_width, oy1, origx2 - gutter_width, origy2))
set_hover(HOVER_INFO_TEXT);
- sc = origx2 - origx1 - (2.0f * gutter_width);
- for (int r = 0; r < r_visible_lines; ++r)
- {
- int itemline = r + m_topline_datsview;
- std::string_view const tempbuf(std::string_view(m_info_buffer).substr(xstart[itemline], xend[itemline] - xstart[itemline]));
- if (!tempbuf.empty() && (tempbuf[0] == '#'))
- continue;
+ if (m_topline_datsview) // up arrow
+ draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
+ if (m_total_lines > (m_topline_datsview + r_visible_lines)) // bottom arrow
+ draw_info_arrow(1, origx1, origx2, oy1 + (float(r_visible_lines - 1) * line_height), line_height, text_size, ud_arrow_width);
- if (r == 0 && m_topline_datsview != 0) // up arrow
- {
- draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
- }
- else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1) // bottom arrow
- {
- draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
- }
- else if (justify == '2') // two-column layout
- {
- // split at first tab
- std::string_view::size_type const splitpos(tempbuf.find('\t'));
- std::string_view const leftcol(tempbuf.substr(0, (std::string_view::npos == splitpos) ? 0U : splitpos));
- std::string_view const rightcol(tempbuf.substr((std::string_view::npos == splitpos) ? 0U : (splitpos + 1U)));
-
- // measure space needed, condense if necessary
- float const leftlen(ui().get_string_width(leftcol, text_size));
- float const rightlen(ui().get_string_width(rightcol, text_size));
- float const textlen(leftlen + rightlen);
- float const tmp_size3((textlen > sc) ? (text_size * (sc / textlen)) : text_size);
-
- // draw in two parts
- ui().draw_text_full(
- container(), leftcol,
- origx1 + gutter_width, oy1, sc,
- ui::text_layout::LEFT, ui::text_layout::TRUNCATE,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(),
- nullptr, nullptr,
- tmp_size3);
- ui().draw_text_full(
- container(), rightcol,
- origx1 + gutter_width, oy1, sc,
- ui::text_layout::RIGHT, ui::text_layout::TRUNCATE,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(),
- nullptr, nullptr,
- tmp_size3);
- }
- else if (justify == 'f' || justify == 'p') // full or partial justify
- {
- // check size
- float const textlen = ui().get_string_width(tempbuf, text_size);
- float tmp_size3 = (textlen > sc) ? text_size * (sc / textlen) : text_size;
- ui().draw_text_full(
- container(), tempbuf,
- origx1 + gutter_width, oy1, origx2 - origx1,
- ui::text_layout::LEFT, ui::text_layout::TRUNCATE,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(),
- nullptr, nullptr,
- tmp_size3);
- }
- else
- {
- ui().draw_text_full(
- container(), tempbuf,
- origx1 + gutter_width, oy1, origx2 - origx1,
- ui::text_layout::LEFT, ui::text_layout::TRUNCATE,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(),
- nullptr, nullptr,
- text_size);
- }
-
- oy1 += (line_height * text_size);
- }
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- m_right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
+ m_info_layout->emit(
+ container(),
+ m_topline_datsview ? (m_topline_datsview + 1) : 0, m_right_visible_lines,
+ origx1 + gutter_width, oy1 + (m_topline_datsview ? line_height : 0.0f));
}
@@ -2937,17 +2889,23 @@ void menu_select_launch::general_info(ui_system_info const *system, game_driver
str << "#j2\n";
- util::stream_format(str, _("Romset\t%1$-.100s\n"), driver.name);
+ if (system)
+ str << system->description;
+ else
+ str << driver.type.fullname();
+ str << "\t\n\n";
+
+ util::stream_format(str, _("Romset\t%1$s\n"), driver.name);
util::stream_format(str, _("Year\t%1$s\n"), driver.year);
- util::stream_format(str, _("Manufacturer\t%1$-.100s\n"), driver.manufacturer);
+ util::stream_format(str, _("Manufacturer\t%1$s\n"), driver.manufacturer);
int cloneof = driver_list::non_bios_clone(driver);
if (0 <= cloneof)
{
util::stream_format(
str,
- _("Driver is Clone of\t%1$-.100s\n"),
- system ? system->parent : driver_list::driver(cloneof).type.fullname());
+ _("Driver is Clone of\t%1$s\n"),
+ system ? std::string_view(system->parent) : std::string_view(driver_list::driver(cloneof).type.fullname()));
}
else
{
diff --git a/src/frontend/mame/ui/selmenu.h b/src/frontend/mame/ui/selmenu.h
index 9a32b33b6db..12da4d2b1f9 100644
--- a/src/frontend/mame/ui/selmenu.h
+++ b/src/frontend/mame/ui/selmenu.h
@@ -20,6 +20,7 @@
#include <map>
#include <memory>
+#include <optional>
#include <vector>
@@ -311,6 +312,7 @@ private:
int m_info_view;
std::vector<std::string> m_items_list;
std::string m_info_buffer;
+ std::optional<text_layout> m_info_layout;
cache &m_cache;
bool m_is_swlist;
diff --git a/src/frontend/mame/ui/simpleselgame.cpp b/src/frontend/mame/ui/simpleselgame.cpp
index 130434a74cf..9ad2fe62dc3 100644
--- a/src/frontend/mame/ui/simpleselgame.cpp
+++ b/src/frontend/mame/ui/simpleselgame.cpp
@@ -149,7 +149,7 @@ void simple_menu_select_game::handle()
container(),
_("The selected game is missing one or more required ROM or CHD images. "
"Please select a different game.\n\nPress any key to continue."),
- ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
+ text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
}
}
@@ -314,7 +314,7 @@ void simple_menu_select_game::custom_render(void *selectedref, float top, float
draw_text_box(
tempbuf, tempbuf + 1,
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
// determine the text to render below
@@ -396,7 +396,7 @@ void simple_menu_select_game::custom_render(void *selectedref, float top, float
draw_text_box(
tempbuf, tempbuf + 4,
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, true,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, true,
ui().colors().text_color(), driver ? m_cached_color : ui().colors().background_color(), 1.0f);
}
diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp
index 4dba8969a90..99b3756bfec 100644
--- a/src/frontend/mame/ui/sliders.cpp
+++ b/src/frontend/mame/ui/sliders.cpp
@@ -9,14 +9,16 @@
*********************************************************************/
#include "emu.h"
+#include "ui/sliders.h"
+
+#include "ui/slider.h"
+#include "ui/ui.h"
#include "osdepend.h"
-#include "ui/ui.h"
-#include "ui/sliders.h"
-#include "ui/slider.h"
namespace ui {
+
menu_sliders::menu_sliders(mame_ui_manager &mui, render_container &container, bool menuless_mode) : menu(mui, container)
{
m_menuless_mode = m_hidden = menuless_mode;
@@ -244,8 +246,12 @@ void menu_sliders::custom_render(void *selectedref, float top, float bottom, flo
y1 += ui().box_tb_border();
// determine the text height
- ui().draw_text_full(container(), tempstring, 0, 0, x2 - x1 - 2.0f * lr_border,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), nullptr, &text_height);
+ ui().draw_text_full(
+ container(),
+ tempstring,
+ 0, 0, x2 - x1 - 2.0f * lr_border,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(), nullptr, &text_height);
// draw the thermometer
bar_left = x1 + lr_border;
@@ -271,8 +277,12 @@ void menu_sliders::custom_render(void *selectedref, float top, float bottom, flo
container().add_line(default_x, bar_bottom, default_x, bar_area_top + bar_area_height, UI_LINE_WIDTH, ui().colors().border_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
// draw the actual text
- ui().draw_text_full(container(), tempstring, x1 + lr_border, y1 + line_height, x2 - x1 - 2.0f * lr_border,
- ui::text_layout::CENTER, ui::text_layout::WORD, mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(), nullptr, &text_height);
+ ui().draw_text_full(
+ container(),
+ tempstring,
+ x1 + lr_border, y1 + line_height, x2 - x1 - 2.0f * lr_border,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::WORD,
+ mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color(), nullptr, &text_height);
}
}
diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp
index c6da9c7589f..b21a039f86a 100644
--- a/src/frontend/mame/ui/slotopt.cpp
+++ b/src/frontend/mame/ui/slotopt.cpp
@@ -221,7 +221,7 @@ void menu_slot_devices::custom_render(void *selectedref, float top, float bottom
draw_text_box(
std::begin(text), std::end(text),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
}
diff --git a/src/frontend/mame/ui/sndmenu.cpp b/src/frontend/mame/ui/sndmenu.cpp
index 52948c8bca2..8eff1ed1b92 100644
--- a/src/frontend/mame/ui/sndmenu.cpp
+++ b/src/frontend/mame/ui/sndmenu.cpp
@@ -164,7 +164,7 @@ void menu_sound_options::custom_render(void *selectedref, float top, float botto
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
diff --git a/src/frontend/mame/ui/state.cpp b/src/frontend/mame/ui/state.cpp
index 98655ffa23e..af56b28e298 100644
--- a/src/frontend/mame/ui/state.cpp
+++ b/src/frontend/mame/ui/state.cpp
@@ -431,13 +431,13 @@ void menu_load_save_state_base::custom_render(void *selectedref, float top, floa
draw_text_box(
std::begin(text), std::next(std::begin(text), count),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + (count * ui().get_line_height()) + (3.0f * ui().box_tb_border()),
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
// draw the confirmation prompt if necessary
if (!m_confirm_prompt.empty())
- ui().draw_text_box(container(), m_confirm_prompt, ui::text_layout::CENTER, 0.5f, 0.5f, ui().colors().background_color());
+ ui().draw_text_box(container(), m_confirm_prompt, text_layout::text_justify::CENTER, 0.5f, 0.5f, ui().colors().background_color());
}
diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp
index 382524b636c..e4bd44763d4 100644
--- a/src/frontend/mame/ui/submenu.cpp
+++ b/src/frontend/mame/ui/submenu.cpp
@@ -443,7 +443,7 @@ void submenu::custom_render(void *selectedref, float top, float bottom, float or
draw_text_box(
std::begin(toptext), std::end(toptext),
origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
if (selectedref)
@@ -455,7 +455,7 @@ void submenu::custom_render(void *selectedref, float top, float bottom, float or
draw_text_box(
std::begin(bottomtext), std::end(bottomtext),
origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
- ui::text_layout::CENTER, ui::text_layout::TRUNCATE, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
ui().colors().text_color(), ui().colors().background_color(), 1.0f);
}
}
diff --git a/src/frontend/mame/ui/text.cpp b/src/frontend/mame/ui/text.cpp
index 981e69b5380..f91f12517a0 100644
--- a/src/frontend/mame/ui/text.cpp
+++ b/src/frontend/mame/ui/text.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
+// copyright-holders:Nathan Woods, Vas Crabb
/*********************************************************************
text.cpp
@@ -10,12 +10,15 @@
#include "emu.h"
#include "text.h"
-#include "rendfont.h"
+
#include "render.h"
-#include "unicode.h"
+#include "rendfont.h"
+
+#include "util/unicode.h"
#include <cstddef>
#include <cstring>
+#include <utility>
namespace ui {
@@ -76,6 +79,191 @@ inline bool is_breakable_char(char32_t ch)
/***************************************************************************
+CLASS TO REPRESENT A LINE
+***************************************************************************/
+
+// information about the "source" of a character - also in a struct
+// to facilitate copying
+struct text_layout::source_info
+{
+ size_t start;
+ size_t span;
+};
+
+
+// this should really be "positioned glyph" as glyphs != characters, but
+// we'll get there eventually
+struct text_layout::positioned_char
+{
+ char32_t character;
+ char_style style;
+ source_info source;
+ float xoffset;
+ float xwidth;
+};
+
+
+class text_layout::line
+{
+public:
+ using size_type = size_t;
+ static constexpr size_type npos = ~size_type(0);
+
+ line(float yoffset, float height) : m_yoffset(yoffset), m_height(height)
+ {
+ }
+
+ // methods
+ void add_character(text_layout &layout, char32_t ch, char_style const &style, source_info const &source)
+ {
+ // get the width of this character
+ float const chwidth = layout.get_char_width(ch, style.size);
+
+ // append the positioned character
+ m_characters.emplace_back(positioned_char{ ch, style, source, m_width, chwidth });
+ m_width += chwidth;
+
+ // we might be bigger
+ m_height = std::max(m_height, style.size * layout.yscale());
+ }
+
+ void truncate(size_t position)
+ {
+ assert(position <= m_characters.size());
+
+ // are we actually truncating?
+ if (position < m_characters.size())
+ {
+ // set the width as appropriate
+ m_width = m_characters[position].xoffset;
+
+ // and resize the array
+ m_characters.resize(position);
+ }
+ }
+
+ void set_justification(text_justify justify)
+ {
+ switch (justify)
+ {
+ case text_justify::RIGHT:
+ if (npos == m_right_justify_start)
+ m_right_justify_start = m_characters.size();
+ [[fallthrough]];
+ case text_justify::CENTER:
+ if (npos == m_center_justify_start)
+ m_center_justify_start = m_characters.size();
+ break;
+ case text_justify::LEFT:
+ break;
+ }
+ }
+
+ void align_text(text_layout const &layout)
+ {
+ assert(m_right_justify_start >= m_center_justify_start);
+
+ if (m_characters.empty() || m_center_justify_start)
+ {
+ // at least some of the text is left-justified - anchor to left
+ m_anchor_pos = 0.0f;
+ m_anchor_target = 0.0f;
+ if ((layout.width() > m_width) && (m_characters.size() > m_center_justify_start))
+ {
+ // at least some text is not left-justified
+ if (m_right_justify_start == m_center_justify_start)
+ {
+ // all text that isn't left-justified is right-justified
+ float const right_offset = layout.width() - m_width;
+ for (size_t i = m_right_justify_start; m_characters.size() > i; ++i)
+ m_characters[i].xoffset += right_offset;
+ m_width = layout.width();
+ }
+ else if (m_characters.size() <= m_right_justify_start)
+ {
+ // all text that isn't left-justified is center-justified
+ float const center_width = m_width - m_characters[m_center_justify_start].xoffset;
+ float const center_offset = ((layout.width() - center_width) * 0.5f) - m_characters[m_center_justify_start].xoffset;
+ if (0.0f < center_offset)
+ {
+ for (size_t i = m_center_justify_start; m_characters.size() > i; ++i)
+ m_characters[i].xoffset += center_offset;
+ m_width += center_offset;
+ }
+ }
+ else
+ {
+ // left, right and center-justified parts
+ float const center_width = m_characters[m_right_justify_start].xoffset - m_characters[m_center_justify_start].xoffset;
+ float const center_offset = ((layout.width() - center_width) * 0.5f) - m_characters[m_center_justify_start].xoffset;
+ float const right_offset = layout.width() - m_width;
+ if (center_offset > right_offset)
+ {
+ // right-justified text pushes centre-justified text to the left
+ for (size_t i = m_center_justify_start; m_right_justify_start > i; ++i)
+ m_characters[i].xoffset += right_offset;
+ }
+ else if (0.0f < center_offset)
+ {
+ // left-justified text doesn't push centre-justified text to the right
+ for (size_t i = m_center_justify_start; m_right_justify_start > i; ++i)
+ m_characters[i].xoffset += center_offset;
+ }
+ for (size_t i = m_right_justify_start; m_characters.size() > i; ++i)
+ m_characters[i].xoffset += right_offset;
+ m_width = layout.width();
+ }
+ }
+ }
+ else if (m_characters.size() <= m_right_justify_start)
+ {
+ // all text is center-justified - anchor to center
+ m_anchor_pos = 0.5f;
+ m_anchor_target = 0.5f;
+ }
+ else
+ {
+ // at least some text is right-justified - anchor to right
+ m_anchor_pos = 1.0f;
+ m_anchor_target = 1.0f;
+ if ((layout.width() > m_width) && (m_right_justify_start > m_center_justify_start))
+ {
+ // mixed center-justified and right-justified text
+ float const center_width = m_characters[m_right_justify_start].xoffset;
+ float const center_offset = (layout.width() - m_width + (center_width * 0.5f)) - (layout.width() * 0.5f);
+ if (0.0f < center_offset)
+ {
+ for (size_t i = m_right_justify_start; m_characters.size() > i; ++i)
+ m_characters[i].xoffset += center_offset;
+ m_width += center_offset;
+ }
+ }
+ }
+ }
+
+ // accessors
+ float xoffset(text_layout const &layout) const { return (layout.width() * m_anchor_target) - (m_width * m_anchor_pos); }
+ float yoffset() const { return m_yoffset; }
+ float width() const { return m_width; }
+ float height() const { return m_height; }
+ size_t character_count() const { return m_characters.size(); }
+ const positioned_char &character(size_t index) const { return m_characters[index]; }
+ positioned_char &character(size_t index) { return m_characters[index]; }
+
+private:
+ std::vector<positioned_char> m_characters;
+ size_type m_center_justify_start = npos;
+ size_type m_right_justify_start = npos;
+ float m_yoffset;
+ float m_height;
+ float m_width = 0.0f;
+ float m_anchor_pos = 0.0f;
+ float m_anchor_target = 0.0f;
+};
+
+
+
+/***************************************************************************
CORE IMPLEMENTATION
***************************************************************************/
@@ -122,7 +310,7 @@ text_layout::~text_layout()
// add_text
//-------------------------------------------------
-void text_layout::add_text(std::string_view text, const char_style &style)
+void text_layout::add_text(std::string_view text, text_justify line_justify, char_style const &style)
{
while (!text.empty())
{
@@ -130,25 +318,9 @@ void text_layout::add_text(std::string_view text, const char_style &style)
invalidate_calculated_actual_width();
// do we need to create a new line?
- if (m_current_line == nullptr)
- {
- // get the current character
- char32_t schar;
- int const scharcount = uchar_from_utf8(&schar, text);
- if (scharcount < 0)
- break;
-
- // if the line starts with a tab character, center it regardless
- text_justify line_justify = justify();
- if (schar == '\t')
- {
- text.remove_prefix(scharcount);
- line_justify = text_layout::CENTER;
- }
-
- // start a new line
- start_new_line(line_justify, style.size);
- }
+ if (!m_current_line)
+ start_new_line(style.size);
+ m_current_line->set_justification(line_justify);
// get the current character
char32_t ch;
@@ -166,45 +338,43 @@ void text_layout::add_text(std::string_view text, const char_style &style)
// is this an endline?
if (ch == '\n')
{
- // first, start a line if we have not already
- if (m_current_line == nullptr)
- start_new_line(LEFT, style.size);
-
- // and then close up the current line
+ // close up the current line
+ m_current_line->align_text(*this);
m_current_line = nullptr;
}
else if (!m_truncating)
{
// if we hit a space, remember the location and width *without* the space
- if (is_space_character(ch))
+ bool const is_space = is_space_character(ch);
+ if (is_space)
m_last_break = m_current_line->character_count();
// append the character
- m_current_line->add_character(ch, style, source);
+ m_current_line->add_character(*this, ch, style, source);
// do we have to wrap?
- if (wrap() != NEVER && m_current_line->width() > m_width)
+ if ((wrap() != word_wrapping::NEVER) && (m_current_line->width() > m_width))
{
switch (wrap())
{
- case TRUNCATE:
- truncate_wrap();
- break;
+ case word_wrapping::TRUNCATE:
+ truncate_wrap();
+ break;
- case WORD:
- word_wrap();
- break;
+ case word_wrapping::WORD:
+ word_wrap(line_justify);
+ break;
- default:
- fatalerror("invalid word wrapping value");
- break;
+ case word_wrapping::NEVER:
+ // can't happen due to if condition, but compile warns about it
+ break;
}
}
else
{
- // we didn't wrap - if we hit any non-space breakable character, remember the location and width
- // *with* the breakable character
- if (ch != ' ' && is_breakable_char(ch))
+ // we didn't wrap - if we hit any non-space breakable character,
+ // remember the location and width *with* the breakable character
+ if (!is_space && is_breakable_char(ch))
m_last_break = m_current_line->character_count();
}
}
@@ -226,25 +396,26 @@ void text_layout::invalidate_calculated_actual_width()
// actual_left
//-------------------------------------------------
-float text_layout::actual_left() const
+float text_layout::actual_left()
{
+ if (m_current_line)
+ {
+ // TODO: is there a sane way to allow an open line to be temporarily finalised and rolled back?
+ m_current_line->align_text(*this);
+ m_current_line = nullptr;
+ }
+
float result;
if (empty())
{
// degenerate scenario
- result = 0;
+ result = 0.0f;
}
else
{
result = 1.0f;
for (const auto &line : m_lines)
- {
- result = std::min(result, line->xoffset());
-
- // take an opportunity to break out easily
- if (result <= 0)
- break;
- }
+ result = std::min(result, line->xoffset(*this));
}
return result;
}
@@ -254,8 +425,15 @@ float text_layout::actual_left() const
// actual_width
//-------------------------------------------------
-float text_layout::actual_width() const
+float text_layout::actual_width()
{
+ if (m_current_line)
+ {
+ // TODO: is there a sane way to allow an open line to be temporarily finalised and rolled back?
+ m_current_line->align_text(*this);
+ m_current_line = nullptr;
+ }
+
// do we need to calculate the width?
if (m_calculated_actual_width < 0)
{
@@ -275,14 +453,12 @@ float text_layout::actual_width() const
// actual_height
//-------------------------------------------------
-float text_layout::actual_height() const
+float text_layout::actual_height()
{
- line *last_line = (m_lines.size() > 0)
- ? m_lines[m_lines.size() - 1].get()
- : nullptr;
- return last_line
- ? last_line->yoffset() + last_line->height()
- : 0;
+ if (!m_lines.empty())
+ return m_lines.back()->yoffset() + m_lines.back()->height();
+ else
+ return 0.0f;
}
@@ -290,18 +466,12 @@ float text_layout::actual_height() const
// start_new_line
//-------------------------------------------------
-void text_layout::start_new_line(text_layout::text_justify justify, float height)
+void text_layout::start_new_line(float height)
{
- // create a new line
- std::unique_ptr<line> new_line(std::make_unique<line>(*this, justify, actual_height(), height * yscale()));
-
// update the current line
- m_current_line = new_line.get();
+ m_current_line = m_lines.emplace_back(std::make_unique<line>(actual_height(), height * yscale())).get();
m_last_break = 0;
m_truncating = false;
-
- // append it
- m_lines.emplace_back(std::move(new_line));
}
@@ -335,7 +505,7 @@ void text_layout::truncate_wrap()
source.start = truncate_char.source.start + truncate_char.source.span;
source.span = 0;
- // figure out how wide an elipsis is
+ // figure out how wide an ellipsis is
float elipsis_width = get_char_width(elipsis, style.size);
// where should we really truncate from?
@@ -345,10 +515,10 @@ void text_layout::truncate_wrap()
// truncate!!!
m_current_line->truncate(truncate_position);
- // and append the elipsis
- m_current_line->add_character(elipsis, style, source);
+ // and append the ellipsis
+ m_current_line->add_character(*this, elipsis, style, source);
- // take note that we are truncating; supress new characters
+ // take note that we are truncating; suppress new characters
m_truncating = true;
}
@@ -357,29 +527,31 @@ void text_layout::truncate_wrap()
// word_wrap
//-------------------------------------------------
-void text_layout::word_wrap()
+void text_layout::word_wrap(text_justify line_justify)
{
// keep track of the last line and break
- line *last_line = m_current_line;
- size_t last_break = m_last_break;
+ line *const last_line = m_current_line;
+ size_t const last_break = m_last_break ? m_last_break : (last_line->character_count() - 1);
// start a new line with the same justification
- start_new_line(last_line->justify(), last_line->character(last_line->character_count() - 1).style.size);
+ start_new_line(last_line->character(last_line->character_count() - 1).style.size);
+ m_current_line->set_justification(line_justify);
- // find the begining of the word to wrap
+ // find the beginning of the word to wrap
size_t position = last_break;
- while (position + 1 < last_line->character_count() && is_space_character(last_line->character(position).character))
+ while ((position + 1) < last_line->character_count() && is_space_character(last_line->character(position).character))
position++;
// transcribe the characters
for (size_t i = position; i < last_line->character_count(); i++)
{
auto &ch = last_line->character(i);
- m_current_line->add_character(ch.character, ch.style, ch.source);
+ m_current_line->add_character(*this, ch.character, ch.style, ch.source);
}
- // and finally, truncate the last line
+ // and finally, truncate the previous line and adjust spacing
last_line->truncate(last_break);
+ last_line->align_text(*this);
}
@@ -387,13 +559,20 @@ void text_layout::word_wrap()
// hit_test
//-------------------------------------------------
-bool text_layout::hit_test(float x, float y, size_t &start, size_t &span) const
+bool text_layout::hit_test(float x, float y, size_t &start, size_t &span)
{
+ if (m_current_line)
+ {
+ // TODO: is there a sane way to allow an open line to be temporarily finalised and rolled back?
+ m_current_line->align_text(*this);
+ m_current_line = nullptr;
+ }
+
for (const auto &line : m_lines)
{
if (y >= line->yoffset() && y < line->yoffset() + line->height())
{
- float line_xoffset = line->xoffset();
+ float line_xoffset = line->xoffset(*this);
if (x >= line_xoffset && x < line_xoffset + line->width())
{
for (size_t i = 0; i < line->character_count(); i++)
@@ -439,56 +618,39 @@ void text_layout::restyle(size_t start, size_t span, rgb_t *fgcolor, rgb_t *bgco
//-------------------------------------------------
-// get_wrap_info
+// emit
//-------------------------------------------------
-int text_layout::get_wrap_info(std::vector<int> &xstart, std::vector<int> &xend) const
+void text_layout::emit(render_container &container, float x, float y)
{
- // this is a hacky method (tailored to the need to implement
- // mame_ui_manager::wrap_text) but so be it
- int line_count = 0;
- for (const auto &line : m_lines)
- {
- int start_pos = 0;
- int end_pos = 0;
-
- auto line_character_count = line->character_count();
- if (line_character_count > 0)
- {
- start_pos = line->character(0).source.start;
- end_pos = line->character(line_character_count - 1).source.start
- + line->character(line_character_count - 1).source.span;
- }
-
- line_count++;
- xstart.push_back(start_pos);
- xend.push_back(end_pos);
- }
- return line_count;
+ emit(container, 0, m_lines.size(), x, y);
}
-
-//-------------------------------------------------
-// emit
-//-------------------------------------------------
-
-void text_layout::emit(render_container &container, float x, float y)
+void text_layout::emit(render_container &container, size_t start, size_t lines, float x, float y)
{
- for (const auto &line : m_lines)
+ if (m_current_line)
{
- float line_xoffset = line->xoffset();
+ // TODO: is there a sane way to allow an open line to be temporarily finalised and rolled back?
+ m_current_line->align_text(*this);
+ m_current_line = nullptr;
+ }
+
+ float const base_y = (m_lines.size() > start) ? m_lines[start]->yoffset() : 0.0f;
+ for (size_t l = start; ((start + lines) > l) && (m_lines.size() > l); ++l)
+ {
+ auto const &line = m_lines[l];
+ float const line_xoffset = line->xoffset(*this);
+ float const char_y = y + line->yoffset() - base_y;
+ float const char_height = line->height();
// emit every single character
for (auto i = 0; i < line->character_count(); i++)
{
auto &ch = line->character(i);
- // position this specific character correctly (TODO - this doesn't
- // handle differently sized text (yet)
- float char_x = x + line_xoffset + ch.xoffset;
- float char_y = y + line->yoffset();
- float char_width = ch.xwidth;
- float char_height = line->height();
+ // position this specific character correctly (TODO - this doesn't handle differently sized text (yet)
+ float const char_x = x + line_xoffset + ch.xoffset;
+ float const char_width = ch.xwidth;
// render the background of the character (if present)
if (ch.style.bgcolor.a() != 0)
@@ -496,95 +658,15 @@ void text_layout::emit(render_container &container, float x, float y)
// render the foreground
container.add_char(
- char_x,
- char_y,
- char_height,
- xscale() / yscale(),
- ch.style.fgcolor,
- font(),
- ch.character);
+ char_x,
+ char_y,
+ char_height,
+ xscale() / yscale(),
+ ch.style.fgcolor,
+ font(),
+ ch.character);
}
}
}
-
-//-------------------------------------------------
-// line::ctor
-//-------------------------------------------------
-
-text_layout::line::line(text_layout &layout, text_justify justify, float yoffset, float height)
- : m_layout(layout), m_justify(justify), m_yoffset(yoffset), m_width(0.0), m_height(height)
-{
-}
-
-
-//-------------------------------------------------
-// line::add_character
-//-------------------------------------------------
-
-void text_layout::line::add_character(char32_t ch, const char_style &style, const source_info &source)
-{
- // get the width of this character
- float chwidth = m_layout.get_char_width(ch, style.size);
-
- // create the positioned character
- positioned_char positioned_char = { 0, };
- positioned_char.character = ch;
- positioned_char.xoffset = m_width;
- positioned_char.xwidth = chwidth;
- positioned_char.style = style;
- positioned_char.source = source;
-
- // append the character
- m_characters.push_back(positioned_char);
- m_width += chwidth;
-
- // we might be bigger
- m_height = std::max(m_height, style.size * m_layout.yscale());
-}
-
-
-//-------------------------------------------------
-// line::xoffset
-//-------------------------------------------------
-
-float text_layout::line::xoffset() const
-{
- float result;
- switch (justify())
- {
- case LEFT:
- default:
- result = 0;
- break;
- case CENTER:
- result = (m_layout.width() - width()) / 2;
- break;
- case RIGHT:
- result = m_layout.width() - width();
- break;
- }
- return result;
-}
-
-
-//-------------------------------------------------
-// line::truncate
-//-------------------------------------------------
-
-void text_layout::line::truncate(size_t position)
-{
- assert(position <= m_characters.size());
-
- // are we actually truncating?
- if (position < m_characters.size())
- {
- // set the width as appropriate
- m_width = m_characters[position].xoffset;
-
- // and resize the array
- m_characters.resize(position);
- }
-}
-
} // namespace ui
diff --git a/src/frontend/mame/ui/text.h b/src/frontend/mame/ui/text.h
index 78f4905bbf4..e0d52b8a211 100644
--- a/src/frontend/mame/ui/text.h
+++ b/src/frontend/mame/ui/text.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
+// copyright-holders:Nathan Woods, Vas Crabb
/***************************************************************************
text.h
@@ -12,11 +12,15 @@
#pragma once
+#include <memory>
#include <string_view>
+#include <vector>
+
class render_font;
class render_container;
+
namespace ui {
/***************************************************************************
@@ -27,7 +31,7 @@ class text_layout
{
public:
// justification options for text
- enum text_justify
+ enum class text_justify
{
LEFT = 0,
CENTER,
@@ -35,7 +39,7 @@ public:
};
// word wrapping options
- enum word_wrapping
+ enum class word_wrapping
{
NEVER,
TRUNCATE,
@@ -56,24 +60,22 @@ public:
word_wrapping wrap() const { return m_wrap; }
// methods
- float actual_left() const;
- float actual_width() const;
- float actual_height() const;
- bool empty() const { return m_lines.size() == 0; }
- bool hit_test(float x, float y, size_t &start, size_t &span) const;
+ float actual_left();
+ float actual_width();
+ float actual_height();
+ bool empty() const { return m_lines.empty(); }
+ size_t lines() const { return m_lines.size(); }
+ bool hit_test(float x, float y, size_t &start, size_t &span);
void restyle(size_t start, size_t span, rgb_t *fgcolor, rgb_t *bgcolor);
- int get_wrap_info(std::vector<int> &xstart, std::vector<int> &xend) const;
void emit(render_container &container, float x, float y);
+ void emit(render_container &container, size_t start, size_t lines, float x, float y);
void add_text(std::string_view text, rgb_t fgcolor = rgb_t::white(), rgb_t bgcolor = rgb_t::transparent(), float size = 1.0)
{
- // create the style
- char_style style = { 0, };
- style.fgcolor = fgcolor;
- style.bgcolor = bgcolor;
- style.size = size;
-
- // and add the text
- add_text(text, style);
+ add_text(text, justify(), char_style{ fgcolor, bgcolor, size });
+ }
+ void add_text(std::string_view text, text_justify line_justify, rgb_t fgcolor = rgb_t::white(), rgb_t bgcolor = rgb_t::transparent(), float size = 1.0)
+ {
+ add_text(text, line_justify, char_style{ fgcolor, bgcolor, size });
}
private:
@@ -85,53 +87,10 @@ private:
float size;
};
- // information about the "source" of a character - also in a struct
- // to facilitate copying
- struct source_info
- {
- size_t start;
- size_t span;
- };
-
- // this should really be "positioned glyph" as glyphs != characters, but
- // we'll get there eventually
- struct positioned_char
- {
- char32_t character;
- char_style style;
- source_info source;
- float xoffset;
- float xwidth;
- };
-
// class to represent a line
- class line
- {
- public:
- line(text_layout &layout, text_justify justify, float yoffset, float height);
-
- // methods
- void add_character(char32_t ch, const char_style &style, const source_info &source);
- void truncate(size_t position);
-
- // accessors
- float xoffset() const;
- float yoffset() const { return m_yoffset; }
- float width() const { return m_width; }
- float height() const { return m_height; }
- text_justify justify() const { return m_justify; }
- size_t character_count() const { return m_characters.size(); }
- const positioned_char &character(size_t index) const { return m_characters[index]; }
- positioned_char &character(size_t index) { return m_characters[index]; }
-
- private:
- std::vector<positioned_char> m_characters;
- text_layout &m_layout;
- text_justify m_justify;
- float m_yoffset;
- float m_width;
- float m_height;
- };
+ struct source_info;
+ struct positioned_char;
+ class line;
// instance variables
render_font &m_font;
@@ -141,21 +100,21 @@ private:
mutable float m_calculated_actual_width;
text_justify m_justify;
word_wrapping m_wrap;
- std::vector<std::unique_ptr<line>> m_lines;
+ std::vector<std::unique_ptr<line> > m_lines;
line *m_current_line;
size_t m_last_break;
size_t m_text_position;
bool m_truncating;
// methods
- void add_text(std::string_view text, const char_style &style);
- void start_new_line(text_justify justify, float height);
+ void add_text(std::string_view text, text_justify line_justify, char_style const &style);
+ void start_new_line(float height);
float get_char_width(char32_t ch, float size);
void truncate_wrap();
- void word_wrap();
+ void word_wrap(text_justify line_justify);
void invalidate_calculated_actual_width();
};
} // namespace ui
-#endif // MAME_FRONTEND_UI_TEXT_H
+#endif // MAME_FRONTEND_UI_TEXT_H
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index c2f50d8c33a..fb3c437fb74 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -212,7 +212,7 @@ void mame_ui_manager::init()
ui_callback_type::GENERAL,
[this] (render_container &container) -> uint32_t
{
- draw_text_box(container, messagebox_text, ui::text_layout::LEFT, 0.5f, 0.5f, colors().background_color());
+ draw_text_box(container, messagebox_text, ui::text_layout::text_justify::LEFT, 0.5f, 0.5f, colors().background_color());
return 0;
});
m_non_char_keys_down = std::make_unique<uint8_t[]>((std::size(non_char_keys) + 7) / 8);
@@ -436,7 +436,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
[this, &poller, &warning_text, &warning_color, &config_menu] (render_container &container) -> uint32_t
{
// draw a standard message window
- draw_text_box(container, warning_text, ui::text_layout::LEFT, 0.5f, 0.5f, warning_color);
+ draw_text_box(container, warning_text, ui::text_layout::text_justify::LEFT, 0.5f, 0.5f, warning_color);
if (machine().ui_input().pressed(IPT_UI_CANCEL))
{
@@ -673,7 +673,7 @@ void mame_ui_manager::update_and_render(render_container &container)
// display any popup messages
if (osd_ticks() < m_popup_text_end)
- draw_text_box(container, messagebox_poptext, ui::text_layout::CENTER, 0.5f, 0.9f, colors().background_color());
+ draw_text_box(container, messagebox_poptext, ui::text_layout::text_justify::CENTER, 0.5f, 0.9f, colors().background_color());
else
m_popup_text_end = 0;
@@ -818,7 +818,12 @@ void mame_ui_manager::draw_outlined_box(render_container &container, float x0, f
void mame_ui_manager::draw_text(render_container &container, std::string_view buf, float x, float y)
{
- draw_text_full(container, buf, x, y, 1.0f - x, ui::text_layout::LEFT, ui::text_layout::WORD, mame_ui_manager::NORMAL, colors().text_color(), colors().text_bg_color(), nullptr, nullptr);
+ draw_text_full(
+ container,
+ buf,
+ x, y, 1.0f - x,
+ ui::text_layout::text_justify::LEFT, ui::text_layout::word_wrapping::WORD,
+ mame_ui_manager::NORMAL, colors().text_color(), colors().text_bg_color(), nullptr, nullptr);
}
@@ -884,8 +889,8 @@ void mame_ui_manager::draw_text_box(render_container &container, ui::text_layout
auto actual_left = layout.actual_left();
auto actual_width = layout.actual_width();
auto actual_height = layout.actual_height();
- auto x = std::min(std::max(xpos - actual_width / 2, box_lr_border()), 1.0f - actual_width - box_lr_border());
- auto y = std::min(std::max(ypos - actual_height / 2, box_tb_border()), 1.0f - actual_height - box_tb_border());
+ auto x = std::clamp(xpos - actual_width / 2, box_lr_border(), 1.0f - actual_width - box_lr_border());
+ auto y = std::clamp(ypos - actual_height / 2, box_tb_border(), 1.0f - actual_height - box_tb_border());
// add a box around that
draw_outlined_box(container,
@@ -1120,8 +1125,12 @@ bool mame_ui_manager::can_paste()
void mame_ui_manager::draw_fps_counter(render_container &container)
{
- draw_text_full(container, machine().video().speed_text(), 0.0f, 0.0f, 1.0f,
- ui::text_layout::RIGHT, ui::text_layout::WORD, OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr);
+ draw_text_full(
+ container,
+ machine().video().speed_text(),
+ 0.0f, 0.0f, 1.0f,
+ ui::text_layout::text_justify::RIGHT, ui::text_layout::word_wrapping::WORD,
+ OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr);
}
@@ -1132,8 +1141,12 @@ void mame_ui_manager::draw_fps_counter(render_container &container)
void mame_ui_manager::draw_timecode_counter(render_container &container)
{
std::string tempstring;
- draw_text_full(container, machine().video().timecode_text(tempstring), 0.0f, 0.0f, 1.0f,
- ui::text_layout::RIGHT, ui::text_layout::WORD, OPAQUE_, rgb_t(0xf0, 0xf0, 0x10, 0x10), rgb_t::black(), nullptr, nullptr);
+ draw_text_full(
+ container,
+ machine().video().timecode_text(tempstring),
+ 0.0f, 0.0f, 1.0f,
+ ui::text_layout::text_justify::RIGHT, ui::text_layout::word_wrapping::WORD,
+ OPAQUE_, rgb_t(0xf0, 0xf0, 0x10, 0x10), rgb_t::black(), nullptr, nullptr);
}
@@ -1144,8 +1157,12 @@ void mame_ui_manager::draw_timecode_counter(render_container &container)
void mame_ui_manager::draw_timecode_total(render_container &container)
{
std::string tempstring;
- draw_text_full(container, machine().video().timecode_total_text(tempstring), 0.0f, 0.0f, 1.0f,
- ui::text_layout::LEFT, ui::text_layout::WORD, OPAQUE_, rgb_t(0xf0, 0x10, 0xf0, 0x10), rgb_t::black(), nullptr, nullptr);
+ draw_text_full(
+ container,
+ machine().video().timecode_total_text(tempstring),
+ 0.0f, 0.0f, 1.0f,
+ ui::text_layout::text_justify::LEFT, ui::text_layout::word_wrapping::WORD,
+ OPAQUE_, rgb_t(0xf0, 0x10, 0xf0, 0x10), rgb_t::black(), nullptr, nullptr);
}
@@ -1156,7 +1173,12 @@ void mame_ui_manager::draw_timecode_total(render_container &container)
void mame_ui_manager::draw_profiler(render_container &container)
{
std::string_view text = g_profiler.text(machine());
- draw_text_full(container, text, 0.0f, 0.0f, 1.0f, ui::text_layout::LEFT, ui::text_layout::WORD, OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr);
+ draw_text_full(
+ container,
+ text,
+ 0.0f, 0.0f, 1.0f,
+ ui::text_layout::text_justify::LEFT, ui::text_layout::word_wrapping::WORD,
+ OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr);
}
@@ -1467,7 +1489,7 @@ uint32_t mame_ui_manager::handler_confirm_quit(render_container &container)
ui_select_text,
ui_cancel_text);
- draw_text_box(container, quit_message, ui::text_layout::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
+ draw_text_box(container, quit_message, ui::text_layout::text_justify::CENTER, 0.5f, 0.5f, UI_RED_COLOR);
machine().pause();
// if the user press ENTER, quit the game
@@ -2101,26 +2123,6 @@ ui::text_layout mame_ui_manager::create_layout(render_container &container, floa
//-------------------------------------------------
-// wrap_text
-//-------------------------------------------------
-
-int mame_ui_manager::wrap_text(render_container &container, std::string_view origs, float x, float y, float origwrapwidth, std::vector<int> &xstart, std::vector<int> &xend, float text_size)
-{
- // create the layout
- auto layout = create_layout(container, origwrapwidth, ui::text_layout::LEFT, ui::text_layout::WORD);
-
- // add the text
- layout.add_text(
- origs,
- rgb_t::black(),
- rgb_t::black(),
- text_size);
-
- // and get the wrapping info
- return layout.get_wrap_info(xstart, xend);
-}
-
-//-------------------------------------------------
// draw_textured_box - add primitives to
// draw an outlined box with the given
// textured background and line color
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index 4cd6292a764..a81278f3333 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -207,10 +207,7 @@ public:
// other
void process_natural_keyboard();
- ui::text_layout create_layout(render_container &container, float width = 1.0, ui::text_layout::text_justify justify = ui::text_layout::LEFT, ui::text_layout::word_wrapping wrap = ui::text_layout::WORD);
-
- // word wrap
- int wrap_text(render_container &container, std::string_view origs, float x, float y, float origwrapwidth, std::vector<int> &xstart, std::vector<int> &xend, float text_size = 1.0f);
+ ui::text_layout create_layout(render_container &container, float width = 1.0, ui::text_layout::text_justify justify = ui::text_layout::text_justify::LEFT, ui::text_layout::word_wrapping wrap = ui::text_layout::word_wrapping::WORD);
// draw an outlined box with given line color and filled with a texture
void draw_textured_box(render_container &container, float x0, float y0, float x1, float y1, rgb_t backcolor, rgb_t linecolor, render_texture *texture = nullptr, uint32_t flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
diff --git a/src/frontend/mame/ui/utils.cpp b/src/frontend/mame/ui/utils.cpp
index 95002ce6482..35aef723b13 100644
--- a/src/frontend/mame/ui/utils.cpp
+++ b/src/frontend/mame/ui/utils.cpp
@@ -396,7 +396,7 @@ private:
draw_text_box(
std::begin(text), std::end(text),
x, x2, y - top, y - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -1002,7 +1002,7 @@ private:
draw_text_box(
std::begin(text), std::end(text),
x, x2, y - top, y - ui().box_tb_border(),
- ui::text_layout::CENTER, ui::text_layout::NEVER, false,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
}
@@ -2044,7 +2044,7 @@ ui_software_info::ui_software_info(
{
// show the list/item here
infotext.append(longname);
- infotext.append("\t\n\n");
+ infotext.append(2, '\n');
infotext.append(_("swlist-info", "Software list/item"));
infotext.append(1, '\n');
infotext.append(listname);