From c2227feb1e1b34c9d9a7025e16fb8ac30302fde6 Mon Sep 17 00:00:00 2001 From: stippi Date: Tue, 4 May 2010 21:54:10 +0000 Subject: [PATCH] Implemented an "auto-hide the interface" feature for the full-screen mode. The mouse cursor will automatically hide if you don't move it, unless it's over the interface. The interface will disappear after three seconds if the cursor is not above it. It will re-appear when you touch the top of the screen with the mouse. I find this the best solution, since the mouse is also used for navigation in the page, and showing the interface based on some virtual area of the interface would just get in the way. git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@485 94f232f2-1747-11df-bad5-a5bfde151594 --- src/apps/webpositive/BrowserWindow.cpp | 209 +++++++++++++++++++------ src/apps/webpositive/BrowserWindow.h | 43 +++-- src/apps/webpositive/SettingsKeys.cpp | 3 + src/apps/webpositive/SettingsKeys.h | 2 + 4 files changed, 192 insertions(+), 65 deletions(-) diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index 173f947577..68febf2eff 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -78,31 +79,33 @@ enum { - OPEN_LOCATION = 'open', - GO_BACK = 'goba', - GO_FORWARD = 'gofo', - STOP = 'stop', - GOTO_URL = 'goul', - RELOAD = 'reld', - CLEAR_HISTORY = 'clhs', + OPEN_LOCATION = 'open', + GO_BACK = 'goba', + GO_FORWARD = 'gofo', + STOP = 'stop', + GOTO_URL = 'goul', + RELOAD = 'reld', + CLEAR_HISTORY = 'clhs', - CREATE_BOOKMARK = 'crbm', - SHOW_BOOKMARKS = 'shbm', + CREATE_BOOKMARK = 'crbm', + SHOW_BOOKMARKS = 'shbm', - ZOOM_FACTOR_INCREASE = 'zfin', - ZOOM_FACTOR_DECREASE = 'zfdc', - ZOOM_FACTOR_RESET = 'zfrs', - ZOOM_TEXT_ONLY = 'zfto', + ZOOM_FACTOR_INCREASE = 'zfin', + ZOOM_FACTOR_DECREASE = 'zfdc', + ZOOM_FACTOR_RESET = 'zfrs', + ZOOM_TEXT_ONLY = 'zfto', - TOGGLE_FULLSCREEN = 'tgfs', + TOGGLE_FULLSCREEN = 'tgfs', + TOGGLE_AUTO_HIDE_INTERFACE_IN_FULLSCREEN = 'tgah', + CHECK_AUTO_HIDE_INTERFACE = 'cahi', - EDIT_SHOW_FIND_GROUP = 'sfnd', - EDIT_HIDE_FIND_GROUP = 'hfnd', - EDIT_FIND_NEXT = 'fndn', - EDIT_FIND_PREVIOUS = 'fndp', - FIND_TEXT_CHANGED = 'ftxt', + EDIT_SHOW_FIND_GROUP = 'sfnd', + EDIT_HIDE_FIND_GROUP = 'hfnd', + EDIT_FIND_NEXT = 'fndn', + EDIT_FIND_PREVIOUS = 'fndp', + FIND_TEXT_CHANGED = 'ftxt', - SELECT_TAB = 'sltb', + SELECT_TAB = 'sltb', }; @@ -188,15 +191,18 @@ private: BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, - const BString& url, ToolbarPolicy toolbarPolicy, BWebView* webView) + const BString& url, uint32 interfaceElements, BWebView* webView) : BWebWindow(frame, kApplicationName, B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS), fIsFullscreen(false), + fPulseRunner(NULL), + fVisibleInterfaceElements(interfaceElements), fAppSettings(appSettings), fZoomTextOnly(true), - fShowTabsIfSinglePageOpen(true) + fShowTabsIfSinglePageOpen(true), + fAutoHideInterfaceInFullscreenMode(false) { // Begin listening to settings changes and read some current values. fAppSettings->AddListener(BMessenger(this)); @@ -284,6 +290,10 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, fFullscreenItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULLSCREEN), B_RETURN); menu->AddItem(fFullscreenItem); + fAutoHideInterfaceInFullscreenItem = new BMenuItem("Auto hide interface " + "in fullscreen mode", + new BMessage(TOGGLE_AUTO_HIDE_INTERFACE_IN_FULLSCREEN)); + menu->AddItem(fAutoHideInterfaceInFullscreenItem); mainMenu->AddItem(menu); @@ -371,11 +381,15 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) ; - BView* statusGroup = BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing) - .Add(fStatusText) - .Add(fLoadingProgressBar, 0.2) - .AddStrut(12 - kElementSpacing) - .SetInsets(kInsetSpacing, 0, kInsetSpacing, 0) + // Status bar group + BView* statusGroup = BGroupLayoutBuilder(B_VERTICAL) + .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) + .Add(BGroupLayoutBuilder(B_HORIZONTAL, kElementSpacing) + .Add(fStatusText) + .Add(fLoadingProgressBar, 0.2) + .AddStrut(12 - kElementSpacing) + .SetInsets(kInsetSpacing, 0, kInsetSpacing, 0) + ) ; BitmapButton* toggleFullscreenButton = new BitmapButton(kWindowIconBits, @@ -383,19 +397,20 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, new BMessage(TOGGLE_FULLSCREEN)); toggleFullscreenButton->SetBackgroundMode(BitmapButton::MENUBAR_BACKGROUND); + BView* menuBarGroup = BGroupLayoutBuilder(B_HORIZONTAL) + .Add(mainMenu) + .Add(toggleFullscreenButton, 0.0f) + ; + // Layout AddChild(BGroupLayoutBuilder(B_VERTICAL) #if !INTEGRATE_MENU_INTO_TAB_BAR - .Add(BGroupLayoutBuilder(B_HORIZONTAL) - .Add(mainMenu) - .Add(toggleFullscreenButton, 0.0f) - ) + .Add(menuBarGroup) #endif .Add(fTabManager->TabGroup()) .Add(navigationGroup) .Add(fTabManager->ContainerView()) .Add(findGroup) - .Add(new BSeparatorView(B_HORIZONTAL, B_PLAIN_BORDER)) .Add(statusGroup) ); @@ -405,7 +420,7 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, fURLInputGroup->MakeFocus(true); - fMenuGroup = layoutItemFor(mainMenu); + fMenuGroup = layoutItemFor(menuBarGroup); fTabGroup = layoutItemFor(fTabManager->TabGroup()); fNavigationGroup = layoutItemFor(navigationGroup); fFindGroup = layoutItemFor(findGroup); @@ -416,14 +431,10 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, fToggleFullscreenButton->SetVisible(false); CreateNewTab(url, true, webView); - - if (toolbarPolicy == DoNotHaveToolbar) { -#if !INTEGRATE_MENU_INTO_TAB_BAR - fMenuGroup->SetVisible(false); -#endif - fTabGroup->SetVisible(false); - fNavigationGroup->SetVisible(false); - } + _ShowInterface(true); + _SetAutoHideInterfaceInFullscreen(fAppSettings->GetValue( + kAutoHideInterfaceInFullscreenMode, + fAutoHideInterfaceInFullscreenMode)); AddShortcut('F', B_COMMAND_KEY | B_SHIFT_KEY, new BMessage(EDIT_HIDE_FIND_GROUP)); @@ -447,6 +458,7 @@ BrowserWindow::~BrowserWindow() { fAppSettings->RemoveListener(BMessenger(this)); delete fTabManager; + delete fPulseRunner; } @@ -482,6 +494,13 @@ BrowserWindow::DispatchMessage(BMessage* message, BHandler* target) } } } + if (message->what == B_MOUSE_MOVED || message->what == B_MOUSE_DOWN + || message->what == B_MOUSE_UP) { + message->FindPoint("where", &fLastMousePos); + if (message->FindInt64("when", &fLastMouseMovedTime) != B_OK) + fLastMouseMovedTime = system_time(); + _CheckAutoHideInterface(); + } BWebWindow::DispatchMessage(message, target); } @@ -629,6 +648,15 @@ BrowserWindow::MessageReceived(BMessage* message) _ToggleFullscreen(); break; + case TOGGLE_AUTO_HIDE_INTERFACE_IN_FULLSCREEN: + _SetAutoHideInterfaceInFullscreen( + !fAutoHideInterfaceInFullscreenMode); + break; + + case CHECK_AUTO_HIDE_INTERFACE: + _CheckAutoHideInterface(); + break; + case EDIT_FIND_NEXT: CurrentWebView()->FindString(fFindTextControl->Text(), true, fFindCaseSensitiveCheckBox->Value()); @@ -758,6 +786,9 @@ BrowserWindow::MessageReceived(BMessage* message) } else if (name == kSettingsKeyNewTabPolicy && message->FindUInt32("value", &value) == B_OK) { fNewTabPolicy = value; + } else if (name == kAutoHideInterfaceInFullscreenMode + && message->FindBool("value", &flag) == B_OK) { + _SetAutoHideInterfaceInFullscreen(flag); } break; } @@ -960,7 +991,7 @@ BrowserWindow::NewPageCreated(BWebView* view, BRect windowFrame, { if (windowFrame.IsValid()) { BrowserWindow* window = new BrowserWindow(windowFrame, fAppSettings, - BString(), DoNotHaveToolbar, view); + BString(), INTERFACE_ELEMENT_STATUS, view); window->Show(); } else CreateNewTab(BString(), activate, view); @@ -1016,13 +1047,11 @@ BrowserWindow::LoadProgress(float progress, BWebView* view) if (view != CurrentWebView()) return; - if (fLoadingProgressBar) { - if (progress < 100 && fLoadingProgressBar->IsHidden()) - fLoadingProgressBar->Show(); - else if (progress == 100 && !fLoadingProgressBar->IsHidden()) - fLoadingProgressBar->Hide(); - fLoadingProgressBar->SetTo(progress); - } + if (progress < 100 && fLoadingProgressBar->IsHidden()) + fLoadingProgressBar->Show(); + else if (progress == 100 && !fLoadingProgressBar->IsHidden()) + fLoadingProgressBar->Hide(); + fLoadingProgressBar->SetTo(progress); } @@ -1035,7 +1064,7 @@ BrowserWindow::LoadFailed(const BString& url, BWebView* view) BString status(url); status << " failed."; view->WebPage()->SetStatusMessage(status); - if (fLoadingProgressBar && !fLoadingProgressBar->IsHidden()) + if (!fLoadingProgressBar->IsHidden()) fLoadingProgressBar->Hide(); } @@ -1049,7 +1078,7 @@ BrowserWindow::LoadFinished(const BString& url, BWebView* view) BString status(url); status << " finished."; view->WebPage()->SetStatusMessage(status); - if (fLoadingProgressBar && !fLoadingProgressBar->IsHidden()) + if (!fLoadingProgressBar->IsHidden()) fLoadingProgressBar->Hide(); NavigationCapabilitiesChanged(fBackButton->IsEnabled(), @@ -1753,6 +1782,8 @@ BrowserWindow::_ToggleFullscreen() SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); SetLook(B_DOCUMENT_WINDOW_LOOK); + + _ShowInterface(true); } else { fNonFullscreenWindowFrame = Frame(); _ResizeToScreen(); @@ -1774,3 +1805,79 @@ BrowserWindow::_ResizeToScreen() ResizeTo(screen.Frame().Width(), screen.Frame().Height()); } + +void +BrowserWindow::_SetAutoHideInterfaceInFullscreen(bool doIt) +{ + if (fAutoHideInterfaceInFullscreenMode == doIt) + return; + + fAutoHideInterfaceInFullscreenMode = doIt; + fAutoHideInterfaceInFullscreenItem->SetMarked(doIt); + if (fAppSettings->GetValue(kAutoHideInterfaceInFullscreenMode, doIt) + != doIt) { + fAppSettings->SetValue(kAutoHideInterfaceInFullscreenMode, doIt); + } + + if (fAutoHideInterfaceInFullscreenMode) { + BMessage message(CHECK_AUTO_HIDE_INTERFACE); + fPulseRunner = new BMessageRunner(BMessenger(this), &message, 300000); + } else { + delete fPulseRunner; + fPulseRunner = NULL; + } +} + + +void +BrowserWindow::_CheckAutoHideInterface() +{ + if (!fIsFullscreen || !fAutoHideInterfaceInFullscreenMode) + return; + + bigtime_t now = system_time(); + float navigationGroupBottom = fNavigationGroup->IsVisible() ? + fNavigationGroup->Frame().bottom : 0; + if (fLastMousePos.y > navigationGroupBottom + && now - fLastMouseMovedTime > 1500000) { + be_app->ObscureCursor(); + } + + if (fLastMousePos.y == 0) + _ShowInterface(true); + else if (fNavigationGroup->IsVisible() + && fLastMousePos.y > fNavigationGroup->Frame().bottom + && now - fLastMouseMovedTime > 3000000) { + // NOTE: Do not re-use navigationGroupBottom in the above + // check, since we only want to hide the interface when it is visible. + _ShowInterface(false); + } +} + + +void +BrowserWindow::_ShowInterface(bool show) +{ + if (show) { +#if !INTEGRATE_MENU_INTO_TAB_BAR + fMenuGroup->SetVisible( + (fVisibleInterfaceElements & INTERFACE_ELEMENT_MENU) != 0); +#endif + fTabGroup->SetVisible( + (fVisibleInterfaceElements & INTERFACE_ELEMENT_TABS) != 0); + fNavigationGroup->SetVisible( + (fVisibleInterfaceElements & INTERFACE_ELEMENT_NAVIGATION) != 0); + fStatusGroup->SetVisible( + (fVisibleInterfaceElements & INTERFACE_ELEMENT_STATUS) != 0); + } else { + fMenuGroup->SetVisible(false); + fTabGroup->SetVisible(false); + fNavigationGroup->SetVisible(false); + fStatusGroup->SetVisible(false); + } + // TODO: Setting the group visible seems to unhide the status bar. + // Fix in Haiku? + if (!fLoadingProgressBar->IsHidden()) + fLoadingProgressBar->Hide(); +} + diff --git a/src/apps/webpositive/BrowserWindow.h b/src/apps/webpositive/BrowserWindow.h index c7d230c2f0..8956bffa2d 100644 --- a/src/apps/webpositive/BrowserWindow.h +++ b/src/apps/webpositive/BrowserWindow.h @@ -41,6 +41,7 @@ class BFile; class BLayoutItem; class BMenu; class BMenuItem; +class BMessageRunner; class BPath; class BStatusBar; class BStringView; @@ -51,25 +52,29 @@ class SettingsMessage; class TabManager; class URLInputGroup; -enum ToolbarPolicy { - HaveToolbar, - DoNotHaveToolbar +enum { + INTERFACE_ELEMENT_MENU = 1 << 0, + INTERFACE_ELEMENT_TABS = 1 << 1, + INTERFACE_ELEMENT_NAVIGATION = 1 << 2, + INTERFACE_ELEMENT_STATUS = 1 << 3, + + INTERFACE_ELEMENT_ALL = 0xffff }; enum NewPagePolicy { - OpenBlankPage = 0, - OpenStartPage = 1, - OpenSearchPage = 2, - CloneCurrentPage = 3 + OpenBlankPage = 0, + OpenStartPage = 1, + OpenSearchPage = 2, + CloneCurrentPage = 3 }; enum { - NEW_WINDOW = 'nwnd', - NEW_TAB = 'ntab', - WINDOW_OPENED = 'wndo', - WINDOW_CLOSED = 'wndc', - SHOW_DOWNLOAD_WINDOW = 'sdwd', - SHOW_SETTINGS_WINDOW = 'sswd' + NEW_WINDOW = 'nwnd', + NEW_TAB = 'ntab', + WINDOW_OPENED = 'wndo', + WINDOW_CLOSED = 'wndc', + SHOW_DOWNLOAD_WINDOW = 'sdwd', + SHOW_SETTINGS_WINDOW = 'sswd' }; #define INTEGRATE_MENU_INTO_TAB_BAR 0 @@ -80,7 +85,8 @@ public: BrowserWindow(BRect frame, SettingsMessage* appSettings, const BString& url, - ToolbarPolicy = HaveToolbar, + uint32 interfaceElements + = INTERFACE_ELEMENT_ALL, BWebView* webView = NULL); virtual ~BrowserWindow(); @@ -172,6 +178,9 @@ private: void _ToggleFullscreen(); void _ResizeToScreen(); + void _SetAutoHideInterfaceInFullscreen(bool doIt); + void _CheckAutoHideInterface(); + void _ShowInterface(bool show); private: BMenu* fHistoryMenu; @@ -184,6 +193,7 @@ private: BMenuItem* fFindNextMenuItem; BMenuItem* fZoomTextOnlyMenuItem; BMenuItem* fFullscreenItem; + BMenuItem* fAutoHideInterfaceInFullscreenItem; BMenuItem* fBackMenuItem; BMenuItem* fForwardMenuItem; @@ -207,11 +217,16 @@ private: bool fIsFullscreen; BRect fNonFullscreenWindowFrame; + BMessageRunner* fPulseRunner; + uint32 fVisibleInterfaceElements; + bigtime_t fLastMouseMovedTime; + BPoint fLastMousePos; // cached settings SettingsMessage* fAppSettings; bool fZoomTextOnly; bool fShowTabsIfSinglePageOpen; + bool fAutoHideInterfaceInFullscreenMode; uint32 fNewWindowPolicy; uint32 fNewTabPolicy; BString fStartPageURL; diff --git a/src/apps/webpositive/SettingsKeys.cpp b/src/apps/webpositive/SettingsKeys.cpp index d525ba6aeb..f9e3de942f 100644 --- a/src/apps/webpositive/SettingsKeys.cpp +++ b/src/apps/webpositive/SettingsKeys.cpp @@ -45,3 +45,6 @@ const char* kDefaultSearchPageURL = "http://www.google.com"; const char* kSettingsKeyUseProxy = "use http proxy"; const char* kSettingsKeyProxyAddress = "http proxy address"; const char* kSettingsKeyProxyPort = "http proxy port"; + +const char* kAutoHideInterfaceInFullscreenMode + = "auto hide interface in full screen mode"; diff --git a/src/apps/webpositive/SettingsKeys.h b/src/apps/webpositive/SettingsKeys.h index 6be0e5e15c..87abb6be7d 100644 --- a/src/apps/webpositive/SettingsKeys.h +++ b/src/apps/webpositive/SettingsKeys.h @@ -46,4 +46,6 @@ extern const char* kSettingsKeyUseProxy; extern const char* kSettingsKeyProxyAddress; extern const char* kSettingsKeyProxyPort; +extern const char* kAutoHideInterfaceInFullscreenMode; + #endif // SETTINGS_KEYS_H