The menus work a bit less good now I think, but they no longer have 100% CPU usage
when the menu item under the mouse cursor has a sub-menu. Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16160 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+21
-21
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2005, Haiku, Inc.
|
* Copyright 2001-2006, Haiku, Inc.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
* Stefano Ceccherini ([email protected])
|
* Stefano Ceccherini ([email protected])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <Debug.h>
|
#include <Debug.h>
|
||||||
@@ -1110,22 +1111,23 @@ BMenu::_track(int *action, long start)
|
|||||||
ulong buttons;
|
ulong buttons;
|
||||||
BMenuItem *item = NULL;
|
BMenuItem *item = NULL;
|
||||||
int localAction = MENU_ACT_NONE;
|
int localAction = MENU_ACT_NONE;
|
||||||
|
|
||||||
bigtime_t startTime = system_time();
|
bigtime_t startTime = system_time();
|
||||||
bigtime_t clickTime = 0;
|
bigtime_t clickTime = 0;
|
||||||
get_click_speed(&clickTime);
|
get_click_speed(&clickTime);
|
||||||
|
|
||||||
// TODO: Test and reduce the timeout if needed.
|
// TODO: Test and reduce the timeout if needed.
|
||||||
clickTime /= 2;
|
clickTime /= 2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!LockLooper())
|
if (!LockLooper())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bigtime_t snoozeAmount = 50000;
|
bigtime_t snoozeAmount = 50000;
|
||||||
BPoint location;
|
BPoint location;
|
||||||
GetMouse(&location, &buttons, true);
|
GetMouse(&location, &buttons, true);
|
||||||
|
BPoint screenLocation = ConvertToScreen(location);
|
||||||
|
|
||||||
item = HitTestItems(location, B_ORIGIN);
|
item = HitTestItems(location, B_ORIGIN);
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
if (item != fSelected) {
|
if (item != fSelected) {
|
||||||
@@ -1140,18 +1142,18 @@ BMenu::_track(int *action, long start)
|
|||||||
SelectItem(item);
|
SelectItem(item);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (OverSuper(location)) {
|
if (OverSuper(screenLocation)) {
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fSelected != NULL && !OverSubmenu(fSelected, ConvertToScreen(location)))
|
if (fSelected != NULL && !OverSubmenu(fSelected, screenLocation))
|
||||||
SelectItem(NULL);
|
SelectItem(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fSelected != NULL && fSelected->Submenu() != NULL
|
if (item != NULL && fSelected != NULL && OverSubmenu(fSelected, screenLocation)
|
||||||
&& fSelected->Submenu()->Window() != NULL) {
|
&& fSelected->Submenu()->Window() != NULL) {
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
|
|
||||||
int submenuAction = MENU_ACT_NONE;
|
int submenuAction = MENU_ACT_NONE;
|
||||||
BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction);
|
BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction);
|
||||||
if (submenuAction == MENU_ACT_CLOSE) {
|
if (submenuAction == MENU_ACT_CLOSE) {
|
||||||
@@ -1159,31 +1161,31 @@ BMenu::_track(int *action, long start)
|
|||||||
localAction = submenuAction;
|
localAction = submenuAction;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LockLooper())
|
if (!LockLooper())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
|
|
||||||
snooze(snoozeAmount);
|
snooze(snoozeAmount);
|
||||||
} while (buttons != 0);
|
} while (buttons != 0);
|
||||||
|
|
||||||
if (localAction == MENU_ACT_NONE) {
|
if (localAction == MENU_ACT_NONE) {
|
||||||
if (buttons != 0)
|
if (buttons != 0)
|
||||||
localAction = MENU_ACT_NONE;
|
localAction = MENU_ACT_NONE;
|
||||||
else
|
else
|
||||||
localAction = MENU_ACT_CLOSE;
|
localAction = MENU_ACT_CLOSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action != NULL)
|
if (action != NULL)
|
||||||
*action = localAction;
|
*action = localAction;
|
||||||
|
|
||||||
if (LockLooper()) {
|
if (LockLooper()) {
|
||||||
SelectItem(NULL);
|
SelectItem(NULL);
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the menu window recycled for all the child menus
|
// delete the menu window recycled for all the child menus
|
||||||
DeleteMenuWindow();
|
DeleteMenuWindow();
|
||||||
|
|
||||||
@@ -1543,9 +1545,7 @@ BMenu::OverSuper(BPoint location)
|
|||||||
{
|
{
|
||||||
if (!Supermenu())
|
if (!Supermenu())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ConvertToScreen(&location);
|
|
||||||
|
|
||||||
return fSuperbounds.Contains(location);
|
return fSuperbounds.Contains(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1557,7 +1557,7 @@ BMenu::OverSubmenu(BMenuItem *item, BPoint loc)
|
|||||||
BMenu *subMenu = item->Submenu();
|
BMenu *subMenu = item->Submenu();
|
||||||
if (subMenu == NULL || subMenu->Window() == NULL)
|
if (subMenu == NULL || subMenu->Window() == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (subMenu->Window()->Frame().Contains(loc))
|
if (subMenu->Window()->Frame().Contains(loc))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,12 @@
|
|||||||
//------------------------------------------------------------------------------
|
/*
|
||||||
// Copyright (c) 2001-2005, Haiku, Inc.
|
* Copyright 2001-2006, Haiku, Inc.
|
||||||
//
|
* Distributed under the terms of the MIT License.
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
*
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
* Authors:
|
||||||
// to deal in the Software without restriction, including without limitation
|
* Marc Flerackers (mflerackers@androme.be)
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
* Stefano Ceccherini (burton666@libero.it)
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
*/
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// File Name: Menubar.cpp
|
|
||||||
// Authors: Marc Flerackers ([email protected])
|
|
||||||
// Stefano Ceccherini ([email protected])
|
|
||||||
// Description: BMenuBar is a menu that's at the root of a menu hierarchy.
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// TODO: Finish this class
|
// TODO: Finish this class
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
@@ -36,8 +19,8 @@
|
|||||||
#include <MenuPrivate.h>
|
#include <MenuPrivate.h>
|
||||||
#include <TokenSpace.h>
|
#include <TokenSpace.h>
|
||||||
|
|
||||||
struct menubar_data
|
|
||||||
{
|
struct menubar_data {
|
||||||
BMenuBar *menuBar;
|
BMenuBar *menuBar;
|
||||||
int32 menuIndex;
|
int32 menuIndex;
|
||||||
|
|
||||||
@@ -50,28 +33,28 @@ struct menubar_data
|
|||||||
|
|
||||||
|
|
||||||
BMenuBar::BMenuBar(BRect frame, const char *title, uint32 resizeMask,
|
BMenuBar::BMenuBar(BRect frame, const char *title, uint32 resizeMask,
|
||||||
menu_layout layout, bool resizeToFit)
|
menu_layout layout, bool resizeToFit)
|
||||||
: BMenu(frame, title, resizeMask,
|
: BMenu(frame, title, resizeMask,
|
||||||
B_WILL_DRAW | B_FRAME_EVENTS, layout, resizeToFit),
|
B_WILL_DRAW | B_FRAME_EVENTS, layout, resizeToFit),
|
||||||
fBorder(B_BORDER_FRAME),
|
fBorder(B_BORDER_FRAME),
|
||||||
fTrackingPID(-1),
|
fTrackingPID(-1),
|
||||||
fPrevFocusToken(-1),
|
fPrevFocusToken(-1),
|
||||||
fMenuSem(-1),
|
fMenuSem(-1),
|
||||||
fLastBounds(NULL),
|
fLastBounds(NULL),
|
||||||
fTracking(false)
|
fTracking(false)
|
||||||
{
|
{
|
||||||
InitData(layout);
|
InitData(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BMenuBar::BMenuBar(BMessage *data)
|
BMenuBar::BMenuBar(BMessage *data)
|
||||||
: BMenu(data),
|
: BMenu(data),
|
||||||
fBorder(B_BORDER_FRAME),
|
fBorder(B_BORDER_FRAME),
|
||||||
fTrackingPID(-1),
|
fTrackingPID(-1),
|
||||||
fPrevFocusToken(-1),
|
fPrevFocusToken(-1),
|
||||||
fMenuSem(-1),
|
fMenuSem(-1),
|
||||||
fLastBounds(NULL),
|
fLastBounds(NULL),
|
||||||
fTracking(false)
|
fTracking(false)
|
||||||
{
|
{
|
||||||
int32 border;
|
int32 border;
|
||||||
|
|
||||||
@@ -412,7 +395,9 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fSelected != NULL) {
|
if (fSelected != NULL && OverSubmenu(fSelected, ConvertToScreen(where))) {
|
||||||
|
// call _track() from the selected sub-menu when the mouse cursor
|
||||||
|
// is over its window
|
||||||
BMenu *menu = fSelected->Submenu();
|
BMenu *menu = fSelected->Submenu();
|
||||||
if (menu != NULL) {
|
if (menu != NULL) {
|
||||||
window->Unlock();
|
window->Unlock();
|
||||||
@@ -423,7 +408,8 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
if (!window->Lock())//WithTimeout(200000) < B_OK)
|
if (!window->Lock())//WithTimeout(200000) < B_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (menuItem == NULL)
|
||||||
|
SelectItem(NULL);
|
||||||
|
|
||||||
window->Unlock();
|
window->Unlock();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user