Merge duplicate code for drawing UI palette menu (nw)

This commit is contained in:
AJR 2017-09-15 17:43:32 -04:00
parent 8930407d7d
commit 9713353735
4 changed files with 34 additions and 213 deletions

View File

@ -946,196 +946,9 @@ void menu_palette_sel::handle()
void menu_palette_sel::populate(float &customtop, float &custombottom)
{
for (unsigned x = 0; x < ARRAY_LENGTH(s_palette); ++x)
item_append(_(s_palette[x].first), s_palette[x].second, 0, (void *)(uintptr_t)(x + 1));
item_append(_(s_palette[x].first), s_palette[x].second, FLAG_COLOR_BOX, (void *)(uintptr_t)(x + 1));
item_append(menu_item_type::SEPARATOR);
}
//-------------------------------------------------
// perform our special rendering
//-------------------------------------------------
void menu_palette_sel::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
{
}
//-------------------------------------------------
// draw - draw palette menu
//-------------------------------------------------
void menu_palette_sel::draw(uint32_t flags)
{
auto line_height = ui().get_line_height();
auto lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
auto ud_arrow_width = line_height * machine().render().ui_aspect();
float const gutter_width = lr_arrow_width * 1.3f;
if (&machine().system() == &GAME_NAME(___empty))
draw_background();
// compute the width and height of the full menu
float visible_width = 0.0f;
float visible_main_menu_height = 0.0f;
for (auto &pitem : item)
{
// compute width of left hand side
float total_width = gutter_width + ui().get_string_width(pitem.text.c_str()) + gutter_width;
// add in width of right hand side
if (!pitem.subtext.empty())
total_width += 2.0f * gutter_width + ui().get_string_width(pitem.subtext.c_str());
// track the maximum
if (total_width > visible_width)
visible_width = total_width;
// track the height as well
visible_main_menu_height += line_height;
}
// account for extra space at the top and bottom
float const visible_extra_menu_height = get_customtop() + get_custombottom();
// add a little bit of slop for rounding
visible_width += 0.01f;
visible_main_menu_height += 0.01f;
// if we are too wide or too tall, clamp it down
if (visible_width + 2.0f * UI_BOX_LR_BORDER > 1.0f)
visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;
// if the menu and extra menu won't fit, take away part of the regular menu, it will scroll
if (visible_main_menu_height + visible_extra_menu_height + 2.0f * UI_BOX_TB_BORDER > 1.0f)
visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;
int visible_lines = floor(visible_main_menu_height / line_height);
visible_main_menu_height = (float)visible_lines * line_height;
// compute top/left of inner menu area by centering
float visible_left = (1.0f - visible_width) * 0.5f;
float visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
// if the menu is at the bottom of the extra, adjust
visible_top += get_customtop();
// first add us a box
float const x1 = visible_left - UI_BOX_LR_BORDER;
float const y1 = visible_top - UI_BOX_TB_BORDER;
float const x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
float const y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER;
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
// determine the first visible line based on the current selection
int top_line = selected_index() - visible_lines / 2;
if (top_line < 0)
top_line = 0;
if (top_line + visible_lines >= item.size())
top_line = item.size() - visible_lines;
// 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;
// locate mouse
map_mouse();
// loop over visible lines
hover = item.size() + 1;
float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
for (int linenum = 0; linenum < visible_lines; linenum++)
{
float const line_y = visible_top + float(linenum) * line_height;
int const itemnum = top_line + linenum;
menu_item const &pitem = item[itemnum];
char const *const itemtext = pitem.text.c_str();
float const line_y0 = line_y;
float const line_y1 = line_y + line_height;
// set the hover if this is our item
if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
hover = itemnum;
rgb_t fgcolor = UI_TEXT_COLOR;
rgb_t bgcolor = UI_TEXT_BG_COLOR;
if (is_selected(itemnum))
{
// if we're selected, draw with a different background
fgcolor = UI_SELECTED_COLOR;
bgcolor = UI_SELECTED_BG_COLOR;
}
else if (itemnum == hover)
{
// else if the mouse is over this item, draw with a different background
fgcolor = UI_MOUSEOVER_COLOR;
bgcolor = UI_MOUSEOVER_BG_COLOR;
}
// if we have some background hilighting to do, add a quad behind everything else
if (bgcolor != UI_TEXT_BG_COLOR)
highlight(line_x0, line_y0, line_x1, line_y1, bgcolor);
if (linenum == 0 && top_line != 0)
{
// if we're on the top line, display the up arrow
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);
if (hover == itemnum)
hover = HOVER_ARROW_UP;
}
else if (linenum == visible_lines - 1 && itemnum != item.size() - 1)
{
// if we're on the bottom line, display the down arrow
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);
if (hover == itemnum)
hover = HOVER_ARROW_DOWN;
}
else if (pitem.type == menu_item_type::SEPARATOR)
{
// if we're just a divider, draw a line
container().add_line(visible_left, 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));
}
else if (pitem.subtext.empty())
{
// if we don't have a subitem, just draw the string centered
ui().draw_text_full(container(), itemtext, effective_left, line_y, effective_width,
ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
}
else
{
// otherwise, draw the item on the left and the subitem text on the right
const char *subitem_text = pitem.subtext.c_str();
rgb_t color = rgb_t((uint32_t)strtoul(subitem_text, nullptr, 16));
// draw the left-side text
ui().draw_text_full(container(), itemtext, effective_left, line_y, effective_width,
ui::text_layout::LEFT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
// give 2 spaces worth of padding
float subitem_width = ui().get_string_width("FF00FF00");
ui().draw_outlined_box(container(), effective_left + effective_width - subitem_width, line_y0,
effective_left + effective_width, line_y1, color);
}
}
// 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 = visible_lines - (top_line != 0) - (top_line + visible_lines != item.size());
}
} // namespace ui

View File

@ -178,13 +178,7 @@ public:
menu_palette_sel(mame_ui_manager &mui, render_container &container, rgb_t &_color);
virtual ~menu_palette_sel() override;
protected:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
// draw palette menu
virtual void draw(uint32_t flags) override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;

View File

@ -709,30 +709,43 @@ void menu::draw(uint32_t flags)
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);
// give 2 spaces worth of padding
item_width += 2.0f * gutter_width;
// if the subitem doesn't fit here, display dots
if (ui().get_string_width(subitem_text) > effective_width - item_width)
if (pitem.flags & FLAG_COLOR_BOX)
{
subitem_text = "...";
if (is_selected(itemnum))
selected_subitem_too_big = true;
rgb_t color = rgb_t((uint32_t)strtoul(subitem_text, nullptr, 16));
// give 2 spaces worth of padding
subitem_width = ui().get_string_width("FF00FF00");
ui().draw_outlined_box(container(), effective_left + effective_width - subitem_width, line_y0,
effective_left + effective_width, line_y1, color);
}
else
{
// give 2 spaces worth of padding
item_width += 2.0f * gutter_width;
// customize subitem text color
if (!core_stricmp(subitem_text, _("On")))
fgcolor2 = rgb_t(0x00,0xff,0x00);
// if the subitem doesn't fit here, display dots
if (ui().get_string_width(subitem_text) > effective_width - item_width)
{
subitem_text = "...";
if (is_selected(itemnum))
selected_subitem_too_big = true;
}
if (!core_stricmp(subitem_text, _("Off")))
fgcolor2 = rgb_t(0xff,0x00,0x00);
// customize subitem text color
if (!core_stricmp(subitem_text, _("On")))
fgcolor2 = rgb_t(0x00,0xff,0x00);
if (!core_stricmp(subitem_text, _("Auto")))
fgcolor2 = rgb_t(0xff,0xff,0x00);
if (!core_stricmp(subitem_text, _("Off")))
fgcolor2 = rgb_t(0xff,0x00,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);
if (!core_stricmp(subitem_text, _("Auto")))
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);
}
// apply arrows
if (is_selected(itemnum) && (pitem.flags & FLAG_LEFT_ARROW))

View File

@ -45,7 +45,8 @@ public:
FLAG_DISABLE = (1 << 5),
FLAG_UI_DATS = (1 << 6),
FLAG_UI_FAVORITE = (1 << 7),
FLAG_UI_HEADING = (1 << 8)
FLAG_UI_HEADING = (1 << 8),
FLAG_COLOR_BOX = (1 << 9)
};
virtual ~menu();