Try to split the tracking function into smaller ones. Please bear with
me for the absolutely UGLY names. Also, if someone can suggest better ones... I seem not to have introduced any new bug. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19476 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -191,6 +191,10 @@ virtual void _ReservedMenu6();
|
|||||||
bool _show(bool selectFirstItem = false);
|
bool _show(bool selectFirstItem = false);
|
||||||
void _hide();
|
void _hide();
|
||||||
BMenuItem *_track(int *action, bigtime_t trackTime, long start = -1);
|
BMenuItem *_track(int *action, bigtime_t trackTime, long start = -1);
|
||||||
|
|
||||||
|
void _UpdateStateOpenSelect(BMenuItem *item, bigtime_t &openTime, bigtime_t &closeTime);
|
||||||
|
void _UpdateStateClose(BMenuItem *item, const BPoint &where, const uint32 &buttons);
|
||||||
|
|
||||||
bool _AddItem(BMenuItem *item, int32 index);
|
bool _AddItem(BMenuItem *item, int32 index);
|
||||||
bool RemoveItems(int32 index,
|
bool RemoveItems(int32 index,
|
||||||
int32 count,
|
int32 count,
|
||||||
@@ -236,8 +240,11 @@ virtual void _ReservedMenu6();
|
|||||||
bool IsStickyPrefOn();
|
bool IsStickyPrefOn();
|
||||||
void RedrawAfterSticky(BRect bounds);
|
void RedrawAfterSticky(BRect bounds);
|
||||||
bool OkToProceed(BMenuItem *);
|
bool OkToProceed(BMenuItem *);
|
||||||
|
|
||||||
|
bool CustomTrackingWantsToQuit();
|
||||||
|
|
||||||
void QuitTracking();
|
void QuitTracking();
|
||||||
|
|
||||||
|
|
||||||
status_t ParseMsg(BMessage *msg, int32 *sindex, BMessage *spec,
|
status_t ParseMsg(BMessage *msg, int32 *sindex, BMessage *spec,
|
||||||
int32 *form, const char **prop,
|
int32 *form, const char **prop,
|
||||||
|
|||||||
+62
-44
@@ -1257,12 +1257,8 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
|
|||||||
fSuper->fState = MENU_STATE_TRACKING_SUBMENU;
|
fSuper->fState = MENU_STATE_TRACKING_SUBMENU;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (fExtraMenuData != NULL && fExtraMenuData->trackingHook != NULL
|
if (CustomTrackingWantsToQuit())
|
||||||
&& fExtraMenuData->trackingState != NULL) {
|
break;
|
||||||
bool quit = fExtraMenuData->trackingHook(this, fExtraMenuData->trackingState);
|
|
||||||
if (quit)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool locked = LockLooper();
|
bool locked = LockLooper();
|
||||||
if (!locked)
|
if (!locked)
|
||||||
@@ -1276,20 +1272,8 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
|
|||||||
Window()->UpdateIfNeeded();
|
Window()->UpdateIfNeeded();
|
||||||
BPoint screenLocation = ConvertToScreen(location);
|
BPoint screenLocation = ConvertToScreen(location);
|
||||||
item = HitTestItems(location, B_ORIGIN);
|
item = HitTestItems(location, B_ORIGIN);
|
||||||
if (item != NULL) {
|
if (item != NULL)
|
||||||
if (item != fSelected && system_time() > closeTime + kHysteresis) {
|
_UpdateStateOpenSelect(item, openTime, closeTime);
|
||||||
_SelectItem(item, false);
|
|
||||||
openTime = system_time();
|
|
||||||
} else if (system_time() > kHysteresis + openTime && item->Submenu() != NULL
|
|
||||||
&& item->Submenu()->Window() == NULL) {
|
|
||||||
// Open the submenu if it's not opened yet, but only if
|
|
||||||
// the mouse pointer stayed over there for some time
|
|
||||||
// (hysteresis)
|
|
||||||
_SelectItem(item);
|
|
||||||
closeTime = system_time();
|
|
||||||
}
|
|
||||||
fState = MENU_STATE_TRACKING;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track the submenu
|
// Track the submenu
|
||||||
if (fSelected != NULL && OverSubmenu(fSelected, screenLocation)) {
|
if (fSelected != NULL && OverSubmenu(fSelected, screenLocation)) {
|
||||||
@@ -1306,11 +1290,8 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
|
|||||||
if (wasSticky && !IsStickyMode()) {
|
if (wasSticky && !IsStickyMode()) {
|
||||||
buttons = 1;
|
buttons = 1;
|
||||||
// buttons must have been pressed in the meantime
|
// buttons must have been pressed in the meantime
|
||||||
trackTime = 0;
|
|
||||||
// we are already in non-sticky mode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//submenu->Window()->Activate();
|
|
||||||
if (submenuAction == MENU_STATE_CLOSED) {
|
if (submenuAction == MENU_STATE_CLOSED) {
|
||||||
item = submenuItem;
|
item = submenuItem;
|
||||||
fState = submenuAction;
|
fState = submenuAction;
|
||||||
@@ -1347,27 +1328,7 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
|
|||||||
if (locked)
|
if (locked)
|
||||||
UnlockLooper();
|
UnlockLooper();
|
||||||
|
|
||||||
if (buttons != 0 && IsStickyMode()) {
|
_UpdateStateClose(item, location, buttons);
|
||||||
if (item == NULL)
|
|
||||||
fState = MENU_STATE_CLOSED;
|
|
||||||
else {
|
|
||||||
BMenu *supermenu = Supermenu();
|
|
||||||
for(; supermenu; supermenu = supermenu->Supermenu())
|
|
||||||
supermenu->SetStickyMode(false);
|
|
||||||
SetStickyMode(false);
|
|
||||||
trackTime = 0;
|
|
||||||
}
|
|
||||||
} else if (buttons == 0 && !IsStickyMode()) {
|
|
||||||
/* TODO: FIXME! trackTime is a hacky workaround for BMenuField. It
|
|
||||||
opens directly under your mouse pointer, so when you release the mouse
|
|
||||||
button the menu closes again because it started in non-sticky mode. */
|
|
||||||
/* if (system_time() < trackTime + 1000000
|
|
||||||
|| (fExtraRect != NULL && fExtraRect->Contains(location))) */
|
|
||||||
if (fExtraRect != NULL && fExtraRect->Contains(location))
|
|
||||||
SetStickyMode(true);
|
|
||||||
else
|
|
||||||
fState = MENU_STATE_CLOSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fState == MENU_STATE_CLOSED)
|
if (fState == MENU_STATE_CLOSED)
|
||||||
break;
|
break;
|
||||||
@@ -1393,6 +1354,51 @@ BMenu::_track(int *action, bigtime_t trackTime, long start)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BMenu::_UpdateStateOpenSelect(BMenuItem *item, bigtime_t &openTime, bigtime_t &closeTime)
|
||||||
|
{
|
||||||
|
if (item != fSelected && system_time() > closeTime + kHysteresis) {
|
||||||
|
_SelectItem(item, false);
|
||||||
|
openTime = system_time();
|
||||||
|
} else if (system_time() > kHysteresis + openTime && item->Submenu() != NULL
|
||||||
|
&& item->Submenu()->Window() == NULL) {
|
||||||
|
// Open the submenu if it's not opened yet, but only if
|
||||||
|
// the mouse pointer stayed over there for some time
|
||||||
|
// (hysteresis)
|
||||||
|
_SelectItem(item);
|
||||||
|
closeTime = system_time();
|
||||||
|
}
|
||||||
|
if (fState != MENU_STATE_TRACKING)
|
||||||
|
fState = MENU_STATE_TRACKING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BMenu::_UpdateStateClose(BMenuItem *item, const BPoint &where, const uint32 &buttons)
|
||||||
|
{
|
||||||
|
if (buttons != 0 && IsStickyMode()) {
|
||||||
|
if (item == NULL)
|
||||||
|
fState = MENU_STATE_CLOSED;
|
||||||
|
else {
|
||||||
|
BMenu *supermenu = Supermenu();
|
||||||
|
for(; supermenu; supermenu = supermenu->Supermenu())
|
||||||
|
supermenu->SetStickyMode(false);
|
||||||
|
SetStickyMode(false);
|
||||||
|
}
|
||||||
|
} else if (buttons == 0 && !IsStickyMode()) {
|
||||||
|
/* TODO: FIXME! trackTime is a hacky workaround for BMenuField. It
|
||||||
|
opens directly under your mouse pointer, so when you release the mouse
|
||||||
|
button the menu closes again because it started in non-sticky mode. */
|
||||||
|
/* if (system_time() < trackTime + 1000000
|
||||||
|
|| (fExtraRect != NULL && fExtraRect->Contains(location))) */
|
||||||
|
if (fExtraRect != NULL && fExtraRect->Contains(where))
|
||||||
|
SetStickyMode(true);
|
||||||
|
else
|
||||||
|
fState = MENU_STATE_CLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BMenu::_AddItem(BMenuItem *item, int32 index)
|
BMenu::_AddItem(BMenuItem *item, int32 index)
|
||||||
{
|
{
|
||||||
@@ -2159,6 +2165,18 @@ BMenu::OkToProceed(BMenuItem* item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BMenu::CustomTrackingWantsToQuit()
|
||||||
|
{
|
||||||
|
if (fExtraMenuData != NULL && fExtraMenuData->trackingHook != NULL
|
||||||
|
&& fExtraMenuData->trackingState != NULL) {
|
||||||
|
return fExtraMenuData->trackingHook(this, fExtraMenuData->trackingState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMenu::QuitTracking()
|
BMenu::QuitTracking()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user