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.
This commit is contained in:
Vas Crabb 2021-10-17 06:58:12 +11:00
parent aa3ae2cf17
commit 22f52553f7
31 changed files with 972 additions and 813 deletions

View File

@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: MAME\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-16 04:41+1100\n"
"PO-Revision-Date: 2021-10-14 21:22+0800\n"
"PO-Revision-Date: 2021-10-16 12:57+0800\n"
"Last-Translator: YuiFAN\n"
"Language-Team: MAME Language Team\n"
"Language: zh_CN\n"
@ -1519,7 +1519,7 @@ msgstr "可见度延迟"
#: src/frontend/mame/ui/miscmenu.cpp:639
#, c-format
msgid "%s.xml saved in UI settings folder."
msgstr ""
msgstr "%s.xml 已保存于 UI 设定文件夹"
#: src/frontend/mame/ui/miscmenu.cpp:665
msgid "Name: Description:\n"
@ -1528,7 +1528,7 @@ msgstr "名称: 描述:\n"
#: src/frontend/mame/ui/miscmenu.cpp:676
#, c-format
msgid "%s.txt saved in UI settings folder."
msgstr ""
msgstr "%s.txt 已保存于 UI 设定文件夹"
#: src/frontend/mame/ui/miscmenu.cpp:693
msgid "Export list in XML format (like -listxml)"
@ -2126,6 +2126,10 @@ msgid ""
"Press %1$s to cancel\n"
"Press %2$s to continue"
msgstr ""
"取消校验?\n"
"\n"
"按下 %1$s 取消\n"
"按下 %2$s 继续"
#: src/frontend/mame/ui/auditmenu.cpp:135
#, c-format
@ -2300,7 +2304,7 @@ msgstr "鼠标按下背景颜色"
#: src/frontend/mame/ui/custui.cpp:600
msgid "Restore default colors"
msgstr ""
msgstr "还原至缺省颜色"
#: src/frontend/mame/ui/custui.cpp:612
msgid "UI Color Settings"
@ -2309,7 +2313,7 @@ msgstr "UI 色彩设定"
#: src/frontend/mame/ui/custui.cpp:621
#, c-format
msgid "Double-click or press %1$s to change color"
msgstr ""
msgstr "双击或按下 %1$s 改变颜色"
#: src/frontend/mame/ui/custui.cpp:629
msgid "Menu Preview"
@ -3615,12 +3619,12 @@ msgstr "半押"
#: src/emu/inpttype.ipp:119
msgctxt "input-name"
msgid "High"
msgstr ""
msgstr ""
#: src/emu/inpttype.ipp:120
msgctxt "input-name"
msgid "Low"
msgstr ""
msgstr ""
#: src/emu/inpttype.ipp:125
msgctxt "input-name"
@ -5225,42 +5229,42 @@ msgstr "P10 选择"
#: src/emu/inpttype.ipp:497
msgctxt "input-name"
msgid "1 Player Start"
msgstr "1 位玩家开始"
msgstr "玩家 1 开始"
#: src/emu/inpttype.ipp:498
msgctxt "input-name"
msgid "2 Players Start"
msgstr "2 位玩家开始"
msgstr "玩家 2 开始"
#: src/emu/inpttype.ipp:499
msgctxt "input-name"
msgid "3 Players Start"
msgstr "3 位玩家开始"
msgstr "玩家 3 开始"
#: src/emu/inpttype.ipp:500
msgctxt "input-name"
msgid "4 Players Start"
msgstr "4 位玩家开始"
msgstr "玩家 4 开始"
#: src/emu/inpttype.ipp:501
msgctxt "input-name"
msgid "5 Players Start"
msgstr "5 位玩家开始"
msgstr "玩家 5 开始"
#: src/emu/inpttype.ipp:502
msgctxt "input-name"
msgid "6 Players Start"
msgstr "6 位玩家开始"
msgstr "玩家 6 开始"
#: src/emu/inpttype.ipp:503
msgctxt "input-name"
msgid "7 Players Start"
msgstr "7 位玩家开始"
msgstr "玩家 7 开始"
#: src/emu/inpttype.ipp:504
msgctxt "input-name"
msgid "8 Players Start"
msgstr "8 位玩家开始"
msgstr "玩家 8 开始"
#: src/emu/inpttype.ipp:509
msgctxt "input-name"
@ -5325,7 +5329,7 @@ msgstr "投币孔 12"
#: src/emu/inpttype.ipp:521
msgctxt "input-name"
msgid "Bill 1"
msgstr ""
msgstr "投钞孔 1"
#: src/emu/inpttype.ipp:526
msgctxt "input-name"
@ -6305,7 +6309,7 @@ msgstr "鼠标 Y 10"
#: src/emu/inpttype.ipp:806
msgctxt "input-name"
msgid "Keypad"
msgstr ""
msgstr "小键盘"
#: src/emu/inpttype.ipp:807
msgctxt "input-name"
@ -6350,7 +6354,7 @@ msgstr "重新启动机台"
#: src/emu/inpttype.ipp:819
msgctxt "input-name"
msgid "Soft Reset"
msgstr ""
msgstr "软体重新启动"
#: src/emu/inpttype.ipp:820
msgctxt "input-name"
@ -6520,7 +6524,7 @@ msgstr "菜单 切换"
#: src/emu/inpttype.ipp:853
msgctxt "input-name"
msgid "UI Release Pointer"
msgstr ""
msgstr "菜单 解除指标锁定"
#: src/emu/inpttype.ipp:854
msgctxt "input-name"
@ -6560,7 +6564,7 @@ msgstr "菜单 新增/移除最爱项目"
#: src/emu/inpttype.ipp:861
msgctxt "input-name"
msgid "UI Export List"
msgstr "菜单"
msgstr "菜单 汇出列表"
#: src/emu/inpttype.ipp:862
msgctxt "input-name"
@ -7046,18 +7050,3 @@ msgstr "MESSinfo"
#: plugins/data/data_mameinfo.lua:20
msgid "MAMEinfo"
msgstr "MAMEinfo"
#, c-format
#~ msgid "%s.xml saved under ui folder."
#~ msgstr "%s.xml 已保存于 ui 文件夹。"
#, c-format
#~ msgid "%s.txt saved under ui folder."
#~ msgstr "%s.txt 已保存于 ui 资料夹下。"
#, c-format
#~ msgid "Double-click or press %1$s to change the color value"
#~ msgstr "双击或按下 %1$s 以改变颜色值"
#~ msgid "Restore originals colors"
#~ msgstr "还原至原本颜色"

View File

@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: MAME\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-16 04:41+1100\n"
"PO-Revision-Date: 2021-10-14 21:20+0800\n"
"PO-Revision-Date: 2021-10-16 12:55+0800\n"
"Last-Translator: YuiFAN\n"
"Language-Team: MAME Language Team\n"
"Language: zh_TW\n"
@ -300,7 +300,7 @@ msgstr "搜尋: %1$s_"
#: src/frontend/mame/ui/selsoft.cpp:723
#, c-format
msgid "Software list/item: %1$s:%2$s"
msgstr ""
msgstr "軟體列表/項目: %1$s:%2$s"
#: src/frontend/mame/ui/optsmenu.cpp:73 src/frontend/mame/ui/sndmenu.cpp:163
msgid "Sound Options"
@ -1519,7 +1519,7 @@ msgstr "可見度延遲"
#: src/frontend/mame/ui/miscmenu.cpp:639
#, c-format
msgid "%s.xml saved in UI settings folder."
msgstr ""
msgstr "%s.xml 已儲存於 UI 設定資料夾"
#: src/frontend/mame/ui/miscmenu.cpp:665
msgid "Name: Description:\n"
@ -1528,7 +1528,7 @@ msgstr "名稱: 描述:\n"
#: src/frontend/mame/ui/miscmenu.cpp:676
#, c-format
msgid "%s.txt saved in UI settings folder."
msgstr ""
msgstr "%s.txt 已儲存於 UI 設定資料夾"
#: src/frontend/mame/ui/miscmenu.cpp:693
msgid "Export list in XML format (like -listxml)"
@ -2126,6 +2126,10 @@ msgid ""
"Press %1$s to cancel\n"
"Press %2$s to continue"
msgstr ""
"取消驗證?\n"
"\n"
"按下 %1$s 取消\n"
"按下 %2$s 繼續"
#: src/frontend/mame/ui/auditmenu.cpp:135
#, c-format
@ -2300,7 +2304,7 @@ msgstr "滑鼠按下背景顏色"
#: src/frontend/mame/ui/custui.cpp:600
msgid "Restore default colors"
msgstr ""
msgstr "還原至預設顏色"
#: src/frontend/mame/ui/custui.cpp:612
msgid "UI Color Settings"
@ -2309,7 +2313,7 @@ msgstr "UI 色彩設定"
#: src/frontend/mame/ui/custui.cpp:621
#, c-format
msgid "Double-click or press %1$s to change color"
msgstr ""
msgstr "雙擊或按下 %1$s 改變顏色"
#: src/frontend/mame/ui/custui.cpp:629
msgid "Menu Preview"
@ -3615,12 +3619,12 @@ msgstr "半押"
#: src/emu/inpttype.ipp:119
msgctxt "input-name"
msgid "High"
msgstr ""
msgstr ""
#: src/emu/inpttype.ipp:120
msgctxt "input-name"
msgid "Low"
msgstr ""
msgstr ""
#: src/emu/inpttype.ipp:125
msgctxt "input-name"
@ -5225,42 +5229,42 @@ msgstr "P10 選擇"
#: src/emu/inpttype.ipp:497
msgctxt "input-name"
msgid "1 Player Start"
msgstr "1 位玩家開始"
msgstr "玩家 1 開始"
#: src/emu/inpttype.ipp:498
msgctxt "input-name"
msgid "2 Players Start"
msgstr "2 位玩家開始"
msgstr "玩家 2 開始"
#: src/emu/inpttype.ipp:499
msgctxt "input-name"
msgid "3 Players Start"
msgstr "3 位玩家開始"
msgstr "玩家 3 開始"
#: src/emu/inpttype.ipp:500
msgctxt "input-name"
msgid "4 Players Start"
msgstr "4 位玩家開始"
msgstr "玩家 4 開始"
#: src/emu/inpttype.ipp:501
msgctxt "input-name"
msgid "5 Players Start"
msgstr "5 位玩家開始"
msgstr "玩家 5 開始"
#: src/emu/inpttype.ipp:502
msgctxt "input-name"
msgid "6 Players Start"
msgstr "6 位玩家開始"
msgstr "玩家 6 開始"
#: src/emu/inpttype.ipp:503
msgctxt "input-name"
msgid "7 Players Start"
msgstr "7 位玩家開始"
msgstr "玩家 7 開始"
#: src/emu/inpttype.ipp:504
msgctxt "input-name"
msgid "8 Players Start"
msgstr "8 位玩家開始"
msgstr "玩家 8 開始"
#: src/emu/inpttype.ipp:509
msgctxt "input-name"
@ -5325,7 +5329,7 @@ msgstr "投幣孔 12"
#: src/emu/inpttype.ipp:521
msgctxt "input-name"
msgid "Bill 1"
msgstr ""
msgstr "吸鈔口 1"
#: src/emu/inpttype.ipp:526
msgctxt "input-name"
@ -6305,7 +6309,7 @@ msgstr "滑鼠 Y 10"
#: src/emu/inpttype.ipp:806
msgctxt "input-name"
msgid "Keypad"
msgstr ""
msgstr "小鍵盤"
#: src/emu/inpttype.ipp:807
msgctxt "input-name"
@ -6350,7 +6354,7 @@ msgstr "重新啟動機台"
#: src/emu/inpttype.ipp:819
msgctxt "input-name"
msgid "Soft Reset"
msgstr ""
msgstr "軟體重新啟動"
#: src/emu/inpttype.ipp:820
msgctxt "input-name"
@ -6520,7 +6524,7 @@ msgstr "選單 切換"
#: src/emu/inpttype.ipp:853
msgctxt "input-name"
msgid "UI Release Pointer"
msgstr ""
msgstr "選單 釋放指標"
#: src/emu/inpttype.ipp:854
msgctxt "input-name"
@ -6560,7 +6564,7 @@ msgstr "選單 新增/移除最愛項目"
#: src/emu/inpttype.ipp:861
msgctxt "input-name"
msgid "UI Export List"
msgstr "選單"
msgstr "選單 匯出清單"
#: src/emu/inpttype.ipp:862
msgctxt "input-name"
@ -7046,18 +7050,3 @@ msgstr "MESSinfo"
#: plugins/data/data_mameinfo.lua:20
msgid "MAMEinfo"
msgstr "MAMEinfo"
#, c-format
#~ msgid "%s.xml saved under ui folder."
#~ msgstr "%s.xml 已儲存於 ui 資料夾下。"
#, c-format
#~ msgid "%s.txt saved under ui folder."
#~ msgstr "%s.txt 已儲存於 ui 資料夾下。"
#, c-format
#~ msgid "Double-click or press %1$s to change the color value"
#~ msgstr "雙擊或按下 %1$s 以改變顏色值"
#~ msgid "Restore originals colors"
#~ msgstr "還原至原本顏色"

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);
@ -105,25 +107,110 @@ menu_dats_view::~menu_dats_view()
{
}
//-------------------------------------------------
// add text to layout
//-------------------------------------------------
void menu_dats_view::add_info_text(text_layout &layout, std::string_view text, rgb_t color, float size)
{
char justify = 'l'; // left justify by default
if ((text.length() > 3) && (text[0] == '#') && (text[1] == 'j'))
{
auto const eol = text.find('\n');
if ((std::string_view::npos != eol) && (2 < eol))
{
justify = text[2];
text.remove_prefix(eol + 1);
}
}
if ('2' == justify)
{
while (!text.empty())
{
// 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()
{
const event *menu_event = process(FLAG_UI_DATS);
if (menu_event != nullptr)
event const *const menu_event = process(PROCESS_LR_ALWAYS | PROCESS_CUSTOM_NAV);
if (menu_event)
{
if (menu_event->iptkey == IPT_UI_LEFT && m_actual > 0)
switch (menu_event->iptkey)
{
m_actual--;
reset(reset_options::SELECT_FIRST);
}
case IPT_UI_LEFT:
if (m_actual > 0)
{
m_actual--;
reset(reset_options::SELECT_FIRST);
}
break;
if (menu_event->iptkey == IPT_UI_RIGHT && m_actual < m_items_list.size() - 1)
{
m_actual++;
reset(reset_options::SELECT_FIRST);
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 (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
{
// 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())
{
// 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)
// 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))
{
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));
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);
}
else
{
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);
}
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

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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)
{
top_line -= m_visible_items - (last_item_visible() ? 1 : 0);
return;
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);
}
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)
{
top_line += m_visible_lines - 2;
return;
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;
}
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))

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
{

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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);
}
}

View File

@ -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 {
@ -75,6 +78,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++)
@ -438,57 +617,40 @@ void text_layout::restyle(size_t start, size_t span, rgb_t *fgcolor, rgb_t *bgco
}
//-------------------------------------------------
// get_wrap_info
//-------------------------------------------------
int text_layout::get_wrap_info(std::vector<int> &xstart, std::vector<int> &xend) const
{
// 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
//-------------------------------------------------
void text_layout::emit(render_container &container, float x, float y)
{
for (const auto &line : m_lines)
emit(container, 0, m_lines.size(), x, y);
}
void text_layout::emit(render_container &container, size_t start, size_t lines, float x, float y)
{
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

View File

@ -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

View File

@ -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
@ -2100,26 +2122,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

View File

@ -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));

View File

@ -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);