From 1fc4cb1f275d1c970745decfec43e1e532716834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 7 Aug 2009 10:22:22 +0000 Subject: [PATCH] * If the user selected color space is not available for the selected resolution, _CheckColorMenu() now selects the closest item available - if you switch back the resolution to one that supports the original color space, it will be restored. This fixes bug #2995. * I also reverted r24674 as I remembered why I did that in the first place (advertizing 24 bit modes as 32 bit), and it was a pretty stupid idea to solve it like this, I must admit. * Instead, the color space menu now only shows spaces that are actually supported by the card at all. One could think about hiding 24 bit in case both 24 bit, and 32 bit are available, but I didn't do that yet. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32179 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/preferences/screen/ScreenMode.cpp | 11 +- src/preferences/screen/ScreenWindow.cpp | 146 +++++++++++++++++++----- src/preferences/screen/ScreenWindow.h | 125 ++++++++++---------- 3 files changed, 186 insertions(+), 96 deletions(-) diff --git a/src/preferences/screen/ScreenMode.cpp b/src/preferences/screen/ScreenMode.cpp index 72a94b815c..848f6b6527 100644 --- a/src/preferences/screen/ScreenMode.cpp +++ b/src/preferences/screen/ScreenMode.cpp @@ -121,17 +121,8 @@ screen_mode::operator==(const screen_mode &other) const bool screen_mode::operator!=(const screen_mode &other) const { - // make no difference between 24 and 32 bit modes - color_space thisSpace = space; - if (thisSpace == B_RGB24) - thisSpace = B_RGB32; - - color_space otherSpace = other.space; - if (otherSpace == B_RGB24) - otherSpace = B_RGB32; - return width != other.width || height != other.height - || thisSpace != otherSpace || refresh != other.refresh + || space != other.space || refresh != other.refresh || combine != other.combine || swap_displays != other.swap_displays || use_laptop_panel != other.use_laptop_panel diff --git a/src/preferences/screen/ScreenWindow.cpp b/src/preferences/screen/ScreenWindow.cpp index e3056ef4c1..9ed072dc2f 100644 --- a/src/preferences/screen/ScreenWindow.cpp +++ b/src/preferences/screen/ScreenWindow.cpp @@ -72,6 +72,7 @@ static const struct { { B_CMAP8, 8, "8 Bits/Pixel, 256 Colors" }, { B_RGB15, 15, "15 Bits/Pixel, 32768 Colors" }, { B_RGB16, 16, "16 Bits/Pixel, 65536 Colors" }, + { B_RGB24, 24, "24 Bits/Pixel, 16 Million Colors" }, { B_RGB32, 32, "32 Bits/Pixel, 16 Million Colors" } }; static const int32 kColorSpaceCount @@ -175,6 +176,7 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings) fIsVesa = true; _UpdateOriginal(); + _BuildSupportedColorSpaces(); fActive = fSelected = fOriginal; fSettings = settings; @@ -282,11 +284,18 @@ ScreenWindow::ScreenWindow(ScreenSettings* settings) fColorsMenu = new BPopUpMenu("colors", true, false); for (int32 i = 0; i < kColorSpaceCount; i++) { + if ((fSupportedColorSpaces & (1 << i)) == 0) + continue; + BMessage *message = new BMessage(POP_COLORS_MSG); message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); message->AddInt32("space", kColorSpaces[i].space); - fColorsMenu->AddItem(new BMenuItem(kColorSpaces[i].label, message)); + BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message); + if (kColorSpaces[i].space == screen.ColorSpace()) + fUserSelectedColorSpace = item; + + fColorsMenu->AddItem(item); } rect.OffsetTo(B_ORIGIN); @@ -511,7 +520,7 @@ ScreenWindow::QuitRequested() /*! Update resolution list according to combine mode - (some resolution may not be combinable due to memory restrictions) + (some resolutions may not be combinable due to memory restrictions). */ void ScreenWindow::_CheckResolutionMenu() @@ -542,7 +551,13 @@ ScreenWindow::_CheckResolutionMenu() void ScreenWindow::_CheckColorMenu() { + int32 supportsAnything = false; + int32 index = 0; + for (int32 i = 0; i < kColorSpaceCount; i++) { + if ((fSupportedColorSpaces & (1 << i)) == 0) + continue; + bool supported = false; for (int32 j = 0; j < fScreenMode.CountModes(); j++) { @@ -550,20 +565,72 @@ ScreenWindow::_CheckColorMenu() if (fSelected.width == mode.width && fSelected.height == mode.height - && (kColorSpaces[i].space == mode.space - // advertize 24 bit mode as 32 bit to avoid confusion - || (kColorSpaces[i].space == B_RGB32 - && mode.space == B_RGB24)) + && kColorSpaces[i].space == mode.space && fSelected.combine == mode.combine) { + supportsAnything = true; supported = true; break; } } - BMenuItem* item = fColorsMenu->ItemAt(i); + BMenuItem* item = fColorsMenu->ItemAt(index++); if (item) item->SetEnabled(supported); } + + fColorsField->SetEnabled(supportsAnything); + + if (!supportsAnything) + return; + + // Make sure a valid item is selected + + BMenuItem* item = fColorsMenu->FindMarked(); + bool changed = false; + + if (item != fUserSelectedColorSpace) { + if (fUserSelectedColorSpace != NULL + && fUserSelectedColorSpace->IsEnabled()) { + fUserSelectedColorSpace->SetMarked(true); + item = fUserSelectedColorSpace; + changed = true; + } + } + if (item != NULL && !item->IsEnabled()) { + // find the next best item + int32 index = fColorsMenu->IndexOf(item); + bool found = false; + + for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) { + item = fColorsMenu->ItemAt(i); + if (item->IsEnabled()) { + found = true; + break; + } + } + if (!found) { + // search backwards as well + for (int32 i = index - 1; i >= 0; i--) { + item = fColorsMenu->ItemAt(i); + if (item->IsEnabled()) + break; + } + } + + item->SetMarked(true); + changed = true; + } + + if (changed) { + // Update selected space + + BMessage* message = item->Message(); + int32 space; + if (message->FindInt32("space", &space) == B_OK) { + fSelected.space = (color_space)space; + _UpdateColorLabel(); + } + } } @@ -694,28 +761,22 @@ ScreenWindow::_UpdateControls() item = fColorsMenu->ItemAt(0); - for (int32 i = kColorSpaceCount; i-- > 0;) { - if (kColorSpaces[i].space == fSelected.space - || (kColorSpaces[i].space == B_RGB32 - && fSelected.space == B_RGB24)) { - item = fColorsMenu->ItemAt(i); + for (int32 i = 0, index = 0; i < kColorSpaceCount; i++) { + if ((fSupportedColorSpaces & (1 << i)) == 0) + continue; + + if (kColorSpaces[i].space == fSelected.space) { + item = fColorsMenu->ItemAt(index); break; } + + index++; } if (item && !item->IsMarked()) item->SetMarked(true); - string.Truncate(0); - uint32 bitsPerPixel = fSelected.BitsPerPixel(); - // advertize 24 bit mode as 32 bit to avoid confusion - if (bitsPerPixel == 24) - bitsPerPixel = 32; - - string << bitsPerPixel << " Bits/Pixel"; - if (string != fColorsMenu->Superitem()->Label()) - fColorsMenu->Superitem()->SetLabel(string.String()); - + _UpdateColorLabel(); _UpdateMonitorView(); _UpdateRefreshControl(); @@ -857,11 +918,17 @@ ScreenWindow::MessageReceived(BMessage* message) case POP_COLORS_MSG: { - message->FindInt32("space", (int32 *)&fSelected.space); + int32 space; + if (message->FindInt32("space", &space) != B_OK) + break; - BString string; - string << fSelected.BitsPerPixel() << " Bits/Pixel"; - fColorsMenu->Superitem()->SetLabel(string.String()); + int32 index; + if (message->FindInt32("index", &index) == B_OK + && fColorsMenu->ItemAt(index) != NULL) + fUserSelectedColorSpace = fColorsMenu->ItemAt(index); + + fSelected.space = (color_space)space; + _UpdateColorLabel(); _CheckApplyEnabled(); break; @@ -871,7 +938,7 @@ ScreenWindow::MessageReceived(BMessage* message) { message->FindFloat("refresh", &fSelected.refresh); fOtherRefresh->SetLabel("Other" B_UTF8_ELLIPSIS); - // revert "Other…" label - it might have had a refresh rate prefix + // revert "Other…" label - it might have a refresh rate prefix _CheckApplyEnabled(); break; @@ -1063,6 +1130,22 @@ ScreenWindow::_GetColumnRowButton(bool columns, bool plus) } +void +ScreenWindow::_BuildSupportedColorSpaces() +{ + fSupportedColorSpaces = 0; + + for (int32 i = 0; i < kColorSpaceCount; i++) { + for (int32 j = 0; j < fScreenMode.CountModes(); j++) { + if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) { + fSupportedColorSpaces |= 1 << i; + break; + } + } + } +} + + void ScreenWindow::_CheckApplyEnabled() { @@ -1141,6 +1224,15 @@ ScreenWindow::_UpdateMonitor() } +void +ScreenWindow::_UpdateColorLabel() +{ + BString string; + string << fSelected.BitsPerPixel() << " Bits/Pixel"; + fColorsMenu->Superitem()->SetLabel(string.String()); +} + + void ScreenWindow::_Apply() { diff --git a/src/preferences/screen/ScreenWindow.h b/src/preferences/screen/ScreenWindow.h index 14d7036d5a..290dfd66fe 100644 --- a/src/preferences/screen/ScreenWindow.h +++ b/src/preferences/screen/ScreenWindow.h @@ -29,79 +29,86 @@ class ScreenSettings; class ScreenWindow : public BWindow { - public: - ScreenWindow(ScreenSettings *settings); - virtual ~ScreenWindow(); +public: + ScreenWindow(ScreenSettings *settings); + virtual ~ScreenWindow(); - virtual bool QuitRequested(); - virtual void MessageReceived(BMessage *message); - virtual void WorkspaceActivated(int32 ws, bool state); - virtual void ScreenChanged(BRect frame, color_space mode); + virtual bool QuitRequested(); + virtual void MessageReceived(BMessage *message); + virtual void WorkspaceActivated(int32 ws, bool state); + virtual void ScreenChanged(BRect frame, color_space mode); - private: - BButton* _CreateColumnRowButton(bool columns, bool plus); - BButton* _GetColumnRowButton(bool columns, bool plus); +private: + BButton* _CreateColumnRowButton(bool columns, bool plus); + BButton* _GetColumnRowButton(bool columns, bool plus); - void _CheckApplyEnabled(); - void _CheckResolutionMenu(); - void _CheckColorMenu(); - void _CheckRefreshMenu(); + void _BuildSupportedColorSpaces(); - void _UpdateActiveMode(); - void _UpdateWorkspaceButtons(); - void _UpdateRefreshControl(); - void _UpdateMonitorView(); - void _UpdateControls(); - void _UpdateOriginal(); - void _UpdateMonitor(); + void _CheckApplyEnabled(); + void _CheckResolutionMenu(); + void _CheckColorMenu(); + void _CheckRefreshMenu(); - void _Apply(); + void _UpdateActiveMode(); + void _UpdateWorkspaceButtons(); + void _UpdateRefreshControl(); + void _UpdateMonitorView(); + void _UpdateControls(); + void _UpdateOriginal(); + void _UpdateMonitor(); + void _UpdateColorLabel(); - status_t _WriteVesaModeFile(const screen_mode& mode) const; - bool _IsVesa() const { return fIsVesa; } + void _Apply(); - ScreenSettings* fSettings; - bool fIsVesa; - bool fBootWorkspaceApplied; + status_t _WriteVesaModeFile(const screen_mode& mode) const; + bool _IsVesa() const { return fIsVesa; } - BStringView* fMonitorInfo; - MonitorView* fMonitorView; - BMenuItem* fAllWorkspacesItem; +private: + ScreenSettings* fSettings; + bool fIsVesa; + bool fBootWorkspaceApplied; - BTextControl* fColumnsControl; - BTextControl* fRowsControl; - BButton* fWorkspacesButtons[4]; + BStringView* fMonitorInfo; + MonitorView* fMonitorView; + BMenuItem* fAllWorkspacesItem; - BPopUpMenu* fResolutionMenu; - BMenuField* fResolutionField; - BPopUpMenu* fColorsMenu; - BMenuField* fColorsField; - BPopUpMenu* fRefreshMenu; - BMenuField* fRefreshField; - BMenuItem* fOtherRefresh; + BTextControl* fColumnsControl; + BTextControl* fRowsControl; + BButton* fWorkspacesButtons[4]; - BPopUpMenu* fCombineMenu; - BMenuField* fCombineField; - BPopUpMenu* fSwapDisplaysMenu; - BMenuField* fSwapDisplaysField; - BPopUpMenu* fUseLaptopPanelMenu; - BMenuField* fUseLaptopPanelField; - BPopUpMenu* fTVStandardMenu; - BMenuField* fTVStandardField; + uint32 fSupportedColorSpaces; + BMenuItem* fUserSelectedColorSpace; - BButton* fDefaultsButton; - BButton* fApplyButton; - BButton* fRevertButton; + BPopUpMenu* fResolutionMenu; + BMenuField* fResolutionField; + BPopUpMenu* fColorsMenu; + BMenuField* fColorsField; + BPopUpMenu* fRefreshMenu; + BMenuField* fRefreshField; + BMenuItem* fOtherRefresh; - BButton* fBackgroundsButton; + BPopUpMenu* fCombineMenu; + BMenuField* fCombineField; + BPopUpMenu* fSwapDisplaysMenu; + BMenuField* fSwapDisplaysField; + BPopUpMenu* fUseLaptopPanelMenu; + BMenuField* fUseLaptopPanelField; + BPopUpMenu* fTVStandardMenu; + BMenuField* fTVStandardField; - ScreenMode fScreenMode, fTempScreenMode; - // screen modes for all workspaces - uint32 fOriginalWorkspacesColumns; - uint32 fOriginalWorkspacesRows; - screen_mode fActive, fSelected, fOriginal; - // screen modes for the current workspace - bool fModified; + BButton* fDefaultsButton; + BButton* fApplyButton; + BButton* fRevertButton; + + BButton* fBackgroundsButton; + + ScreenMode fScreenMode, fTempScreenMode; + // screen modes for all workspaces + uint32 fOriginalWorkspacesColumns; + uint32 fOriginalWorkspacesRows; + screen_mode fActive, fSelected, fOriginal; + // screen modes for the current workspace + bool fModified; }; #endif /* SCREEN_WINDOW_H */