Tweaked formula used to determine best number of rows in dynamic ribbon. It now looks fine in all resolutions I tested. Hopefully the now rather complicated formula doesn't have unforseen issues...

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6086 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2010-09-20 17:31:59 +00:00
parent 1c4e3f8492
commit a17b78d5fc

View File

@ -66,19 +66,26 @@ DynamicRibbonWidget::~DynamicRibbonWidget()
/** Function that estimates the area (in squared pixels) that ribbon icons
* would take given a number of rows (used to estimate the best number of
* rows)
* \param[out] visibleItems number of items that can be displayed in this
* configuration
* \param[out] takenArea how many square pixels are taken by the icons
* \param[out] itemHeight how high each item would be in this configuration
*/
int estimateIconAreaFor(const int rowCount, const int wantedIconWidth,
const int width, const int height,
const float iconAspectRatio)
void estimateIconAreaFor(const int rowCount, const int wantedIconWidth,
const int width, const int height,
const float iconAspectRatio,
int* visibleItems, int* takenArea, int* itemHeight)
{
const int row_height = height / rowCount;
float icon_height = (float)row_height;
float icon_width = row_height * iconAspectRatio;
*itemHeight = int(icon_height);
const int icons_per_row = std::min(int(width / icon_width), int(width / wantedIconWidth));
return int(icons_per_row * rowCount * icon_width * icon_height);
*visibleItems = icons_per_row * rowCount ;
*takenArea = int(*visibleItems * icon_width * icon_height);
}
void DynamicRibbonWidget::add()
@ -177,17 +184,36 @@ void DynamicRibbonWidget::add()
const float aspect_ratio = (float)m_child_width / (float)m_child_height;
// const int count = m_items.size();
int max_area_so_far = -1;
int max_score_so_far = -1;
m_row_amount = -1;
for (int row_count = 1; row_count < 10; row_count++)
{
const int area = estimateIconAreaFor(row_count, m_child_width,
m_w, m_h - m_label_height, aspect_ratio);
if (area > max_area_so_far)
int visible_items;
int taken_area;
int item_height;
estimateIconAreaFor(row_count, m_child_width, m_w, m_h - m_label_height,
aspect_ratio, &visible_items, &taken_area, &item_height);
// FIXME: this system to determine the best number of columns is really complicated!
// the score is computed from taken screen area AND visible item count.
// A number of rows that allows for the screen space to be used a lot will
// get a better score. A number of rows that allows showing very few items
// will be penalized. A configuration that makes items much smaller than
// requested in the XML file will also be penalized.
const int score = int(log(2*visible_items) *
std::min((float)item_height / (float)m_child_height, 1.0f) *
taken_area);
//std::cout << " " << row_count << " rows : " << visible_items << " visible items; area = "
// << taken_area << "; size penalty = " << std::min((float)item_height / (float)m_child_height, 1.0f)
// << "; score = " << score << "\n";
if (score > max_score_so_far)
{
m_row_amount = row_count;
max_area_so_far = area;
max_score_so_far = score;
}
}
assert(m_row_amount != -1);