summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ui/menu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/ui/menu.cpp')
-rw-r--r--src/emu/ui/menu.cpp85
1 files changed, 59 insertions, 26 deletions
diff --git a/src/emu/ui/menu.cpp b/src/emu/ui/menu.cpp
index 2af806fa586..1d8ae588c0f 100644
--- a/src/emu/ui/menu.cpp
+++ b/src/emu/ui/menu.cpp
@@ -296,7 +296,17 @@ void ui_menu::set_special_main_menu(bool special)
// end of the menu
//-------------------------------------------------
-void ui_menu::item_append(const char *text, const char *subtext, UINT32 flags, void *ref)
+void ui_menu::item_append(ui_menu_item item)
+{
+ item_append(item.text, item.subtext, item.flags, item.ref, item.type);
+}
+
+//-------------------------------------------------
+// item_append - append a new item to the
+// end of the menu
+//-------------------------------------------------
+
+void ui_menu::item_append(const char *text, const char *subtext, UINT32 flags, void *ref, ui_menu_item_type type)
{
// only allow multiline as the first item
if ((flags & MENU_FLAG_MULTILINE) != 0)
@@ -312,6 +322,7 @@ void ui_menu::item_append(const char *text, const char *subtext, UINT32 flags, v
pitem.subtext = (subtext != nullptr) ? pool_strdup(subtext) : nullptr;
pitem.flags = flags;
pitem.ref = ref;
+ pitem.type = type;
// append to array
int index = item.size();
@@ -380,6 +391,7 @@ const ui_menu_event *ui_menu::process(UINT32 flags)
if (menu_event.iptkey != IPT_INVALID && selected >= 0 && selected < item.size())
{
menu_event.itemref = item[selected].ref;
+ menu_event.type = item[selected].type;
return &menu_event;
}
return nullptr;
@@ -527,6 +539,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;
visible_lines = floor(visible_main_menu_height / line_height);
+ if (visible_lines > item.size()) visible_lines = item.size();
visible_main_menu_height = (float)visible_lines * line_height;
// compute top/left of inner menu area by centering
@@ -544,14 +557,26 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
if (!customonly)
machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
- // determine the first visible line based on the current selection
- if (selected > top_line + visible_lines || selected < top_line - visible_lines)
- top_line = selected - (visible_lines / 2);
if (top_line < 0 || selected == 0)
top_line = 0;
- if (top_line + visible_lines >= item.size())
+ if (top_line > item.size() - visible_lines || selected == (item.size() - 1))
top_line = item.size() - visible_lines;
+ bool show_top_arrow = false;
+ bool show_bottom_arrow = false;
+
+ // if scrolling, show arrows
+ if (item.size() > visible_lines)
+ {
+ if (top_line > 0)
+ show_top_arrow = true;
+ if (top_line != item.size() - visible_lines)
+ show_bottom_arrow = true;
+ }
+
+ // set the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
+ visitems = visible_lines - show_top_arrow - show_bottom_arrow;
+
// determine effective positions taking into account the hilighting arrows
float effective_width = visible_width - 2.0f * gutter_width;
float effective_left = visible_left + gutter_width;
@@ -573,6 +598,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
if (!customonly)
+ {
for (linenum = 0; linenum < visible_lines; linenum++)
{
float line_y = visible_top + (float)linenum * line_height;
@@ -613,7 +639,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
// if we're on the top line, display the up arrow
- if (linenum == 0 && top_line != 0)
+ if (linenum == 0 && show_top_arrow)
{
draw_arrow(container,
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
@@ -627,7 +653,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
// if we're on the bottom line, display the down arrow
- else if (linenum == visible_lines - 1 && itemnum != item.size() - 1)
+ else if (linenum == visible_lines - 1 && show_bottom_arrow)
{
draw_arrow(container,
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
@@ -646,8 +672,16 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// if we don't have a subitem, just draw the string centered
else if (pitem.subtext == nullptr)
+ {
+ if (pitem.flags & MENU_FLAG_UI_HEADING)
+ {
+ float heading_width = machine().ui().get_string_width(itemtext);
+ container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + ((visible_width - heading_width) / 2) - UI_BOX_LR_BORDER, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+ container->add_line(visible_left + visible_width - ((visible_width - heading_width) / 2) + UI_BOX_LR_BORDER, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+ }
machine().ui().draw_text_full(container, itemtext, effective_left, line_y, effective_width,
JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ }
// otherwise, draw the item on the left and the subitem text on the right
else
@@ -708,6 +742,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
}
}
+ }
// if the selected subitem is too big, display it in a separate offset box
if (selected_subitem_too_big)
@@ -741,9 +776,6 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// if there is something special to add, do it by calling the virtual method
custom_render((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != item.size());
}
void ui_menu::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2)
@@ -889,9 +921,10 @@ void ui_menu::handle_events(UINT32 flags)
top_line -= local_menu_event.num_lines;
return;
}
- selected -= local_menu_event.num_lines;
+ (selected == 0) ? selected = top_line = item.size() - 1 : selected -= local_menu_event.num_lines;
validate_selection(-1);
- if (selected < top_line + (top_line != 0))
+ top_line -= (selected <= top_line && top_line != 0);
+ if (selected <= top_line && visitems != visible_lines)
top_line -= local_menu_event.num_lines;
}
else
@@ -901,11 +934,10 @@ void ui_menu::handle_events(UINT32 flags)
top_line += local_menu_event.num_lines;
return;
}
- selected += local_menu_event.num_lines;
+ (selected == item.size() - 1) ? selected = top_line = 0 : selected += local_menu_event.num_lines;
validate_selection(1);
- if (selected > item.size() - 1)
- selected = item.size() - 1;
- if (selected >= top_line + visitems + (top_line != 0))
+ top_line += (selected >= top_line + visitems + (top_line != 0));
+ if (selected >= (top_line + visitems + (top_line != 0)))
top_line += local_menu_event.num_lines;
}
}
@@ -989,7 +1021,9 @@ void ui_menu::handle_keys(UINT32 flags)
}
(selected == 0) ? selected = top_line = item.size() - 1 : --selected;
validate_selection(-1);
- top_line -= (selected == top_line && top_line != 0);
+ top_line -= (selected <= top_line && top_line != 0);
+ if (selected <= top_line && visitems != visible_lines)
+ top_line--;
}
// down advances by one item
@@ -1001,7 +1035,10 @@ void ui_menu::handle_keys(UINT32 flags)
return;
}
(selected == item.size() - 1) ? selected = top_line = 0 : ++selected;
- top_line += (selected == top_line + visitems + (top_line != 0));
+ validate_selection(1);
+ top_line += (selected >= top_line + visitems + (top_line != 0));
+ if (selected >= (top_line + visitems + (top_line != 0)))
+ top_line++;
}
// page up backs up by visitems
@@ -1383,7 +1420,7 @@ void ui_menu::draw_select_game(bool noinput)
{
float line_height = machine().ui().get_line_height();
float ud_arrow_width = line_height * machine().render().ui_aspect();
- float gutter_width = 0.52f * line_height * machine().render().ui_aspect();
+ float gutter_width = 0.52f * ud_arrow_width;
mouse_x = -1, mouse_y = -1;
float right_panel_size = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL) ? 2.0f * UI_BOX_LR_BORDER : 0.3f;
float visible_width = 1.0f - 4.0f * UI_BOX_LR_BORDER;
@@ -1444,9 +1481,8 @@ void ui_menu::draw_select_game(bool noinput)
x1 = visible_left - UI_BOX_LR_BORDER;
x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
float line = visible_top + (float)(visible_lines * line_height);
-
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
+
if (visible_items < visible_lines)
visible_lines = visible_items;
if (top_line < 0 || selected == 0)
@@ -1543,7 +1579,7 @@ void ui_menu::draw_select_game(bool noinput)
else
draw_icon(linenum, item[itemnum].ref, effective_left, line_y);
- space = mui.get_line_height() * container->manager().ui_aspect() * 1.5f;
+ space = ud_arrow_width * 1.5f;
}
mui.draw_text_full(container, itemtext, effective_left + space, line_y, effective_width - space, JUSTIFY_LEFT, WRAP_TRUNCATE,
DRAW_NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor, nullptr, nullptr);
@@ -1701,10 +1737,8 @@ void ui_menu::handle_main_keys(UINT32 flags)
// hitting cancel also pops the stack
if (exclusive_input_pressed(IPT_UI_CANCEL, 0))
{
- if (!menu_has_search_active())
+ if (!ui_error && !menu_has_search_active())
ui_menu::stack_pop(machine());
- // else if (!ui_error)
- // ui_menu::stack_pop(machine()); TODO
return;
}
@@ -2763,7 +2797,6 @@ void ui_menu::draw_dats_menu()
float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER + extra_height;
float line = visible_top + (float)(visible_lines * line_height);
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
if (visible_items < visible_lines)