1a10cf76eSAxel Dörfler /* 28242ac7fSAxel Dörfler * Copyright 2001-2006, Haiku. 3a10cf76eSAxel Dörfler * Distributed under the terms of the MIT License. 4a10cf76eSAxel Dörfler * 5a10cf76eSAxel Dörfler * Authors: 6a10cf76eSAxel Dörfler * Rafael Romo 7a10cf76eSAxel Dörfler * Stefano Ceccherini (burton666@libero.it) 8a10cf76eSAxel Dörfler * Andrew Bachmann 9a10cf76eSAxel Dörfler * Thomas Kurschel 10a10cf76eSAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 11df3f5bacSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 12a10cf76eSAxel Dörfler */ 13a10cf76eSAxel Dörfler 14a10cf76eSAxel Dörfler 15a10cf76eSAxel Dörfler #include <Alert.h> 16a10cf76eSAxel Dörfler #include <Application.h> 17a10cf76eSAxel Dörfler #include <Box.h> 18a10cf76eSAxel Dörfler #include <Button.h> 19a10cf76eSAxel Dörfler #include <InterfaceDefs.h> 20df3f5bacSStephan Aßmus #include <MenuBar.h> 21a10cf76eSAxel Dörfler #include <MenuItem.h> 22a10cf76eSAxel Dörfler #include <MenuField.h> 23a10cf76eSAxel Dörfler #include <Messenger.h> 24a10cf76eSAxel Dörfler #include <PopUpMenu.h> 25a10cf76eSAxel Dörfler #include <Screen.h> 26a10cf76eSAxel Dörfler #include <String.h> 27df3f5bacSStephan Aßmus #include <Roster.h> 28a10cf76eSAxel Dörfler #include <Window.h> 29a10cf76eSAxel Dörfler 30a10cf76eSAxel Dörfler #include <cstdio> 31a10cf76eSAxel Dörfler #include <cstdlib> 32a10cf76eSAxel Dörfler #include <cstring> 33a10cf76eSAxel Dörfler 34a10cf76eSAxel Dörfler #include "AlertWindow.h" 35a10cf76eSAxel Dörfler #include "Constants.h" 36a10cf76eSAxel Dörfler #include "RefreshWindow.h" 37a10cf76eSAxel Dörfler #include "MonitorView.h" 38a10cf76eSAxel Dörfler #include "ScreenSettings.h" 39a10cf76eSAxel Dörfler #include "ScreenWindow.h" 40a10cf76eSAxel Dörfler #include "Utility.h" 41a10cf76eSAxel Dörfler 42a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant. 43a10cf76eSAxel Dörfler * It's a solution that works with the current BeOS interface that Haiku 44a10cf76eSAxel Dörfler * adopted. 45a10cf76eSAxel Dörfler * However, it's not a nice and clean solution. Don't use this header in any 46a10cf76eSAxel Dörfler * application if you can avoid it. No other driver is using this, or should 47a10cf76eSAxel Dörfler * be using this. 48a10cf76eSAxel Dörfler * It will be replaced as soon as we introduce an updated accelerant interface 49a10cf76eSAxel Dörfler * which may even happen before R1 hits the streets. 50a10cf76eSAxel Dörfler */ 51a10cf76eSAxel Dörfler 52a10cf76eSAxel Dörfler #include "multimon.h" // the usual: DANGER WILL, ROBINSON! 53a10cf76eSAxel Dörfler 54a10cf76eSAxel Dörfler 55a10cf76eSAxel Dörfler #define USE_FIXED_REFRESH 56a10cf76eSAxel Dörfler // define to use fixed standard refresh rates 57a10cf76eSAxel Dörfler // undefine to get standard refresh rates from driver 58a10cf76eSAxel Dörfler 59a10cf76eSAxel Dörfler 60c5d80d47SAxel Dörfler const char* kBackgroundsSignature = "application/x-vnd.haiku-backgrounds"; 61c5d80d47SAxel Dörfler 62a10cf76eSAxel Dörfler // list of officially supported colour spaces 63a10cf76eSAxel Dörfler static const struct { 64a10cf76eSAxel Dörfler color_space space; 65a10cf76eSAxel Dörfler int32 bits_per_pixel; 66a10cf76eSAxel Dörfler const char* label; 67a10cf76eSAxel Dörfler } kColorSpaces[] = { 68a10cf76eSAxel Dörfler { B_CMAP8, 8, "8 Bits/Pixel, 256 Colors" }, 69a10cf76eSAxel Dörfler { B_RGB15, 15, "15 Bits/Pixel, 32768 Colors" }, 70a10cf76eSAxel Dörfler { B_RGB16, 16, "16 Bits/Pixel, 65536 Colors" }, 71a10cf76eSAxel Dörfler { B_RGB32, 32, "32 Bits/Pixel, 16 Million Colors" } 72a10cf76eSAxel Dörfler }; 73a10cf76eSAxel Dörfler static const int32 kColorSpaceCount = sizeof(kColorSpaces) / sizeof(kColorSpaces[0]); 74a10cf76eSAxel Dörfler 75a10cf76eSAxel Dörfler // list of standard refresh rates 76*a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 }; 77a10cf76eSAxel Dörfler static const int32 kRefreshRateCount = sizeof(kRefreshRates) / sizeof(kRefreshRates[0]); 78a10cf76eSAxel Dörfler 79a10cf76eSAxel Dörfler 80a10cf76eSAxel Dörfler // list of combine modes 81a10cf76eSAxel Dörfler static const struct { 82a10cf76eSAxel Dörfler combine_mode mode; 83a10cf76eSAxel Dörfler const char *name; 84a10cf76eSAxel Dörfler } kCombineModes[] = { 85a10cf76eSAxel Dörfler { kCombineDisable, "disable" }, 86a10cf76eSAxel Dörfler { kCombineHorizontally, "horizontally" }, 87a10cf76eSAxel Dörfler { kCombineVertically, "vertically" } 88a10cf76eSAxel Dörfler }; 89a10cf76eSAxel Dörfler static const int32 kCombineModeCount = sizeof(kCombineModes) / sizeof(kCombineModes[0]); 90a10cf76eSAxel Dörfler 91a10cf76eSAxel Dörfler 92a10cf76eSAxel Dörfler static BString 93a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 94a10cf76eSAxel Dörfler { 95a10cf76eSAxel Dörfler switch (mode) { 96a10cf76eSAxel Dörfler case 0: return "disabled"; 97a10cf76eSAxel Dörfler case 1: return "NTSC"; 98a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 99a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 100a10cf76eSAxel Dörfler case 4: return "PAL M"; 101a10cf76eSAxel Dörfler case 5: return "PAL N"; 102a10cf76eSAxel Dörfler case 6: return "SECAM"; 103a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 104a10cf76eSAxel Dörfler case 102: return "PAL 60"; 105a10cf76eSAxel Dörfler case 103: return "PAL NC"; 106a10cf76eSAxel Dörfler default: 107a10cf76eSAxel Dörfler { 108a10cf76eSAxel Dörfler BString name; 109a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 110a10cf76eSAxel Dörfler 111a10cf76eSAxel Dörfler return name; 112a10cf76eSAxel Dörfler } 113a10cf76eSAxel Dörfler } 114a10cf76eSAxel Dörfler } 115a10cf76eSAxel Dörfler 116a10cf76eSAxel Dörfler 117a10cf76eSAxel Dörfler static void 118a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 119a10cf76eSAxel Dörfler { 120a10cf76eSAxel Dörfler string << mode.width << " x " << mode.height; 121a10cf76eSAxel Dörfler } 122a10cf76eSAxel Dörfler 123a10cf76eSAxel Dörfler 124a10cf76eSAxel Dörfler static void 125a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 126a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 127a10cf76eSAxel Dörfler { 128a10cf76eSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, refresh); 129a10cf76eSAxel Dörfler string.UnlockBuffer(); 130a10cf76eSAxel Dörfler 131a10cf76eSAxel Dörfler if (appendUnit) 132a10cf76eSAxel Dörfler string << " Hz"; 133a10cf76eSAxel Dörfler } 134a10cf76eSAxel Dörfler 135a10cf76eSAxel Dörfler 13607184a9eSAxel Dörfler static const char* 13707184a9eSAxel Dörfler screen_errors(status_t status) 13807184a9eSAxel Dörfler { 13907184a9eSAxel Dörfler switch (status) { 14007184a9eSAxel Dörfler case B_ENTRY_NOT_FOUND: 14107184a9eSAxel Dörfler return "Unknown Mode"; 14207184a9eSAxel Dörfler // TODO: add more? 14307184a9eSAxel Dörfler 14407184a9eSAxel Dörfler default: 14507184a9eSAxel Dörfler return strerror(status); 14607184a9eSAxel Dörfler } 14707184a9eSAxel Dörfler } 14807184a9eSAxel Dörfler 149df3f5bacSStephan Aßmus enum { 150df3f5bacSStephan Aßmus SHOW_COMBINE_FIELD = 0x01, 151df3f5bacSStephan Aßmus SHOW_SWAP_FIELD = 0x02, 152df3f5bacSStephan Aßmus SHOW_LAPTOP_PANEL_FIELD = 0x04, 153df3f5bacSStephan Aßmus SHOW_TV_STANDARD_FIELD = 0x08, 154df3f5bacSStephan Aßmus }; 155df3f5bacSStephan Aßmus 156df3f5bacSStephan Aßmus 1573dfd20c0SStephan Aßmus // #pragma mark - 1583dfd20c0SStephan Aßmus 1593dfd20c0SStephan Aßmus 1605a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings *settings) 1615a78744bSAxel Dörfler : BWindow(settings->WindowFrame(), "Screen", B_TITLED_WINDOW, 162a10cf76eSAxel Dörfler B_NOT_RESIZABLE | B_NOT_ZOOMABLE, B_ALL_WORKSPACES), 163a10cf76eSAxel Dörfler fScreenMode(this), 164a10cf76eSAxel Dörfler fChangingAllWorkspaces(false) 165a10cf76eSAxel Dörfler { 166a10cf76eSAxel Dörfler BScreen screen(this); 167a10cf76eSAxel Dörfler 168a10cf76eSAxel Dörfler fScreenMode.Get(fOriginal); 169a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 170a10cf76eSAxel Dörfler 171df3f5bacSStephan Aßmus BView *view = new BView(Bounds(), "ScreenView", B_FOLLOW_ALL, B_WILL_DRAW); 172a10cf76eSAxel Dörfler view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 173a10cf76eSAxel Dörfler AddChild(view); 174a10cf76eSAxel Dörfler 1755a78744bSAxel Dörfler fSettings = settings; 1765a78744bSAxel Dörfler 1775a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 1785a78744bSAxel Dörfler 1795a78744bSAxel Dörfler BPopUpMenu *popUpMenu = new BPopUpMenu("Current Workspace", true, true); 1805a78744bSAxel Dörfler fAllWorkspacesItem = new BMenuItem("All Workspaces", new BMessage(WORKSPACE_CHECK_MSG)); 1815a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 1825a78744bSAxel Dörfler BMenuItem *item = new BMenuItem("Current Workspace", new BMessage(WORKSPACE_CHECK_MSG)); 1835a78744bSAxel Dörfler item->SetMarked(true); 1845a78744bSAxel Dörfler popUpMenu->AddItem(item); 1855a78744bSAxel Dörfler 186df3f5bacSStephan Aßmus BMenuField* workspaceMenuField = new BMenuField(BRect(0, 0, 100, 15), 1875a78744bSAxel Dörfler "WorkspaceMenu", NULL, popUpMenu, true); 1885a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 189a10cf76eSAxel Dörfler 190a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 191a10cf76eSAxel Dörfler 1925a78744bSAxel Dörfler popUpMenu = new BPopUpMenu("", true, true); 193df3f5bacSStephan Aßmus fWorkspaceCountField = new BMenuField(BRect(0.0, 0.0, 50.0, 15.0), 194df3f5bacSStephan Aßmus "WorkspaceCountMenu", "Workspace count:", popUpMenu, true); 195df3f5bacSStephan Aßmus float labelWidth = fWorkspaceCountField->StringWidth(fWorkspaceCountField->Label()) + 5.0; 196df3f5bacSStephan Aßmus fWorkspaceCountField->SetDivider(labelWidth); 197df3f5bacSStephan Aßmus 198df3f5bacSStephan Aßmus fScreenBox = new BBox(BRect(0.0, 0.0, 100.0, 100.0), "left box"); 199df3f5bacSStephan Aßmus fScreenBox->AddChild(fWorkspaceCountField); 200a10cf76eSAxel Dörfler 201a10cf76eSAxel Dörfler for (int32 count = 1; count <= 32; count++) { 202a10cf76eSAxel Dörfler BString workspaceCount; 203a10cf76eSAxel Dörfler workspaceCount << count; 204a10cf76eSAxel Dörfler 205a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_WORKSPACE_CHANGED_MSG); 206a10cf76eSAxel Dörfler message->AddInt32("workspace count", count); 207a10cf76eSAxel Dörfler 208a10cf76eSAxel Dörfler popUpMenu->AddItem(new BMenuItem(workspaceCount.String(), 209a10cf76eSAxel Dörfler message)); 210a10cf76eSAxel Dörfler } 211a10cf76eSAxel Dörfler 2125a78744bSAxel Dörfler item = popUpMenu->ItemAt(count_workspaces() - 1); 213a10cf76eSAxel Dörfler if (item != NULL) 214a10cf76eSAxel Dörfler item->SetMarked(true); 215a10cf76eSAxel Dörfler 216df3f5bacSStephan Aßmus fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0), "monitor", 2175a78744bSAxel Dörfler screen.Frame().Width() + 1, screen.Frame().Height() + 1); 218df3f5bacSStephan Aßmus fScreenBox->AddChild(fMonitorView); 2195a78744bSAxel Dörfler 220df3f5bacSStephan Aßmus view->AddChild(fScreenBox); 221a10cf76eSAxel Dörfler 222a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 223a10cf76eSAxel Dörfler 224df3f5bacSStephan Aßmus fControlsBox = new BBox(BRect(0.0, 0.0, 100.0, 100.0)); 225df3f5bacSStephan Aßmus fControlsBox->SetLabel(workspaceMenuField); 226a10cf76eSAxel Dörfler 227a10cf76eSAxel Dörfler fResolutionMenu = new BPopUpMenu("resolution", true, true); 228a10cf76eSAxel Dörfler 229a10cf76eSAxel Dörfler uint16 previousWidth = 0, previousHeight = 0; 230a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 231a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 232a10cf76eSAxel Dörfler 233a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 234a10cf76eSAxel Dörfler continue; 235a10cf76eSAxel Dörfler 236a10cf76eSAxel Dörfler previousWidth = mode.width; 237a10cf76eSAxel Dörfler previousHeight = mode.height; 238a10cf76eSAxel Dörfler 239a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_RESOLUTION_MSG); 240a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 241a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 242a10cf76eSAxel Dörfler 243a10cf76eSAxel Dörfler BString name; 244a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 245a10cf76eSAxel Dörfler 246a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 247a10cf76eSAxel Dörfler } 248a10cf76eSAxel Dörfler 249df3f5bacSStephan Aßmus BRect rect(0.0, 0.0, 30.0, 15.0); 250df3f5bacSStephan Aßmus // fResolutionField needs to be at the correct 251df3f5bacSStephan Aßmus // left-top offset, because all other menu fields 252df3f5bacSStephan Aßmus // will be layouted relative to it 253df3f5bacSStephan Aßmus fResolutionField = new BMenuField(rect.OffsetToCopy(10.0, 30.0), 254df3f5bacSStephan Aßmus "ResolutionMenu", "Resolution:", fResolutionMenu, true); 255df3f5bacSStephan Aßmus fControlsBox->AddChild(fResolutionField); 256a10cf76eSAxel Dörfler 257a10cf76eSAxel Dörfler fColorsMenu = new BPopUpMenu("colors", true, true); 258a10cf76eSAxel Dörfler 259a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 260a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_COLORS_MSG); 261a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 262a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 263a10cf76eSAxel Dörfler 264a10cf76eSAxel Dörfler fColorsMenu->AddItem(new BMenuItem(kColorSpaces[i].label, message)); 265a10cf76eSAxel Dörfler } 266a10cf76eSAxel Dörfler 267df3f5bacSStephan Aßmus rect.OffsetTo(B_ORIGIN); 268df3f5bacSStephan Aßmus 269a10cf76eSAxel Dörfler fColorsField = new BMenuField(rect, "ColorsMenu", "Colors:", fColorsMenu, true); 270df3f5bacSStephan Aßmus fControlsBox->AddChild(fColorsField); 271a10cf76eSAxel Dörfler 272a10cf76eSAxel Dörfler fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 273a10cf76eSAxel Dörfler 274a10cf76eSAxel Dörfler #ifdef USE_FIXED_REFRESH 275a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 276a10cf76eSAxel Dörfler BString name; 277a10cf76eSAxel Dörfler name << kRefreshRates[i] << " Hz"; 278a10cf76eSAxel Dörfler 279a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_REFRESH_MSG); 280a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 281a10cf76eSAxel Dörfler 282a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 283a10cf76eSAxel Dörfler } 284a10cf76eSAxel Dörfler #endif 285a10cf76eSAxel Dörfler 286a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_OTHER_REFRESH_MSG); 287a10cf76eSAxel Dörfler 288a10cf76eSAxel Dörfler fOtherRefresh = new BMenuItem("Other" B_UTF8_ELLIPSIS, message); 289a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 290a10cf76eSAxel Dörfler 291a10cf76eSAxel Dörfler fRefreshField = new BMenuField(rect, "RefreshMenu", "Refresh Rate:", fRefreshMenu, true); 292df3f5bacSStephan Aßmus fControlsBox->AddChild(fRefreshField); 293a10cf76eSAxel Dörfler 294df3f5bacSStephan Aßmus view->AddChild(fControlsBox); 295df3f5bacSStephan Aßmus 296df3f5bacSStephan Aßmus uint32 controlsFlags = 0; 297a10cf76eSAxel Dörfler 298a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 299a10cf76eSAxel Dörfler { 300a10cf76eSAxel Dörfler bool dummy; 301a10cf76eSAxel Dörfler uint32 dummy32; 302a10cf76eSAxel Dörfler bool multiMonSupport; 303a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 304a10cf76eSAxel Dörfler bool tvStandardSupport; 305a10cf76eSAxel Dörfler 306a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 307a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 308a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 309df3f5bacSStephan Aßmus if (multiMonSupport) { 310df3f5bacSStephan Aßmus controlsFlags |= SHOW_COMBINE_FIELD; 311df3f5bacSStephan Aßmus controlsFlags |= SHOW_SWAP_FIELD; 312df3f5bacSStephan Aßmus } 313df3f5bacSStephan Aßmus if (useLaptopPanelSupport) 314df3f5bacSStephan Aßmus controlsFlags |= SHOW_LAPTOP_PANEL_FIELD; 315a10cf76eSAxel Dörfler 316a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 317a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 318a10cf76eSAxel Dörfler 319a10cf76eSAxel Dörfler fCombineMenu = new BPopUpMenu("CombineDisplays", true, true); 320a10cf76eSAxel Dörfler 321a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 322a10cf76eSAxel Dörfler message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 323a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 324a10cf76eSAxel Dörfler 325a10cf76eSAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, message)); 326a10cf76eSAxel Dörfler } 327a10cf76eSAxel Dörfler 328df3f5bacSStephan Aßmus fCombineField = new BMenuField(rect, "CombineMenu", 329a10cf76eSAxel Dörfler "Combine Displays:", fCombineMenu, true); 330df3f5bacSStephan Aßmus fControlsBox->AddChild(fCombineField); 331a10cf76eSAxel Dörfler 332a10cf76eSAxel Dörfler if (!multiMonSupport) 333df3f5bacSStephan Aßmus fCombineField->Hide(); 334a10cf76eSAxel Dörfler 335a10cf76eSAxel Dörfler fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", true, true); 336a10cf76eSAxel Dörfler 337a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 338a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 339a10cf76eSAxel Dörfler message->AddBool("swap", false); 340a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("no", message)); 341a10cf76eSAxel Dörfler 342a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 343a10cf76eSAxel Dörfler message->AddBool("swap", true); 344a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("yes", message)); 345a10cf76eSAxel Dörfler 346df3f5bacSStephan Aßmus fSwapDisplaysField = new BMenuField(rect, "SwapMenu", "Swap Displays:", 347a10cf76eSAxel Dörfler fSwapDisplaysMenu, true); 348a10cf76eSAxel Dörfler 349df3f5bacSStephan Aßmus fControlsBox->AddChild(fSwapDisplaysField); 350a10cf76eSAxel Dörfler if (!multiMonSupport) 351df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 352a10cf76eSAxel Dörfler 353a10cf76eSAxel Dörfler fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", true, true); 354a10cf76eSAxel Dörfler 355a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 356a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 357a10cf76eSAxel Dörfler message->AddBool("use", false); 358a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("if needed", message)); 359a10cf76eSAxel Dörfler 360a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 361a10cf76eSAxel Dörfler message->AddBool("use", true); 362a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("always", message)); 363a10cf76eSAxel Dörfler 364df3f5bacSStephan Aßmus fUseLaptopPanelField = new BMenuField(rect, "UseLaptopPanel", "Use Laptop Panel:", 365a10cf76eSAxel Dörfler fUseLaptopPanelMenu, true); 366a10cf76eSAxel Dörfler 367df3f5bacSStephan Aßmus fControlsBox->AddChild(fUseLaptopPanelField); 368a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 369df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 370a10cf76eSAxel Dörfler 371a10cf76eSAxel Dörfler fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 372a10cf76eSAxel Dörfler 373a10cf76eSAxel Dörfler // arbitrary limit 374a10cf76eSAxel Dörfler uint32 i; 375a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 376a10cf76eSAxel Dörfler uint32 mode; 377a10cf76eSAxel Dörfler 378a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 379a10cf76eSAxel Dörfler break; 380a10cf76eSAxel Dörfler 381a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 382a10cf76eSAxel Dörfler 383a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 384a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 385a10cf76eSAxel Dörfler 386a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 387a10cf76eSAxel Dörfler } 388a10cf76eSAxel Dörfler 389df3f5bacSStephan Aßmus fTVStandardField = new BMenuField(rect, "tv standard", "Video Format:", 390a10cf76eSAxel Dörfler fTVStandardMenu, true); 391df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 392a10cf76eSAxel Dörfler 393df3f5bacSStephan Aßmus if (!tvStandardSupport || i == 0) { 394df3f5bacSStephan Aßmus fTVStandardField->Hide(); 395df3f5bacSStephan Aßmus } else { 396df3f5bacSStephan Aßmus controlsFlags |= SHOW_TV_STANDARD_FIELD; 397a10cf76eSAxel Dörfler } 398a10cf76eSAxel Dörfler 399df3f5bacSStephan Aßmus fControlsBox->AddChild(fTVStandardField); 400df3f5bacSStephan Aßmus } 401df3f5bacSStephan Aßmus 402df3f5bacSStephan Aßmus BRect buttonRect(0.0, 0.0, 30.0, 10.0); 403df3f5bacSStephan Aßmus fBackgroundsButton = new BButton(buttonRect, "BackgroundsButton", 404df3f5bacSStephan Aßmus "Set Background"B_UTF8_ELLIPSIS, new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG)); 4053dfd20c0SStephan Aßmus fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9); 406df3f5bacSStephan Aßmus fScreenBox->AddChild(fBackgroundsButton); 407df3f5bacSStephan Aßmus 408df3f5bacSStephan Aßmus fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 409a10cf76eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG)); 410a10cf76eSAxel Dörfler view->AddChild(fDefaultsButton); 411a10cf76eSAxel Dörfler 412df3f5bacSStephan Aßmus fRevertButton = new BButton(buttonRect, "RevertButton", "Revert", 413a10cf76eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 414a10cf76eSAxel Dörfler fRevertButton->SetEnabled(false); 415a10cf76eSAxel Dörfler view->AddChild(fRevertButton); 416a10cf76eSAxel Dörfler 417df3f5bacSStephan Aßmus fApplyButton = new BButton(buttonRect, "ApplyButton", "Apply", 418df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 419df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 420df3f5bacSStephan Aßmus view->AddChild(fApplyButton); 4215a78744bSAxel Dörfler 422a10cf76eSAxel Dörfler UpdateControls(); 423df3f5bacSStephan Aßmus 424df3f5bacSStephan Aßmus LayoutControls(controlsFlags); 425a10cf76eSAxel Dörfler } 426a10cf76eSAxel Dörfler 427a10cf76eSAxel Dörfler 428a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 429a10cf76eSAxel Dörfler { 430a10cf76eSAxel Dörfler delete fSettings; 431a10cf76eSAxel Dörfler } 432a10cf76eSAxel Dörfler 433a10cf76eSAxel Dörfler 434a10cf76eSAxel Dörfler bool 435a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 436a10cf76eSAxel Dörfler { 437a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 438a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 439a10cf76eSAxel Dörfler 440a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 441a10cf76eSAxel Dörfler } 442a10cf76eSAxel Dörfler 443a10cf76eSAxel Dörfler 444a10cf76eSAxel Dörfler /** update resolution list according to combine mode 445a10cf76eSAxel Dörfler * (some resolution may not be combinable due to memory restrictions) 446a10cf76eSAxel Dörfler */ 447a10cf76eSAxel Dörfler 448a10cf76eSAxel Dörfler void 449a10cf76eSAxel Dörfler ScreenWindow::CheckResolutionMenu() 450a10cf76eSAxel Dörfler { 451a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 452a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 453a10cf76eSAxel Dörfler 454a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 455a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 456a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 457a10cf76eSAxel Dörfler continue; 458a10cf76eSAxel Dörfler 459a10cf76eSAxel Dörfler BString name; 460a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 461a10cf76eSAxel Dörfler 462a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 463a10cf76eSAxel Dörfler if (item != NULL) 464a10cf76eSAxel Dörfler item->SetEnabled(true); 465a10cf76eSAxel Dörfler } 466a10cf76eSAxel Dörfler } 467a10cf76eSAxel Dörfler 468a10cf76eSAxel Dörfler 469a10cf76eSAxel Dörfler /** update color and refresh options according to current mode 470a10cf76eSAxel Dörfler * (a color space is made active if there is any mode with 471a10cf76eSAxel Dörfler * given resolution and this colour space; same applies for 472a10cf76eSAxel Dörfler * refresh rate, though "Other…" is always possible) 473a10cf76eSAxel Dörfler */ 474a10cf76eSAxel Dörfler 475a10cf76eSAxel Dörfler void 476a10cf76eSAxel Dörfler ScreenWindow::CheckColorMenu() 477a10cf76eSAxel Dörfler { 478a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 479a10cf76eSAxel Dörfler bool supported = false; 480a10cf76eSAxel Dörfler 481a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 482a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 483a10cf76eSAxel Dörfler 484a10cf76eSAxel Dörfler if (fSelected.width == mode.width 485a10cf76eSAxel Dörfler && fSelected.height == mode.height 486a10cf76eSAxel Dörfler && kColorSpaces[i].space == mode.space 487a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 488a10cf76eSAxel Dörfler supported = true; 489a10cf76eSAxel Dörfler break; 490a10cf76eSAxel Dörfler } 491a10cf76eSAxel Dörfler } 492a10cf76eSAxel Dörfler 493a10cf76eSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(i); 494a10cf76eSAxel Dörfler if (item) 495a10cf76eSAxel Dörfler item->SetEnabled(supported); 496a10cf76eSAxel Dörfler } 497a10cf76eSAxel Dörfler } 498a10cf76eSAxel Dörfler 499a10cf76eSAxel Dörfler 500a10cf76eSAxel Dörfler /** Enable/disable refresh options according to current mode. 501a10cf76eSAxel Dörfler * Only needed when USE_FIXED_REFRESH is not defined. 502a10cf76eSAxel Dörfler */ 503a10cf76eSAxel Dörfler 504a10cf76eSAxel Dörfler void 505a10cf76eSAxel Dörfler ScreenWindow::CheckRefreshMenu() 506a10cf76eSAxel Dörfler { 507a10cf76eSAxel Dörfler #ifndef USE_FIXED_REFRESH 508a10cf76eSAxel Dörfler // ToDo: does currently not compile! 509a10cf76eSAxel Dörfler for (int32 i = fRefreshMenu->CountItems() - 2; i >= 0; --i) { 510a10cf76eSAxel Dörfler delete fRefreshMenu->RemoveItem(i); 511a10cf76eSAxel Dörfler } 512a10cf76eSAxel Dörfler 513a10cf76eSAxel Dörfler for (int32 i = 0; i < fModeListCount; ++i) { 514a10cf76eSAxel Dörfler if (virtualWidth == fModeList[i].virtual_width 515a10cf76eSAxel Dörfler && virtualHeight == fModeList[i].virtual_height 516a10cf76eSAxel Dörfler && combine == get_combine_mode(&fModeList[i])) { 517a10cf76eSAxel Dörfler BString name; 518a10cf76eSAxel Dörfler BMenuItem *item; 519a10cf76eSAxel Dörfler 520a10cf76eSAxel Dörfler int32 refresh10 = get_refresh10(fModeList[i]); 521a10cf76eSAxel Dörfler refresh10_to_string(name, refresh10); 522a10cf76eSAxel Dörfler 523a10cf76eSAxel Dörfler item = fRefreshMenu->FindItem(name.String()); 524a10cf76eSAxel Dörfler if (item == NULL) { 525a10cf76eSAxel Dörfler BMessage *msg = new BMessage(POP_REFRESH_MSG); 526a10cf76eSAxel Dörfler msg->AddFloat("refresh", refresh); 527a10cf76eSAxel Dörfler 528a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), msg), 529a10cf76eSAxel Dörfler fRefreshMenu->CountItems() - 1); 530a10cf76eSAxel Dörfler } 531a10cf76eSAxel Dörfler } 532a10cf76eSAxel Dörfler } 533a10cf76eSAxel Dörfler #endif 534a10cf76eSAxel Dörfler 535a10cf76eSAxel Dörfler // TBD: some drivers lack many refresh rates; still, they 536a10cf76eSAxel Dörfler // can be used by generating the mode manually 537a10cf76eSAxel Dörfler /* 538a10cf76eSAxel Dörfler for( i = 0; i < sizeof( refresh_list ) / sizeof( refresh_list[0] ); ++i ) { 539a10cf76eSAxel Dörfler BMenuItem *item; 540a10cf76eSAxel Dörfler bool supported = false; 541a10cf76eSAxel Dörfler 542a10cf76eSAxel Dörfler for( j = 0; j < fModeListCount; ++j ) { 543a10cf76eSAxel Dörfler if( width == fModeList[j].virtual_width && 544a10cf76eSAxel Dörfler height == fModeList[j].virtual_height && 545a10cf76eSAxel Dörfler refresh_list[i].refresh * 10 == getModeRefresh10( &fModeList[j] )) 546a10cf76eSAxel Dörfler { 547a10cf76eSAxel Dörfler supported = true; 548a10cf76eSAxel Dörfler break; 549a10cf76eSAxel Dörfler } 550a10cf76eSAxel Dörfler } 551a10cf76eSAxel Dörfler 552a10cf76eSAxel Dörfler item = fRefreshMenu->ItemAt( i ); 553a10cf76eSAxel Dörfler if( item ) 554a10cf76eSAxel Dörfler item->SetEnabled( supported ); 555a10cf76eSAxel Dörfler } 556a10cf76eSAxel Dörfler */ 557a10cf76eSAxel Dörfler } 558a10cf76eSAxel Dörfler 559a10cf76eSAxel Dörfler 560a10cf76eSAxel Dörfler /** activate appropriate menu item according to selected refresh rate */ 561a10cf76eSAxel Dörfler 562a10cf76eSAxel Dörfler void 563a10cf76eSAxel Dörfler ScreenWindow::UpdateRefreshControl() 564a10cf76eSAxel Dörfler { 565a10cf76eSAxel Dörfler BString string; 566a10cf76eSAxel Dörfler refresh_rate_to_string(fSelected.refresh, string); 567a10cf76eSAxel Dörfler 568a10cf76eSAxel Dörfler BMenuItem* item = fRefreshMenu->FindItem(string.String()); 569a10cf76eSAxel Dörfler if (item) { 570a10cf76eSAxel Dörfler if (!item->IsMarked()) 571a10cf76eSAxel Dörfler item->SetMarked(true); 572a10cf76eSAxel Dörfler // "Other…" items only contains a refresh rate when active 573a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other…"); 574a10cf76eSAxel Dörfler return; 575a10cf76eSAxel Dörfler } 576a10cf76eSAxel Dörfler 577a10cf76eSAxel Dörfler // this is a non-standard refresh rate 578a10cf76eSAxel Dörfler 579a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 580a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 581a10cf76eSAxel Dörfler 582a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 583a10cf76eSAxel Dörfler 584a10cf76eSAxel Dörfler string.Append("/Other" B_UTF8_ELLIPSIS); 585a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 586a10cf76eSAxel Dörfler } 587a10cf76eSAxel Dörfler 588a10cf76eSAxel Dörfler 589a10cf76eSAxel Dörfler void 590a10cf76eSAxel Dörfler ScreenWindow::UpdateMonitorView() 591a10cf76eSAxel Dörfler { 592a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 593a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 594a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 595a10cf76eSAxel Dörfler 596a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 597a10cf76eSAxel Dörfler } 598a10cf76eSAxel Dörfler 599a10cf76eSAxel Dörfler 600a10cf76eSAxel Dörfler void 601a10cf76eSAxel Dörfler ScreenWindow::UpdateControls() 602a10cf76eSAxel Dörfler { 603a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 604a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 605a10cf76eSAxel Dörfler item->SetMarked(true); 606a10cf76eSAxel Dörfler 607a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 608a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 609a10cf76eSAxel Dörfler item->SetMarked(true); 610a10cf76eSAxel Dörfler 611a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 612a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 613a10cf76eSAxel Dörfler 614a10cf76eSAxel Dörfler uint32 tvStandard; 615a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 616a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 617a10cf76eSAxel Dörfler if (!item->IsMarked()) 618a10cf76eSAxel Dörfler item->SetMarked(true); 619a10cf76eSAxel Dörfler break; 620a10cf76eSAxel Dörfler } 621a10cf76eSAxel Dörfler } 622a10cf76eSAxel Dörfler 623a10cf76eSAxel Dörfler CheckResolutionMenu(); 624a10cf76eSAxel Dörfler CheckColorMenu(); 625a10cf76eSAxel Dörfler CheckRefreshMenu(); 626a10cf76eSAxel Dörfler 627a10cf76eSAxel Dörfler BString string; 628a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 629a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 630a10cf76eSAxel Dörfler 631a10cf76eSAxel Dörfler if (item != NULL) { 632a10cf76eSAxel Dörfler if (!item->IsMarked()) 633a10cf76eSAxel Dörfler item->SetMarked(true); 634a10cf76eSAxel Dörfler } else { 635a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 636a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 637a10cf76eSAxel Dörfler // 1. add a new resolution to list 638a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 639a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 640a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 641a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 642a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 643a10cf76eSAxel Dörfler // 2. choose nearest resolution 644a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 645a10cf76eSAxel Dörfler // 3. choose lowest resolution 646a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 647a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 648a10cf76eSAxel Dörfler if (item) 649a10cf76eSAxel Dörfler item->SetMarked(true); 650a10cf76eSAxel Dörfler 651a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 652a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 653a10cf76eSAxel Dörfler } 654a10cf76eSAxel Dörfler 655a10cf76eSAxel Dörfler // mark active combine mode 656a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 657a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 658a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 659a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 660a10cf76eSAxel Dörfler item->SetMarked(true); 661a10cf76eSAxel Dörfler break; 662a10cf76eSAxel Dörfler } 663a10cf76eSAxel Dörfler } 664a10cf76eSAxel Dörfler 665a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 666a10cf76eSAxel Dörfler 667a10cf76eSAxel Dörfler for (int32 i = kColorSpaceCount; i-- > 0;) { 668a10cf76eSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 669a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(i); 670a10cf76eSAxel Dörfler break; 671a10cf76eSAxel Dörfler } 672a10cf76eSAxel Dörfler } 673a10cf76eSAxel Dörfler 674a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 675a10cf76eSAxel Dörfler item->SetMarked(true); 676a10cf76eSAxel Dörfler 677a10cf76eSAxel Dörfler string.Truncate(0); 678a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 679a10cf76eSAxel Dörfler if (string != fColorsMenu->Superitem()->Label()) 680a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 681a10cf76eSAxel Dörfler 682a10cf76eSAxel Dörfler UpdateMonitorView(); 683a10cf76eSAxel Dörfler UpdateRefreshControl(); 684a10cf76eSAxel Dörfler 685a10cf76eSAxel Dörfler CheckApplyEnabled(); 686a10cf76eSAxel Dörfler } 687a10cf76eSAxel Dörfler 688a10cf76eSAxel Dörfler 689a10cf76eSAxel Dörfler /** reflect active mode in chosen settings */ 690a10cf76eSAxel Dörfler 691a10cf76eSAxel Dörfler void 692a10cf76eSAxel Dörfler ScreenWindow::UpdateActiveMode() 693a10cf76eSAxel Dörfler { 694a10cf76eSAxel Dörfler // usually, this function gets called after a mode 695a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 696a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 697a10cf76eSAxel Dörfler // what kind of mode we actually got 698a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 699a10cf76eSAxel Dörfler fSelected = fActive; 700a10cf76eSAxel Dörfler 701a10cf76eSAxel Dörfler UpdateControls(); 702a10cf76eSAxel Dörfler } 703a10cf76eSAxel Dörfler 704a10cf76eSAxel Dörfler 705a10cf76eSAxel Dörfler void 706a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 707a10cf76eSAxel Dörfler { 708a10cf76eSAxel Dörfler // move window on screen, if necessary 709a10cf76eSAxel Dörfler if (frame.right <= Frame().right 710a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 711a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 712a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 713a10cf76eSAxel Dörfler } 714a10cf76eSAxel Dörfler } 715a10cf76eSAxel Dörfler 716a10cf76eSAxel Dörfler 717a10cf76eSAxel Dörfler void 718a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 719a10cf76eSAxel Dörfler { 720a10cf76eSAxel Dörfler if (fChangingAllWorkspaces) { 721a10cf76eSAxel Dörfler // we're currently changing all workspaces, so there is no need 722a10cf76eSAxel Dörfler // to update the interface 723a10cf76eSAxel Dörfler return; 724a10cf76eSAxel Dörfler } 725a10cf76eSAxel Dörfler 726a10cf76eSAxel Dörfler fScreenMode.Get(fOriginal); 727a10cf76eSAxel Dörfler fScreenMode.UpdateOriginalMode(); 728a10cf76eSAxel Dörfler 729a10cf76eSAxel Dörfler // only override current settings if they have not been changed yet 730a10cf76eSAxel Dörfler if (fSelected == fActive) 731a10cf76eSAxel Dörfler UpdateActiveMode(); 732a10cf76eSAxel Dörfler 7336edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 7346edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 735a10cf76eSAxel Dörfler } 736a10cf76eSAxel Dörfler 737a10cf76eSAxel Dörfler 738a10cf76eSAxel Dörfler void 739a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 740a10cf76eSAxel Dörfler { 741a10cf76eSAxel Dörfler switch (message->what) { 742a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 743a10cf76eSAxel Dörfler CheckApplyEnabled(); 744a10cf76eSAxel Dörfler break; 745a10cf76eSAxel Dörfler 746a10cf76eSAxel Dörfler case POP_WORKSPACE_CHANGED_MSG: 747a10cf76eSAxel Dörfler { 748a10cf76eSAxel Dörfler int32 index; 749a10cf76eSAxel Dörfler if (message->FindInt32("index", &index) == B_OK) 750a10cf76eSAxel Dörfler set_workspace_count(index + 1); 751a10cf76eSAxel Dörfler break; 752a10cf76eSAxel Dörfler } 753a10cf76eSAxel Dörfler 754a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 755a10cf76eSAxel Dörfler { 756a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 757a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 758a10cf76eSAxel Dörfler 759a10cf76eSAxel Dörfler CheckColorMenu(); 760a10cf76eSAxel Dörfler CheckRefreshMenu(); 761a10cf76eSAxel Dörfler 762a10cf76eSAxel Dörfler UpdateMonitorView(); 763a10cf76eSAxel Dörfler UpdateRefreshControl(); 764a10cf76eSAxel Dörfler 765a10cf76eSAxel Dörfler CheckApplyEnabled(); 766a10cf76eSAxel Dörfler break; 767a10cf76eSAxel Dörfler } 768a10cf76eSAxel Dörfler 769a10cf76eSAxel Dörfler case POP_COLORS_MSG: 770a10cf76eSAxel Dörfler { 771a10cf76eSAxel Dörfler message->FindInt32("space", (int32 *)&fSelected.space); 772a10cf76eSAxel Dörfler 773a10cf76eSAxel Dörfler BString string; 774a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 775a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 776a10cf76eSAxel Dörfler 777a10cf76eSAxel Dörfler CheckApplyEnabled(); 778a10cf76eSAxel Dörfler break; 779a10cf76eSAxel Dörfler } 780a10cf76eSAxel Dörfler 781a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 782a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 783a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other" B_UTF8_ELLIPSIS); 784a10cf76eSAxel Dörfler // revert "Other…" label - it might have had a refresh rate prefix 785a10cf76eSAxel Dörfler 786a10cf76eSAxel Dörfler CheckApplyEnabled(); 787a10cf76eSAxel Dörfler break; 788a10cf76eSAxel Dörfler 789a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 790a10cf76eSAxel Dörfler { 791a10cf76eSAxel Dörfler // make sure menu shows something usefull 792a10cf76eSAxel Dörfler UpdateRefreshControl(); 793a10cf76eSAxel Dörfler 794a10cf76eSAxel Dörfler BRect frame(Frame()); 795a10cf76eSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow(BRect(frame.left + 201.0, 796a10cf76eSAxel Dörfler frame.top + 34.0, frame.left + 509.0, frame.top + 169.0), 797a10cf76eSAxel Dörfler int32(fSelected.refresh * 10)); 798a10cf76eSAxel Dörfler fRefreshWindow->Show(); 799a10cf76eSAxel Dörfler break; 800a10cf76eSAxel Dörfler } 801a10cf76eSAxel Dörfler 802a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 803a10cf76eSAxel Dörfler { 804a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 805a10cf76eSAxel Dörfler // select the refresh rate chosen 806a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 807a10cf76eSAxel Dörfler 808a10cf76eSAxel Dörfler UpdateRefreshControl(); 809a10cf76eSAxel Dörfler CheckApplyEnabled(); 810a10cf76eSAxel Dörfler break; 811a10cf76eSAxel Dörfler } 812a10cf76eSAxel Dörfler 813a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 814a10cf76eSAxel Dörfler { 815a10cf76eSAxel Dörfler // new combine mode has bee chosen 816a10cf76eSAxel Dörfler int32 mode; 817a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 818a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 819a10cf76eSAxel Dörfler 820a10cf76eSAxel Dörfler CheckResolutionMenu(); 821a10cf76eSAxel Dörfler CheckApplyEnabled(); 822a10cf76eSAxel Dörfler break; 823a10cf76eSAxel Dörfler } 824a10cf76eSAxel Dörfler 825a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 826a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 827a10cf76eSAxel Dörfler CheckApplyEnabled(); 828a10cf76eSAxel Dörfler break; 829a10cf76eSAxel Dörfler 830a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 831a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 832a10cf76eSAxel Dörfler CheckApplyEnabled(); 833a10cf76eSAxel Dörfler break; 834a10cf76eSAxel Dörfler 835a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 836a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 837a10cf76eSAxel Dörfler CheckApplyEnabled(); 838a10cf76eSAxel Dörfler break; 839a10cf76eSAxel Dörfler 840df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 841c5d80d47SAxel Dörfler be_roster->Launch(kBackgroundsSignature); 842df3f5bacSStephan Aßmus break; 843df3f5bacSStephan Aßmus 844a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 845a10cf76eSAxel Dörfler { 846a10cf76eSAxel Dörfler fSelected.width = 640; 847a10cf76eSAxel Dörfler fSelected.height = 480; 848a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 849a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 850a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 851a10cf76eSAxel Dörfler fSelected.swap_displays = false; 852a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 853a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 854a10cf76eSAxel Dörfler 855a10cf76eSAxel Dörfler UpdateControls(); 856a10cf76eSAxel Dörfler break; 857a10cf76eSAxel Dörfler } 858a10cf76eSAxel Dörfler 859a10cf76eSAxel Dörfler case BUTTON_REVERT_MSG: 860a10cf76eSAxel Dörfler case SET_INITIAL_MODE_MSG: 861a10cf76eSAxel Dörfler fScreenMode.Revert(); 862a10cf76eSAxel Dörfler UpdateActiveMode(); 863a10cf76eSAxel Dörfler break; 864a10cf76eSAxel Dörfler 865a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 866a10cf76eSAxel Dörfler Apply(); 867a10cf76eSAxel Dörfler break; 868a10cf76eSAxel Dörfler 869a10cf76eSAxel Dörfler case MAKE_INITIAL_MSG: { 870a10cf76eSAxel Dörfler // user pressed "keep" in confirmation box; 871a10cf76eSAxel Dörfler // select this mode in dialog and mark it as 872a10cf76eSAxel Dörfler // previous mode; if "all workspaces" is selected, 873a10cf76eSAxel Dörfler // distribute mode to all workspaces 874a10cf76eSAxel Dörfler 875a10cf76eSAxel Dörfler // use the mode that has eventually been set and 876a10cf76eSAxel Dörfler // thus we know to be working; it can differ from 877a10cf76eSAxel Dörfler // the mode selected by user due to hardware limitation 878a10cf76eSAxel Dörfler display_mode newMode; 879a10cf76eSAxel Dörfler BScreen screen(this); 880a10cf76eSAxel Dörfler screen.GetMode(&newMode); 881a10cf76eSAxel Dörfler 882a10cf76eSAxel Dörfler if (fAllWorkspacesItem->IsMarked()) { 883a10cf76eSAxel Dörfler int32 originatingWorkspace; 884a10cf76eSAxel Dörfler 885a10cf76eSAxel Dörfler // the original panel activates each workspace in turn; 886a10cf76eSAxel Dörfler // this is disguisting and there is a SetMode 887a10cf76eSAxel Dörfler // variant that accepts a workspace id, so let's take 888a10cf76eSAxel Dörfler // this one 889a10cf76eSAxel Dörfler originatingWorkspace = current_workspace(); 890a10cf76eSAxel Dörfler 891a10cf76eSAxel Dörfler // well, this "cannot be reverted" message is not 892a10cf76eSAxel Dörfler // entirely true - at least, you can revert it 893a10cf76eSAxel Dörfler // for current workspace; to not overwrite original 894a10cf76eSAxel Dörfler // mode during workspace switch, we use this flag 895a10cf76eSAxel Dörfler fChangingAllWorkspaces = true; 896a10cf76eSAxel Dörfler 897a10cf76eSAxel Dörfler for (int32 i = 0; i < count_workspaces(); i++) { 898a10cf76eSAxel Dörfler if (i != originatingWorkspace) 899a10cf76eSAxel Dörfler screen.SetMode(i, &newMode, true); 900a10cf76eSAxel Dörfler } 901a10cf76eSAxel Dörfler 902a10cf76eSAxel Dörfler fChangingAllWorkspaces = false; 903a10cf76eSAxel Dörfler } 904a10cf76eSAxel Dörfler 905cfa91cc4SAxel Dörfler fScreenMode.UpdateOriginalMode(); 906a10cf76eSAxel Dörfler UpdateActiveMode(); 907a10cf76eSAxel Dörfler break; 908a10cf76eSAxel Dörfler } 909a10cf76eSAxel Dörfler 910a10cf76eSAxel Dörfler default: 911a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 912a10cf76eSAxel Dörfler break; 913a10cf76eSAxel Dörfler } 914a10cf76eSAxel Dörfler } 915a10cf76eSAxel Dörfler 916a10cf76eSAxel Dörfler 917a10cf76eSAxel Dörfler bool 918a10cf76eSAxel Dörfler ScreenWindow::CanApply() const 919a10cf76eSAxel Dörfler { 920a10cf76eSAxel Dörfler if (fAllWorkspacesItem->IsMarked()) 921a10cf76eSAxel Dörfler return true; 922a10cf76eSAxel Dörfler 923a10cf76eSAxel Dörfler return fSelected != fActive; 924a10cf76eSAxel Dörfler } 925a10cf76eSAxel Dörfler 926a10cf76eSAxel Dörfler 927a10cf76eSAxel Dörfler bool 928a10cf76eSAxel Dörfler ScreenWindow::CanRevert() const 929a10cf76eSAxel Dörfler { 930a10cf76eSAxel Dörfler if (fActive != fOriginal) 931a10cf76eSAxel Dörfler return true; 932a10cf76eSAxel Dörfler 933a10cf76eSAxel Dörfler return CanApply(); 934a10cf76eSAxel Dörfler } 935a10cf76eSAxel Dörfler 936a10cf76eSAxel Dörfler 937a10cf76eSAxel Dörfler void 938a10cf76eSAxel Dörfler ScreenWindow::CheckApplyEnabled() 939a10cf76eSAxel Dörfler { 940a10cf76eSAxel Dörfler fApplyButton->SetEnabled(CanApply()); 941a10cf76eSAxel Dörfler fRevertButton->SetEnabled(CanRevert()); 942a10cf76eSAxel Dörfler } 943a10cf76eSAxel Dörfler 944a10cf76eSAxel Dörfler 945a10cf76eSAxel Dörfler void 946a10cf76eSAxel Dörfler ScreenWindow::Apply() 947a10cf76eSAxel Dörfler { 948a10cf76eSAxel Dörfler if (fAllWorkspacesItem->IsMarked()) { 949a10cf76eSAxel Dörfler BAlert *workspacesAlert = new BAlert("WorkspacesAlert", 950a10cf76eSAxel Dörfler "Change all workspaces? This action cannot be reverted.", "Okay", "Cancel", 951a10cf76eSAxel Dörfler NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 952a10cf76eSAxel Dörfler 953a10cf76eSAxel Dörfler if (workspacesAlert->Go() == 1) 954a10cf76eSAxel Dörfler return; 955a10cf76eSAxel Dörfler } 956a10cf76eSAxel Dörfler 95707184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 95807184a9eSAxel Dörfler if (status == B_OK) { 959a10cf76eSAxel Dörfler fActive = fSelected; 960a10cf76eSAxel Dörfler 961a10cf76eSAxel Dörfler // ToDo: only show alert when this is an unknown mode 962a10cf76eSAxel Dörfler BWindow* window = new AlertWindow(this); 963a10cf76eSAxel Dörfler window->Show(); 96407184a9eSAxel Dörfler } else { 96507184a9eSAxel Dörfler char message[256]; 96607184a9eSAxel Dörfler snprintf(message, sizeof(message), 96707184a9eSAxel Dörfler "The screen mode could not be set:\n\t%s\n", screen_errors(status)); 96807184a9eSAxel Dörfler BAlert* alert = new BAlert("Screen Alert", message, "Okay", NULL, NULL, 96907184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 97007184a9eSAxel Dörfler alert->Go(); 971a10cf76eSAxel Dörfler } 97207184a9eSAxel Dörfler } 97307184a9eSAxel Dörfler 974df3f5bacSStephan Aßmus 975df3f5bacSStephan Aßmus void 976df3f5bacSStephan Aßmus ScreenWindow::LayoutControls(uint32 flags) 977df3f5bacSStephan Aßmus { 978df3f5bacSStephan Aßmus // layout the screen box and its controls 979df3f5bacSStephan Aßmus fWorkspaceCountField->ResizeToPreferred(); 980df3f5bacSStephan Aßmus 981df3f5bacSStephan Aßmus float monitorViewHeight = fMonitorView->Bounds().Height(); 982df3f5bacSStephan Aßmus float workspaceFieldHeight = fWorkspaceCountField->Bounds().Height(); 983df3f5bacSStephan Aßmus float backgroundsButtonHeight = fBackgroundsButton->Bounds().Height(); 984df3f5bacSStephan Aßmus 985df3f5bacSStephan Aßmus float screenBoxWidth = fWorkspaceCountField->Bounds().Width() + 20.0; 986df3f5bacSStephan Aßmus float screenBoxHeight = monitorViewHeight + 5.0 987df3f5bacSStephan Aßmus + workspaceFieldHeight + 5.0 988df3f5bacSStephan Aßmus + backgroundsButtonHeight 989df3f5bacSStephan Aßmus + 20.0; 990df3f5bacSStephan Aßmus 991df3f5bacSStephan Aßmus fScreenBox->MoveTo(10.0, 10.0 + fControlsBox->TopBorderOffset()); 992df3f5bacSStephan Aßmus fScreenBox->ResizeTo(screenBoxWidth, screenBoxHeight); 993df3f5bacSStephan Aßmus 994df3f5bacSStephan Aßmus float leftOffset = 10.0; 995df3f5bacSStephan Aßmus float topOffset = 10.0; 996df3f5bacSStephan Aßmus fMonitorView->MoveTo(leftOffset, topOffset); 997df3f5bacSStephan Aßmus fMonitorView->ResizeTo(screenBoxWidth - 20.0, monitorViewHeight); 998df3f5bacSStephan Aßmus fMonitorView->SetResizingMode(B_FOLLOW_ALL); 999df3f5bacSStephan Aßmus topOffset += monitorViewHeight + 5.0; 1000df3f5bacSStephan Aßmus 1001df3f5bacSStephan Aßmus fWorkspaceCountField->MoveTo(leftOffset, topOffset); 1002df3f5bacSStephan Aßmus fWorkspaceCountField->SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 1003df3f5bacSStephan Aßmus topOffset += workspaceFieldHeight + 5.0; 1004df3f5bacSStephan Aßmus 1005df3f5bacSStephan Aßmus fBackgroundsButton->MoveTo(leftOffset, topOffset); 1006df3f5bacSStephan Aßmus fBackgroundsButton->ResizeTo(screenBoxWidth - 20.0, backgroundsButtonHeight); 1007df3f5bacSStephan Aßmus fBackgroundsButton->SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 1008df3f5bacSStephan Aßmus 1009df3f5bacSStephan Aßmus fControlsBox->MoveTo(fScreenBox->Frame().right + 10.0, 10.0); 1010df3f5bacSStephan Aßmus 1011df3f5bacSStephan Aßmus // layout the right side 1012df3f5bacSStephan Aßmus BRect controlsRect = LayoutMenuFields(flags); 1013df3f5bacSStephan Aßmus controlsRect.InsetBy(-10.0, -10.0); 1014df3f5bacSStephan Aßmus // adjust size of controls box and move aligned buttons along 1015df3f5bacSStephan Aßmus float xDiff = controlsRect.right - fControlsBox->Bounds().right; 1016df3f5bacSStephan Aßmus float yDiff = controlsRect.bottom - fControlsBox->Bounds().bottom; 1017df3f5bacSStephan Aßmus if (yDiff < 0.0) { 1018df3f5bacSStephan Aßmus // don't shrink vertically 1019df3f5bacSStephan Aßmus yDiff = 0.0; 1020df3f5bacSStephan Aßmus } 1021df3f5bacSStephan Aßmus 1022df3f5bacSStephan Aßmus fControlsBox->ResizeBy(xDiff, yDiff); 1023df3f5bacSStephan Aßmus 1024df3f5bacSStephan Aßmus // align bottom of boxen 1025df3f5bacSStephan Aßmus float boxBottomDiff = fControlsBox->Frame().bottom - fScreenBox->Frame().bottom; 1026df3f5bacSStephan Aßmus if (boxBottomDiff > 0) 1027df3f5bacSStephan Aßmus fScreenBox->ResizeBy(0.0, boxBottomDiff); 1028df3f5bacSStephan Aßmus else 1029df3f5bacSStephan Aßmus fControlsBox->ResizeBy(0.0, -boxBottomDiff); 1030df3f5bacSStephan Aßmus 1031df3f5bacSStephan Aßmus BRect boxFrame = fScreenBox->Frame() | fControlsBox->Frame(); 1032df3f5bacSStephan Aßmus 1033df3f5bacSStephan Aßmus // layout rest of buttons 1034df3f5bacSStephan Aßmus fDefaultsButton->ResizeToPreferred(); 1035df3f5bacSStephan Aßmus fDefaultsButton->MoveTo(boxFrame.left, boxFrame.bottom + 8); 1036df3f5bacSStephan Aßmus 1037df3f5bacSStephan Aßmus fRevertButton->ResizeToPreferred(); 1038df3f5bacSStephan Aßmus fRevertButton->MoveTo(fDefaultsButton->Frame().right + 10, 1039df3f5bacSStephan Aßmus fDefaultsButton->Frame().top); 1040df3f5bacSStephan Aßmus 1041df3f5bacSStephan Aßmus fApplyButton->ResizeToPreferred(); 1042df3f5bacSStephan Aßmus fApplyButton->MoveTo(boxFrame.right - fApplyButton->Bounds().Width(), 1043df3f5bacSStephan Aßmus fDefaultsButton->Frame().top); 1044df3f5bacSStephan Aßmus 1045df3f5bacSStephan Aßmus ResizeTo(boxFrame.right + 10, fDefaultsButton->Frame().bottom + 10); 1046df3f5bacSStephan Aßmus } 1047df3f5bacSStephan Aßmus 1048df3f5bacSStephan Aßmus 1049df3f5bacSStephan Aßmus static float 1050df3f5bacSStephan Aßmus max_label_width(BMenuField* control, float widestLabel) 1051df3f5bacSStephan Aßmus { 1052df3f5bacSStephan Aßmus float labelWidth = control->StringWidth(control->Label()); 1053df3f5bacSStephan Aßmus if (widestLabel < labelWidth) 1054df3f5bacSStephan Aßmus return labelWidth; 1055df3f5bacSStephan Aßmus return widestLabel; 1056df3f5bacSStephan Aßmus } 1057df3f5bacSStephan Aßmus 1058df3f5bacSStephan Aßmus 1059df3f5bacSStephan Aßmus static BRect 1060df3f5bacSStephan Aßmus stack_and_align_menu_fields(const BList& menuFields) 1061df3f5bacSStephan Aßmus { 1062df3f5bacSStephan Aßmus float widestLabel = 0.0; 1063df3f5bacSStephan Aßmus int32 count = menuFields.CountItems(); 1064df3f5bacSStephan Aßmus for (int32 i = 0; i < count; i++) { 1065df3f5bacSStephan Aßmus BMenuField* menuField = (BMenuField*)menuFields.ItemAtFast(i); 1066df3f5bacSStephan Aßmus widestLabel = max_label_width(menuField, widestLabel); 1067df3f5bacSStephan Aßmus } 1068df3f5bacSStephan Aßmus 1069df3f5bacSStephan Aßmus // add some room (but only if there is text at all) 1070df3f5bacSStephan Aßmus if (widestLabel > 0.0) 1071df3f5bacSStephan Aßmus widestLabel += 5.0; 1072df3f5bacSStephan Aßmus 1073df3f5bacSStephan Aßmus // make all controls the same width 1074df3f5bacSStephan Aßmus float widestField = 0.0; 1075df3f5bacSStephan Aßmus for (int32 i = 0; i < count; i++) { 1076df3f5bacSStephan Aßmus BMenuField* menuField = (BMenuField*)menuFields.ItemAtFast(i); 1077df3f5bacSStephan Aßmus menuField->SetAlignment(B_ALIGN_RIGHT); 1078df3f5bacSStephan Aßmus menuField->SetDivider(widestLabel); 1079df3f5bacSStephan Aßmus menuField->ResizeToPreferred(); 1080df3f5bacSStephan Aßmus widestField = max_c(menuField->Bounds().Width(), widestField); 1081df3f5bacSStephan Aßmus } 1082df3f5bacSStephan Aßmus 1083df3f5bacSStephan Aßmus // layout controls under each other, resize all to size 1084df3f5bacSStephan Aßmus // of largest of them (they could still have different 1085df3f5bacSStephan Aßmus // heights though) 1086df3f5bacSStephan Aßmus BMenuField* topMenuField = (BMenuField*)menuFields.FirstItem(); 1087df3f5bacSStephan Aßmus BPoint leftTop = topMenuField->Frame().LeftTop(); 1088df3f5bacSStephan Aßmus BRect frame = topMenuField->Frame(); 1089df3f5bacSStephan Aßmus 1090df3f5bacSStephan Aßmus for (int32 i = 0; i < count; i++) { 1091df3f5bacSStephan Aßmus BMenuField* menuField = (BMenuField*)menuFields.ItemAtFast(i); 1092df3f5bacSStephan Aßmus menuField->MoveTo(leftTop); 1093df3f5bacSStephan Aßmus float height = menuField->Bounds().Height(); 1094df3f5bacSStephan Aßmus menuField->ResizeTo(widestField, height); 1095df3f5bacSStephan Aßmus frame = frame | menuField->Frame(); 1096df3f5bacSStephan Aßmus leftTop.y += height + 5.0; 1097df3f5bacSStephan Aßmus } 1098df3f5bacSStephan Aßmus 1099df3f5bacSStephan Aßmus return frame; 1100df3f5bacSStephan Aßmus } 1101df3f5bacSStephan Aßmus 1102df3f5bacSStephan Aßmus 1103df3f5bacSStephan Aßmus BRect 1104df3f5bacSStephan Aßmus ScreenWindow::LayoutMenuFields(uint32 flags, bool sideBySide) 1105df3f5bacSStephan Aßmus { 1106df3f5bacSStephan Aßmus BList menuFields; 1107df3f5bacSStephan Aßmus menuFields.AddItem((void*)fResolutionField); 1108df3f5bacSStephan Aßmus menuFields.AddItem((void*)fColorsField); 1109df3f5bacSStephan Aßmus menuFields.AddItem((void*)fRefreshField); 1110df3f5bacSStephan Aßmus 1111df3f5bacSStephan Aßmus BRect frame; 1112df3f5bacSStephan Aßmus 1113df3f5bacSStephan Aßmus if (sideBySide) 1114df3f5bacSStephan Aßmus frame = stack_and_align_menu_fields(menuFields); 1115df3f5bacSStephan Aßmus 1116df3f5bacSStephan Aßmus if (sideBySide) 1117df3f5bacSStephan Aßmus menuFields.MakeEmpty(); 1118df3f5bacSStephan Aßmus 1119df3f5bacSStephan Aßmus if (flags & SHOW_COMBINE_FIELD) 1120df3f5bacSStephan Aßmus menuFields.AddItem((void*)fCombineField); 1121df3f5bacSStephan Aßmus if (flags & SHOW_SWAP_FIELD) 1122df3f5bacSStephan Aßmus menuFields.AddItem((void*)fSwapDisplaysField); 1123df3f5bacSStephan Aßmus if (flags & SHOW_LAPTOP_PANEL_FIELD) 1124df3f5bacSStephan Aßmus menuFields.AddItem((void*)fUseLaptopPanelField); 1125df3f5bacSStephan Aßmus if (flags & SHOW_TV_STANDARD_FIELD) 1126df3f5bacSStephan Aßmus menuFields.AddItem((void*)fTVStandardField); 1127df3f5bacSStephan Aßmus 1128df3f5bacSStephan Aßmus if (sideBySide) { 1129df3f5bacSStephan Aßmus if (menuFields.CountItems() > 0) { 1130df3f5bacSStephan Aßmus ((BMenuField*)menuFields.FirstItem())->MoveTo(frame.right + 8.0, frame.top); 1131df3f5bacSStephan Aßmus frame = frame | stack_and_align_menu_fields(menuFields); 1132df3f5bacSStephan Aßmus } 1133df3f5bacSStephan Aßmus } else { 1134df3f5bacSStephan Aßmus frame = stack_and_align_menu_fields(menuFields); 1135df3f5bacSStephan Aßmus } 1136df3f5bacSStephan Aßmus 1137df3f5bacSStephan Aßmus return frame; 1138df3f5bacSStephan Aßmus } 1139df3f5bacSStephan Aßmus 1140