Screen preferences: use a matrix menu for the resolution list

When there are a lot of display resolutions available, the menu can
become very high. Switch to a "matrix" menu with 3 columns in this case
to keep it a reasonable size.

Change-Id: I826be06a91bd1bcae600cc333e34d4a9dd7b3df5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5320
Reviewed-by: nephele nephele <[email protected]>
Reviewed-by: John Scipione <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
PulkoMandy
2023-07-31 07:02:23 +00:00
committed by Adrien Destugues
parent 24a34a5ee5
commit 4c28b3f19f
+54 -7
View File
@@ -307,13 +307,53 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings)
B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
controlsBox->AddChild(outerControlsView);
fResolutionMenu = new BPopUpMenu("resolution", true, true);
menu_layout layout = B_ITEMS_IN_COLUMN;
// There are modes in the list with the same resolution but different bpp or refresh rates.
// We don't want to take these into account when computing the menu layout, so we need to
// count how many entries we will really have in the menu.
int fullModeCount = fScreenMode.CountModes();
int modeCount = 0;
int index = 0;
uint16 maxWidth = 0;
uint16 maxHeight = 0;
uint16 previousWidth = 0;
uint16 previousHeight = 0;
for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
for (int32 i = 0; i < fullModeCount; i++) {
screen_mode mode = fScreenMode.ModeAt(i);
if (mode.width == previousWidth && mode.height == previousHeight)
continue;
modeCount++;
previousWidth = mode.width;
previousHeight = mode.height;
if (maxWidth < mode.width)
maxWidth = mode.width;
if (maxHeight < mode.height)
maxHeight = mode.height;
}
if (modeCount > 16)
layout = B_ITEMS_IN_MATRIX;
fResolutionMenu = new BPopUpMenu("resolution", true, true, layout);
// Compute the size we should allocate to each item in the menu
BRect itemRect;
if (layout == B_ITEMS_IN_MATRIX) {
BFont menuFont;
font_height fontHeight;
fResolutionMenu->GetFont(&menuFont);
menuFont.GetHeight(&fontHeight);
itemRect.left = itemRect.top = 0;
itemRect.bottom = fontHeight.ascent + fontHeight.descent + 4;
itemRect.right = menuFont.StringWidth("99999x99999") + 16;
rows = modeCount / 3 + 1;
}
index = 0;
for (int32 i = 0; i < fullModeCount; i++) {
screen_mode mode = fScreenMode.ModeAt(i);
if (mode.width == previousWidth && mode.height == previousHeight)
@@ -321,10 +361,6 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings)
previousWidth = mode.width;
previousHeight = mode.height;
if (maxWidth < mode.width)
maxWidth = mode.width;
if (maxHeight < mode.height)
maxHeight = mode.height;
BMessage* message = new BMessage(POP_RESOLUTION_MSG);
message->AddInt32("width", mode.width);
@@ -333,7 +369,18 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings)
BString name;
name << mode.width << " x " << mode.height;
fResolutionMenu->AddItem(new BMenuItem(name.String(), message));
if (layout == B_ITEMS_IN_COLUMN)
fResolutionMenu->AddItem(new BMenuItem(name.String(), message));
else {
int y = index % rows;
int x = index / rows;
itemRect.OffsetTo(x * itemRect.Width(), y * itemRect.Height());
printf("i %d x %d y %d\n", index, x, y);
itemRect.PrintToStream();
fResolutionMenu->AddItem(new BMenuItem(name.String(), message), itemRect);
}
index++;
}
fMonitorView->SetMaxResolution(maxWidth, maxHeight);