void MemoryView::_HandleContextMenu(BPoint point) { int32 offset = _GetOffsetAt(point); if (offset < fSelectionStart || offset > fSelectionEnd) return; BPopUpMenu* menu = new(std::nothrow) BPopUpMenu("Options"); if (menu == NULL) return; ObjectDeleter<BPopUpMenu> menuDeleter(menu); ObjectDeleter<BMenuItem> itemDeleter; ObjectDeleter<BMessage> messageDeleter; BMessage* message = NULL; BMenuItem* item = NULL; if (fSelectionEnd - fSelectionStart == fTargetAddressSize / 2) { BMessage* message = new(std::nothrow) BMessage(MSG_INSPECT_ADDRESS); if (message == NULL) return; target_addr_t address; if (fTargetAddressSize == 8) address = *((uint32*)(fTargetBlock->Data() + fSelectionStart)); else address = *((uint64*)(fTargetBlock->Data() + fSelectionStart)); if (fCurrentEndianMode == EndianModeBigEndian) address = B_HOST_TO_BENDIAN_INT64(address); else address = B_HOST_TO_LENDIAN_INT64(address); messageDeleter.SetTo(message); message->AddUInt64("address", address); BMenuItem* item = new(std::nothrow) BMenuItem("Inspect", message); if (item == NULL) return; messageDeleter.Detach(); itemDeleter.SetTo(item); if (!menu->AddItem(item)) return; item->SetTarget(Looper()); itemDeleter.Detach(); } message = new(std::nothrow) BMessage(B_COPY); if (message == NULL) return; messageDeleter.SetTo(message); item = new(std::nothrow) BMenuItem("Copy", message); if (item == NULL) return; messageDeleter.Detach(); itemDeleter.SetTo(item); if (!menu->AddItem(item)) return; item->SetTarget(this); itemDeleter.Detach(); menuDeleter.Detach(); BPoint screenWhere(point); ConvertToScreen(&screenWhere); BRect mouseRect(screenWhere, screenWhere); mouseRect.InsetBy(-4.0, -4.0); menu->Go(screenWhere, true, false, mouseRect, true); }
void BComboBox::ChoiceListView::MouseDown(BPoint where) { BRect rect(Window()->Frame()); ConvertFromScreen(&rect); if (!rect.Contains(where)) { // hide the popup window when the user clicks outside of it if (fParent->Window()->Lock()) { fParent->HidePopupWindow(); fParent->Window()->Unlock(); } // HACK: the window is locked and unlocked so that it will get // activated before we potentially send the mouse down event in the // code below. Is there a way to wait until the window is activated // before sending the mouse down? Should we call // fParent->Window()->MakeActive(true) here? if (fParent->Window()->Lock()) { // resend the mouse event to the textinput, if necessary BTextView *text = fParent->TextView(); BPoint screenWhere(ConvertToScreen(where)); rect = text->Window()->ConvertToScreen(text->Frame()); if (rect.Contains(screenWhere)) { //printf(" resending mouse down to textinput\n"); BMessage *msg = new BMessage(*Window()->CurrentMessage()); msg->RemoveName("be:view_where"); text->ConvertFromScreen(&screenWhere); msg->AddPoint("be:view_where", screenWhere); text->Window()->PostMessage(msg, text); delete msg; } fParent->Window()->Unlock(); } return; } rect = Bounds(); if (!rect.Contains(where)) return; fTrackingMouseDown = true; // check for double click bigtime_t now = system_time(); bigtime_t clickSpeed; get_click_speed(&clickSpeed); if ((now - fClickTime < clickSpeed) && ((abs((int)(fClickLoc.x - where.x)) < 3) && (abs((int)(fClickLoc.y - where.y)) < 3))) { // this is a double click // XXX: what to do here? printf("BComboBox::ChoiceListView::MouseDown() -- unhandled double click\n"); } fClickTime = now; fClickLoc = where; float h = LineHeight(); int32 oldIndex = fSelIndex; fSelIndex = (int32)floor(where.y / h); int32 choices = fParent->fChoiceList->CountChoices(); if (fSelIndex < 0 || fSelIndex >= choices) fSelIndex = -1; if (oldIndex != fSelIndex) { InvalidateItem(oldIndex); InvalidateItem(fSelIndex); } // XXX: this probably isn't necessary since we are doing a SetEventMask // whenever the popup window becomes visible which routes all mouse events // to this view // SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); }