big improvements for menus. The tracking is in many ways on par with r5, except for a few things, like diagonal movement and that grandparent bug
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17095 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -188,7 +188,7 @@ virtual void _ReservedMenu6();
|
|||||||
void InitData(BMessage *data = NULL);
|
void InitData(BMessage *data = NULL);
|
||||||
bool _show(bool selectFirstItem = false);
|
bool _show(bool selectFirstItem = false);
|
||||||
void _hide();
|
void _hide();
|
||||||
BMenuItem *_track(int *action, long start = -1);
|
BMenuItem *_track(int *action, bigtime_t trackTime, long start = -1);
|
||||||
bool _AddItem(BMenuItem *item, int32 index);
|
bool _AddItem(BMenuItem *item, int32 index);
|
||||||
bool RemoveItems(int32 index,
|
bool RemoveItems(int32 index,
|
||||||
int32 count,
|
int32 count,
|
||||||
|
|||||||
@@ -975,7 +975,7 @@ BMenu::Track(bool openAnyway, BRect *clickToOpenRect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int action;
|
int action;
|
||||||
BMenuItem *menuItem = _track(&action, -1);
|
BMenuItem *menuItem = _track(&action, system_time());
|
||||||
|
|
||||||
SetStickyMode(false);
|
SetStickyMode(false);
|
||||||
fExtraRect = NULL;
|
fExtraRect = NULL;
|
||||||
@@ -1136,7 +1136,7 @@ BMenu::_hide()
|
|||||||
|
|
||||||
|
|
||||||
BMenuItem *
|
BMenuItem *
|
||||||
BMenu::_track(int *action, long start)
|
BMenu::_track(int *action, bigtime_t trackTime, long start)
|
||||||
{
|
{
|
||||||
// TODO: cleanup
|
// TODO: cleanup
|
||||||
ulong buttons;
|
ulong buttons;
|
||||||
@@ -1186,7 +1186,7 @@ BMenu::_track(int *action, long start)
|
|||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
locked = false;
|
locked = false;
|
||||||
int submenuAction = MENU_ACT_NONE;
|
int submenuAction = MENU_ACT_NONE;
|
||||||
BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction);
|
BMenuItem *submenuItem = fSelected->Submenu()->_track(&submenuAction, startTime);
|
||||||
if (submenuAction == MENU_ACT_CLOSE) {
|
if (submenuAction == MENU_ACT_CLOSE) {
|
||||||
item = submenuItem;
|
item = submenuItem;
|
||||||
localAction = submenuAction;
|
localAction = submenuAction;
|
||||||
@@ -1202,8 +1202,8 @@ BMenu::_track(int *action, long start)
|
|||||||
if (buttons != 0 && IsStickyMode()) {
|
if (buttons != 0 && IsStickyMode()) {
|
||||||
localAction = MENU_ACT_CLOSE;
|
localAction = MENU_ACT_CLOSE;
|
||||||
break;
|
break;
|
||||||
} else if (buttons == 0) {
|
} else if (buttons == 0 && !IsStickyMode()) {
|
||||||
if (IsStickyPrefOn())
|
if (IsStickyPrefOn() && system_time() < trackTime + 2000000)
|
||||||
SetStickyMode(true);
|
SetStickyMode(true);
|
||||||
else {
|
else {
|
||||||
localAction = MENU_ACT_CLOSE;
|
localAction = MENU_ACT_CLOSE;
|
||||||
@@ -1220,6 +1220,9 @@ BMenu::_track(int *action, long start)
|
|||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsStickyMode())
|
||||||
|
SetStickyMode(false);
|
||||||
|
|
||||||
// delete the menu window recycled for all the child menus
|
// delete the menu window recycled for all the child menus
|
||||||
DeleteMenuWindow();
|
DeleteMenuWindow();
|
||||||
|
|
||||||
@@ -1785,6 +1788,11 @@ void
|
|||||||
BMenu::SetStickyMode(bool on)
|
BMenu::SetStickyMode(bool on)
|
||||||
{
|
{
|
||||||
fStickyMode = on;
|
fStickyMode = on;
|
||||||
|
|
||||||
|
// If we are switching to sticky mode, propagate the status
|
||||||
|
// back to the super menu
|
||||||
|
if (on && fSuper != NULL)
|
||||||
|
fSuper->SetStickyMode(on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -377,15 +377,15 @@ BMenuBar::TrackTask(void *arg)
|
|||||||
BMenuItem *
|
BMenuItem *
|
||||||
BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
||||||
{
|
{
|
||||||
// TODO: This function is very incomplete and just partially working:
|
// TODO: Cleanup, merge some "if" blocks if possible
|
||||||
// For example, it doesn't respect the "sticky mode" setting.
|
|
||||||
BMenuItem *resultItem = NULL;
|
BMenuItem *resultItem = NULL;
|
||||||
BWindow *window = Window();
|
BWindow *window = Window();
|
||||||
int localAction = MENU_ACT_NONE;
|
int localAction = MENU_ACT_NONE;
|
||||||
|
bigtime_t startTime = system_time();
|
||||||
while (true) {
|
while (true) {
|
||||||
bigtime_t snoozeAmount = 30000;
|
bigtime_t snoozeAmount = 30000;
|
||||||
if (!window->Lock())//WithTimeout(200000) < B_OK)
|
bool locked = window->Lock();//WithTimeout(200000)
|
||||||
|
if (!locked)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BPoint where;
|
BPoint where;
|
||||||
@@ -393,12 +393,18 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
GetMouse(&where, &buttons);
|
GetMouse(&where, &buttons);
|
||||||
BMenuItem *menuItem = HitTestItems(where, B_ORIGIN);
|
BMenuItem *menuItem = HitTestItems(where, B_ORIGIN);
|
||||||
if (menuItem != NULL && menuItem != fSelected) {
|
if (menuItem != NULL && menuItem != fSelected) {
|
||||||
// only select the item
|
// Select item if:
|
||||||
SelectItem(menuItem, -1);
|
// - clicked in sticky mode
|
||||||
if (menuItem->Submenu() != NULL
|
// - nonsticky mode,
|
||||||
&& menuItem->Submenu()->Window() == NULL) {
|
// - no previous selection
|
||||||
// open the menu if it's not opened yet
|
if (fSelected == NULL || !IsStickyMode() || buttons != 0) {
|
||||||
SelectItem(menuItem);
|
// only select the item
|
||||||
|
SelectItem(menuItem, -1);
|
||||||
|
if (menuItem->Submenu() != NULL
|
||||||
|
&& menuItem->Submenu()->Window() == NULL) {
|
||||||
|
// open the menu if it's not opened yet
|
||||||
|
SelectItem(menuItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,20 +414,22 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
BMenu *menu = fSelected->Submenu();
|
BMenu *menu = fSelected->Submenu();
|
||||||
if (menu != NULL) {
|
if (menu != NULL) {
|
||||||
window->Unlock();
|
window->Unlock();
|
||||||
|
locked = false;
|
||||||
snoozeAmount = 0;
|
snoozeAmount = 0;
|
||||||
resultItem = menu->_track(&localAction);
|
resultItem = menu->_track(&localAction, startTime);
|
||||||
if (!window->Lock())//WithTimeout(200000) < B_OK)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else if (menuItem == NULL && !fLastBounds->Contains(where))
|
} else if (menuItem == NULL && !IsStickyMode())
|
||||||
SelectItem(NULL);
|
SelectItem(NULL);
|
||||||
|
|
||||||
window->Unlock();
|
if (locked)
|
||||||
|
window->Unlock();
|
||||||
|
|
||||||
if (localAction == MENU_ACT_CLOSE || (buttons != 0 && IsStickyMode()))
|
if (localAction == MENU_ACT_CLOSE || (buttons != 0 && IsStickyMode() && menuItem == NULL))
|
||||||
break;
|
break;
|
||||||
else if (buttons == 0) {
|
else if (buttons == 0 && !IsStickyMode()) {
|
||||||
if (IsStickyPrefOn())
|
// Don't switch to sticky mode if user kept the mouse pressed for too long
|
||||||
|
// TODO: Delay could be smaller, but then it wouldn't be noticeable on QEMU on my machine
|
||||||
|
if (IsStickyPrefOn() && system_time() < startTime + 2000000)
|
||||||
SetStickyMode(true);
|
SetStickyMode(true);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
@@ -444,6 +452,7 @@ BMenuBar::Track(int32 *action, int32 startIndex, bool showMenu)
|
|||||||
|
|
||||||
if (IsStickyMode())
|
if (IsStickyMode())
|
||||||
SetStickyMode(false);
|
SetStickyMode(false);
|
||||||
|
|
||||||
DeleteMenuWindow();
|
DeleteMenuWindow();
|
||||||
|
|
||||||
if (action != NULL)
|
if (action != NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user