Example #1
0
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);
}