Ejemplo n.º 1
0
void
BListView::MouseDown(BPoint where)
{
    if (!IsFocus()) {
        MakeFocus();
        Sync();
        Window()->UpdateIfNeeded();
    }

    BMessage* message = Looper()->CurrentMessage();
    int32 index = IndexOf(where);

    int32 buttons = 0;
    if (message != NULL)
        message->FindInt32("buttons", &buttons);

    int32 modifiers = 0;
    if (message != NULL)
        message->FindInt32("modifiers", &modifiers);

    // If the user double (or more) clicked within the current selection,
    // we don't change the selection but invoke the selection.
    // TODO: move this code someplace where it can be shared everywhere
    // instead of every class having to reimplement it, once some sane
    // API for it is decided.
    BPoint delta = where - fTrack->drag_start;
    bigtime_t sysTime;
    Window()->CurrentMessage()->FindInt64("when", &sysTime);
    bigtime_t timeDelta = sysTime - fTrack->last_click_time;
    bigtime_t doubleClickSpeed;
    get_click_speed(&doubleClickSpeed);
    bool doubleClick = false;

    if (timeDelta < doubleClickSpeed
            && fabs(delta.x) < kDoubleClickThreshold
            && fabs(delta.y) < kDoubleClickThreshold
            && fTrack->item_index == index) {
        doubleClick = true;
    }

    if (doubleClick && index >= fFirstSelected && index <= fLastSelected) {
        fTrack->drag_start.Set(INT32_MAX, INT32_MAX);
        Invoke();
        return BView::MouseDown(where);
    }

    if (!doubleClick) {
        fTrack->drag_start = where;
        fTrack->last_click_time = system_time();
        fTrack->item_index = index;
        fTrack->was_selected = index >= 0 ? ItemAt(index)->IsSelected() : false;
        fTrack->try_drag = true;

        MouseDownThread<BListView>::TrackMouse(this,
                                               &BListView::_DoneTracking, &BListView::_Track);
    }

    if (index >= 0) {
        if (fListType == B_MULTIPLE_SELECTION_LIST) {
            if ((modifiers & B_SHIFT_KEY) != 0) {
                // select entire block
                // TODO: maybe review if we want it like in Tracker
                // (anchor item)
                if (index >= fFirstSelected && index < fLastSelected) {
                    // clicked inside of selected items block, deselect all
                    // but from the first selected item to the clicked item
                    DeselectExcept(fFirstSelected, index);
                } else {
                    Select(std::min(index, fFirstSelected), std::max(index,
                            fLastSelected));
                }
            } else {
                if ((modifiers & B_COMMAND_KEY) != 0) {
                    // toggle selection state of clicked item (like in Tracker)
                    // toggle selection state of clicked item
                    if (ItemAt(index)->IsSelected())
                        Deselect(index);
                    else
                        Select(index, true);
                } else
                    Select(index);
            }
        } else {
            // toggle selection state of clicked item
            if ((modifiers & B_COMMAND_KEY) != 0 && ItemAt(index)->IsSelected())
                Deselect(index);
            else
                Select(index);
        }
    } else if ((modifiers & B_COMMAND_KEY) == 0)
        DeselectAll();

    BView::MouseDown(where);
}
Ejemplo n.º 2
0
void
NamesView::MouseMoved (BPoint myPoint, uint32 transitcode, const BMessage *dragMessage)
{
 if ((dragMessage != NULL) && (dragMessage->HasRef("refs")))
 {
	 // make sure the ref isn't a dir
	 entry_ref ref;
	 dragMessage->FindRef("refs", &ref);
	 BDirectory dir (&ref);
	 if (dir.InitCheck() != B_OK)
	 {
		 int32 nameIndex (IndexOf(myPoint));
		 if (nameIndex >= 0)
			 Select(nameIndex);
	 }
 }
 else if (fTracking)
 {
	 if (transitcode == B_INSIDE_VIEW)
	 {
		 BListItem *item = ItemAt (IndexOf(myPoint));
		 if (item)
		 {
			 BListItem *lastitem (NULL);
			 int32 first (CurrentSelection (0));
			 int32 last (first);
			 int32 i (1);
			 while ((last = CurrentSelection(i++)) != -1)
				 lastitem = ItemAt(last);
			 if (lastitem)
				 last = IndexOf(lastitem);
			 else
				 last = first;
			 int32 current (IndexOf (myPoint));

			 if (current >= 0)
			 {
				 if (current < first)
				 {
					 // sweep up
					 Select (current, last, true);
				 }
				 else if (current > last)
				 {
					 // sweep down
					 Select (first, current, true);
				 }
				 else if (fCurrentindex > current)
				 {
					 // backtrack up
					 DeselectExcept (first, current);
				 }
				 else if (fCurrentindex < current)
				 {
					 // backtrack down
					 DeselectExcept (current, last);
				 }
				 fCurrentindex = current;
			 }
		 }
	 }
 }
 else
	 BListView::MouseMoved (myPoint, transitcode, dragMessage);
}