📄 screenwindow.cpp
字号:
msg->AddBool( "use", false ); item = new BMenuItem( "if needed", msg ); fUseLaptopPanelMenu->AddItem( item ); msg = new BMessage( POP_USE_LAPTOP_PANEL_MSG ); msg->AddBool( "use", true ); item = new BMenuItem( "always", msg ); fUseLaptopPanelMenu->AddItem( item ); rect.Set( 184, 86, 356, 104 ); menuField = new BMenuField( rect, "UseLaptopPanel", "Use Laptop Panel:", fUseLaptopPanelMenu, true ); menuField->SetDivider( 91 ); fControlsBox->AddChild( menuField ); if( !useLaptopPanelSupport ) menuField->Hide(); fTVStandardMenu = new BPopUpMenu( "TVStandard", true, true ); // arbitrary limit for( i = 0; i < 100; ++i ) { uint32 mode; if( GetNthSupportedTVStandard( &screen, i, &mode ) != B_OK ) break; BString name = TVStandard2Name( mode ); BMessage *msg; msg = new BMessage( POP_TV_STANDARD_MSG ); msg->AddInt32( "tv_standard", mode ); fTVStandardMenu->AddItem( new BMenuItem( name.String(), msg )); } rect.Set( 15, 114, 171, 132 ); menuField = new BMenuField( rect, "TVStandard", "Video Format:", fTVStandardMenu, true ); menuField->SetDivider( 73 ); fControlsBox->AddChild( menuField ); if( !tvStandardSupport || i == 0 ) menuField->Hide(); } ButtonRect.Set(10.0, 167, 100.0, 200.0); fDefaultsButton = new BButton(ButtonRect, "DefaultsButton", "Defaults", new BMessage(BUTTON_DEFAULTS_MSG)); fDefaultsButton->AttachedToWindow(); fDefaultsButton->ResizeToPreferred(); view->AddChild(fDefaultsButton); ButtonRect.Set(95.0, 167, 160.0, 200.0); fRevertButton = new BButton(ButtonRect, "RevertButton", "Revert", new BMessage(BUTTON_REVERT_MSG)); fRevertButton->AttachedToWindow(); fRevertButton->ResizeToPreferred(); fRevertButton->SetEnabled(false); view->AddChild(fRevertButton); fOrigSwapDisplays = false; GetSwapDisplays( &screen, &fOrigSwapDisplays ); fOrigUseLaptopPanel = false; GetUseLaptopPanel( &screen, &fOrigUseLaptopPanel ); fOrigTVStandard = 0; GetTVStandard( &screen, &fOrigTVStandard ); screen.GetMode( &fOrigMode ); ReflectActiveMode(); Show();}ScreenWindow::~ScreenWindow(){ delete fSettings;}// get refresh rate of mode in 1/10 Hz (this accuracy is used everywhere)int ScreenWindow::getModeRefresh10( display_mode *mode ){ float fRefresh; int refresh10; // we have to be catious as refresh rate cannot be controlled directly, // so it suffers under rounding errors and hardware restrictions fRefresh = float(mode->timing.pixel_clock * 1000) / float(mode->timing.h_total * mode->timing.v_total); refresh10 = (int)rint( fRefresh * 10 ); return refresh10;}// update resolution list according to combine mode// (some resolution may not be combinable due to memory restrictions)void ScreenWindow::UpdateResolutions( CombineMode combine ){ for( int i = 0; i < fResolutionMenu->CountItems(); ++i ) fResolutionMenu->ItemAt( i )->SetEnabled( false ); for( uint j = 0; j < fModeListCount; ++j ) { uint16 width, height; BMenuItem *item; if( getCombineMode( &fModeList[j] ) != combine ) continue; width = fModeList[j].virtual_width; height = fModeList[j].virtual_height; BString name; name << (uint)(combine == cb_horizontally ? width / 2 : width) << " x " << (uint)(combine == cb_vertically ? height / 2 : height); item = fResolutionMenu->FindItem( name.String() ); if( item != NULL ) item->SetEnabled( true ); }}// update bpp and refresh options according to current mode// (a colour space is made active if there is any mode with // given resolution and this colour space; same applies for // refresh rate, though "other..." is always possible)void ScreenWindow::UpdateModeOptions( int width, int height, CombineMode combine ){ uint i, j; uint16 virtual_width, virtual_height; virtual_width = combine == cb_horizontally ? width * 2 : width; virtual_height = combine == cb_vertically ? height * 2 : height; for( i = 0; i < sizeof( bpp_list ) / sizeof( bpp_list[0] ); ++i ) { BMenuItem *item; bool supported = false; for( j = 0; j < fModeListCount; ++j ) { if( virtual_width == fModeList[j].virtual_width && virtual_height == fModeList[j].virtual_height && bpp_list[i].space == fModeList[j].space && combine == getCombineMode( &fModeList[j] )) { supported = true; break; } } item = fColorsMenu->ItemAt( i ); if( item ) item->SetEnabled( supported ); } #ifndef USE_FIXED_REFRESH for( i = fRefreshMenu->CountItems() - 2; i >= 0; --i ) { BMenuItem *item; item = fRefreshMenu->RemoveItem( i ); if( item ) delete item; } for( i = 0; i < fModeListCount; ++i ) { if( virtual_width == fModeList[i].virtual_width && virtual_width == fModeList[i].virtual_height && combine == getCombineMode( &fModeList[i] )) { BString name; BMenuItem *item; int refresh10; refresh10 = getModeRefresh10( &fModeList[i] ); name << Refresh2Text( refresh10, false ) << " Hz"; item = fRefreshMenu->FindItem( name.String() ); if( item == NULL ) { BMessage *msg; msg = new BMessage( POP_REFRESH_MSG ); msg->AddInt32( "refresh10", refresh10 ); fRefreshMenu->AddItem( new BMenuItem( name.String(), msg ), fRefreshMenu->CountItems() - 1 ); } } }#endif // TBD: some drivers lack many refresh rates; still, they // can be used by generating the mode manually/* for( i = 0; i < sizeof( refresh_list ) / sizeof( refresh_list[0] ); ++i ) { BMenuItem *item; bool supported = false; for( j = 0; j < fModeListCount; ++j ) { if( width == fModeList[j].virtual_width && height == fModeList[j].virtual_height && refresh_list[i].refresh * 10 == getModeRefresh10( &fModeList[j] )) { supported = true; break; } } item = fRefreshMenu->ItemAt( i ); if( item ) item->SetEnabled( supported ); }*/}BString ScreenWindow::Refresh2Text( int refresh10, bool always_with_fraction ){ if( always_with_fraction || refresh10 % 10 != 0 ) { char buffer[100]; // I always distrust sprintf, especially with // floating point (if refresh10 is something like 1e4000, // we get a *very* long output; as refresh10 is int, i.e. // in [-2e9,2e9], the result should consist of up to // 8 significant digits and 1 fractional digit, altogether // 12 character; anyway - I don't trust these estimations, // something link snprintf made me sleep more easily) sprintf( buffer, "%3.1f", refresh10 / 10.0 ); return buffer; } else { BString str; str << refresh10 / 10; return str; }}// activate appropriate menu item according to selected refresh ratevoid ScreenWindow::ReflectSelectedRefresh(){ BString str, str2; BMenuItem *item; item = NULL; // try to find refresh rate in list of standard refreshes/* // (don't do that if refresh has fractional part as this // gets discarded before searching) if( fSelectedRefresh10 % 10 == 0 ) { // we are lazy and ask refresh menu directly instead of // going through refresh_list str.Truncate( 0 ); str << fSelectedRefresh10 / 10 << " Hz"; item = fRefreshMenu->FindItem( str.String() ); }*/ str2 = Refresh2Text( fSelectedRefresh10, false ); str.Truncate( 0 ); str << str2 << " Hz"; item = fRefreshMenu->FindItem( str.String() ); if( item ) { item->SetMarked( true ); // "Other..." items only contains a refresh rate when active fOtherRefresh->SetLabel( "Other..." ); return; } // this is a non-standard refresh rate fOtherRefresh->Message()->ReplaceInt32( "refresh10", (int)fSelectedRefresh10 ); str2 = Refresh2Text( fSelectedRefresh10, true ); str.Truncate( 0 ); str << str2 << " Hz/Other..."; fOtherRefresh->SetLabel( str.String() ); fOtherRefresh->SetMarked( true ); // we don't want this "Other..." appear in menu label str.Truncate( 0 ); str << str2 << " Hz"; fRefreshMenu->Superitem()->SetLabel( str.String() );}void ScreenWindow::ReflectSelectedResolution(){ BMessage *Message = new BMessage(UPDATE_DESKTOP_MSG); Message->AddInt32( "width", fSelectedWidth ); Message->AddInt32( "height", fSelectedHeight ); PostMessage( Message, fScreenDrawView );}// reflect active mode in chosen settingsvoid ScreenWindow::ReflectActiveMode(){ BScreen screen( this ); display_mode mode; BString str; BMenuItem *item; int i; // usually, this function gets called after a mode // has been set manually; still, as the graphics driver // is free to fiddle with mode passed, we better ask // what kind of mode we actually got screen.GetMode( &mode ); fActiveMode = mode; fActiveWidth = mode.virtual_width; fActiveHeight = mode.virtual_height; fSelectedSpace = fActiveSpace = mode.space; fSelectedRefresh10 = fActiveRefresh10 = getModeRefresh10( &mode ); fSelectedCombineMode = fActiveCombineMode = getCombineMode( &mode ); if( fActiveCombineMode == cb_horizontally ) fActiveWidth /= 2; if( fActiveCombineMode == cb_vertically ) fActiveHeight /= 2; fSelectedWidth = fActiveWidth; fSelectedHeight = fActiveHeight; // assign some value so we GetSwapDisplays,... can fail silently // (else, "Apply" and "Revert" is always enabled if SwapDisplay-variables differ) fActiveSwapDisplays = fOrigSwapDisplays; GetSwapDisplays( &screen, &fActiveSwapDisplays ); fSelectedSwapDisplays = fActiveSwapDisplays; fActiveUseLaptopPanel = fOrigUseLaptopPanel; GetUseLaptopPanel( &screen, &fActiveUseLaptopPanel ); fSelectedUseLaptopPanel = fActiveUseLaptopPanel; fActiveTVStandard = fOrigTVStandard; GetTVStandard( &screen, &fActiveTVStandard ); fSelectedTVStandard = fActiveTVStandard; item = fSwapDisplaysMenu->ItemAt( fSelectedSwapDisplays ); if( item ) item->SetMarked( true ); item = fUseLaptopPanelMenu->ItemAt( fSelectedUseLaptopPanel ); if( item ) item->SetMarked( true ); for( i = 0; i < fTVStandardMenu->CountItems(); ++i ) { uint32 cur_tv_standard; item = fTVStandardMenu->ItemAt( i ); item->Message()->FindInt32( "tv_standard", (int32 *)&cur_tv_standard ); if( cur_tv_standard == fSelectedTVStandard ) { item->SetMarked( true ); break; } } UpdateResolutions( fActiveCombineMode ); UpdateModeOptions( fActiveWidth, fActiveHeight, fActiveCombineMode ); str.Truncate( 0 ); str << (uint)fActiveWidth << " x " << (uint)fActiveHeight; item = fResolutionMenu->FindItem( str.String() ); /*item = NULL; for( i = 0; i < fResolutionMenu->CountItems(); ++i ) { BMenuItem *cur_item; BMessage *msg; int32 tmp_width, tmp_height; cur_item = fResolutionMenu->ItemAt( i ); msg = cur_item->Message(); if( msg->FindInt32( "width", &tmp_width ) != B_OK || msg->FindInt32( "height", &tmp_height ) != B_OK ) continue; if( fActiveWidth == mode.virtual_width && fActiveHeight == mode.virtual_height ) { item = cur_item; break; } }*/ if( item != NULL ) { item->SetMarked( true ); } else { // this is bad luck - if mode has been set via screen references, // this case cannot occur; there are three possible solutions: // 1. add a new resolution to list // - we had to remove it as soon as a "valid" one is selected // - we don't know which frequencies/bit depths are supported // - as long as we haven't the GMT formula to create // parameters for any resolution given, we cannot // really set current mode - it's just not in the list // 2. choose nearest resolution // - probably a good idea, but implies coding and testing // 3. choose lowest resolution // - do you really think we are so lazy? yes, we are item = fResolutionMenu->ItemAt( 0 ); if( item ) item->SetMarked( true ); // okay - at least we set menu label to active resolution fResolutionMenu->Superitem()->SetLabel( str.String() ); } // mark active combine mode for( i = 0; (uint)i < sizeof( combine_list ) / sizeof( combine_list[0] ); ++i ) if( combine_list[i].mode == fActiveCombineMode ) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -