void DragonView::MouseMoved( BPoint where, uint32 code, const BMessage *msg ) { // If we're already dragging, we don't care. if( _am_dragging ) return; // If the primary mouse button isn't down, or the mouse is just entering // the view, we just return... no drag is starting. if( !_button_down || code == B_ENTERED_VIEW ) return; // If the mouse has travelled "far enough", we start a drag. In this // case, "far enough" is measured by the number of pixels the user's // chosen in the "Drag Threshold" submenu of the "File" menu. // // A real application would probably have a slider for picking the // threshold values. float dx = fabs( where.x - _button_click.x ); float dy = fabs( where.y - _button_click.y ); if( dx >= _drag_threshold || dy >= _drag_threshold ) { // Start a drag! _bits_mutex.Lock(); _am_dragging = true; // Create our drag message. BMessage *drag_message = _MakeDragMessage(); // Create a new bitmap or rectangle (if the bitmap would be too // large) to drag around. BRect drag_rect( _bits->Bounds() ); BBitmap *drag_bitmap = _MakeDragBitmap(); _bits_mutex.Unlock(); if( drag_bitmap ) { DragMessage( drag_message, drag_bitmap, B_OP_ALPHA, where, this ); } else { DragMessage( drag_message, drag_rect, this ); } delete drag_message; } }
bool ViewFileList::InitiateDrag(BPoint a, int32 index, bool selected) { if (selected == false) return false; PListItem *sam = ((PListItem*) ItemAt(index)); if (sam == NULL) return false; BEntry *tempOne = new BEntry(); if (sam->GetEntry(tempOne) == B_OK ) { entry_ref tmp; tempOne->GetRef(&tmp); // get picture here BNode noddy(tempOne); BNodeInfo noddi(&noddy); BBitmap *snoopy = new BBitmap( BRect(0,0,31,31), B_CMAP8); noddi.GetTrackerIcon(snoopy,B_LARGE_ICON); BMessage *dragee = new BMessage(B_SIMPLE_DATA); dragee->AddRef("refs",&tmp); dragee->AddString("source","Peek"); DragMessage(dragee, snoopy, B_OP_ALPHA, BPoint(15,15), NULL); delete dragee; } delete tempOne; return true; }
void PieView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) { if (fClicked) { // Primary mouse button is down. if (fDragging) return; // If the mouse has moved far enough, initiate dragging. BPoint diff = where - fDragStart; float distance = sqrtf(diff.x * diff.x + diff.y * diff.x); if (distance > kDragThreshold) { fDragging = true; BBitmap* icon = new BBitmap(BRect(0.0, 0.0, 31.0, 31.0), B_RGBA32); if (BNodeInfo::GetTrackerIcon(&fClickedFile->ref, icon, B_LARGE_ICON) == B_OK) { BMessage msg(B_SIMPLE_DATA); msg.AddRef("refs", &fClickedFile->ref); DragMessage(&msg, icon, B_OP_BLEND, BPoint(15.0, 15.0)); } else delete icon; } } else { // Mouse button is not down, display file info. if (transit == B_EXITED_VIEW) { // Clear status view fWindow->ShowInfo(NULL); } else { // Display file information. fWindow->ShowInfo(_FileAt(where)); } } }
void ImageView::MouseDown(BPoint point) { if (!HasImage()) return; // Only accept left button clicks BMessage *pmsg = Window()->CurrentMessage(); int32 button = pmsg->FindInt32("buttons"); if (button != B_PRIMARY_MOUSE_BUTTON) return; // Tell BeOS to setup a Drag/Drop operation // // (When the image is dropped, BeOS sends // the following message to ImageWindow, // which causes it to call ImageView::SetImage()) BMessage msg(B_SIMPLE_DATA); msg.AddInt32("be:actions", B_COPY_TARGET); msg.AddString("be:filetypes", "application/octet-stream"); msg.AddString("be:types", "application/octet-stream"); msg.AddString("be:clip_name", "Bitmap"); DragMessage(&msg, Bounds()); }
void CCellView::StartDrag(BPoint where, bool copy) { ClearAnts(); BMessage msg(B_SIMPLE_DATA); msg.AddPointer("container", fContainer); msg.AddPointer("cellview", this); msg.AddData("range", 'rang', &fSelection, sizeof(range)); msg.AddBool("dragacopy", copy); BRegion rgn; SelectionToRegion(rgn); cell c; GetCellHitBy(where, c); BRect dragRect = rgn.Frame(); dragRect.OffsetBy(fCellWidths[c.h] - fCellWidths[fSelection.left], fCellHeights[c.v] - fCellHeights[fSelection.top]); BMallocIO buf; CTextConverter conv(buf, fContainer); conv.ConvertToText(&fSelection); msg.AddData("text/plain", B_MIME_DATA, buf.Buffer(), buf.BufferLength()); // and add a nice picture BPicture pic; BRect r; GetPictureOfSelection(&pic, r); pic.Archive(&msg); // msg.AddData("picture", 'PICT', pic.Data(), pic.DataSize()); msg.AddData("rect of pict", 'RECT', &r, sizeof(BRect)); fDragIsAcceptable = true; DragMessage(&msg, dragRect, this); } /* CCellView::StartDrag */
void TPanelWindowView::DraggingItem( TPanelIcon *item ) { if ( item ) { BMessage message( 'IDRG' ); message.AddPointer( "source", item ); DragMessage( &message, item->fFrame, this ); } }
void DropView::MouseMoved(BPoint where, uint32 code, const BMessage *msg) { // check for our drag message if (msg != NULL && msg->what == dropWhat) { // if we ain't occupied, aren't about to be and // the mouse just entered if (!hasOccupant && !occupantLoading && code == B_ENTERED_VIEW) { // you can drop that here! // give the user some visual feedback drawHighlight = true; // force redraw Invalidate(Bounds()); } else if (code == B_EXITED_VIEW) { // it left, stop highlighting drawHighlight = false; // force redraw Invalidate(Bounds()); } } else if (msg != NULL && msg->what == JE_CONTAINER_VIEW_DND && isDragging) { // this is a drag initiated by us // if the mouse is leaving the view, then our occupant // is being removed if (code == B_EXITED_VIEW) { // tell the main window our plugin is gone ((MainWindow *)Window())->UnloadPlugin(piType,id); ToggleOccupant(false); } } else if (trackingMouse) { // we're tracking the mouse after it clicked on us float dx = where.x - mouseDownPt.x; // delta x float dy = where.y - mouseDownPt.y; // delta y float dp = (float)sqrt((dx*dx)+(dy*dy)); // delta magnitude // if the mouse has moved futher than 5 pixels in any direction if (dp > 5.0) { // initiate a drag BMessage drag(JE_CONTAINER_VIEW_DND); DragMessage(&drag, new BBitmap(iconBitmap), B_OP_OVER, BPoint(where.x-2.0, where.y-2.0)); // stop tracking the mouse trackingMouse = false; // our occupant is being dragged isDragging = true; } } }
bool FactoryDragListView::InitiateDrag(BPoint point, int32 index, bool wasSelected) { BALM::CustomizableAddOn* addOn = fInstalledComponents.ItemAt(index); BMessage dragMessage(kMsgCreateComponent); dragMessage.AddString("component", addOn->Name()); BRect frame; BBitmap* bitmap = BALM::EditorHelper::CreateBitmap(addOn, frame, NULL); if (bitmap != NULL) { DragMessage(&dragMessage, bitmap, BPoint(frame.Width() / 2, frame.Height() / 2)); } else { frame.OffsetTo(fCurrentMousePosition.x - frame.Width() / 2, fCurrentMousePosition.y - frame.Height() / 2); DragMessage(&dragMessage, frame); } return true; }
void QuaSymbolBridge::MouseDown(BPoint where) { long channel, quant; BRect area = Bounds(); ulong mods = modifiers(); // Key mods??? ulong buts; BMessage *msg; BPoint pt; drawing_mode cur_mode = DrawingMode(); long clicks; GetMouse(&pt, &buts); msg = Window()->CurrentMessage(); if ((clicks=msg->FindInt32("clicks")) == 1) { if (buts & B_SECONDARY_MOUSE_BUTTON) { BPopUpMenu *qMenu = new BPopUpMenu("env sel", true, FALSE); BPoint orig = where; ConvertToScreen(&where); BMessage *msg = new BMessage(SET_DISPLAY_MODE); msg->AddInt32("display mode", OBJECT_DISPLAY_SMALL); BMenuItem *item = new BMenuItem("Small", msg); qMenu->AddItem(item); item->SetTarget(this); msg = new BMessage(SET_DISPLAY_MODE); msg->AddInt32("display mode", OBJECT_DISPLAY_BIG); item = new BMenuItem("Large", msg); qMenu->AddItem(item); item->SetTarget(this); qMenu->SetAsyncAutoDestruct(true); qMenu->Go(where, true, false, true); } else { msg = new BMessage(MOVE_OBJECT); msg->AddPointer("sym_object", this); if (mods & B_SHIFT_KEY) { ((ObjectViewContainer *)Parent())->AddSelection(this); } else { ((ObjectViewContainer *)Parent())->Select(this); } DragMessage(msg, area); } } else if (clicks > 1) { // edit object Edit(); } else { } }
bool ClipView::InitiateDrag(BPoint point, int32 index, bool wasSelected) { ClipItem* sItem = dynamic_cast<ClipItem *> (ItemAt(index)); if (sItem == NULL) return false; BString string(sItem->GetClip()); BMessage message(FAV_ADD); message.AddData("text/plain", B_MIME_TYPE, string, string.Length()); message.AddPointer("clip", sItem); BRect dragRect(0.0f, 0.0f, Bounds().Width(), sItem->Height()); BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true); if (dragBitmap->IsValid()) { BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); dragBitmap->AddChild(view); dragBitmap->Lock(); sItem->DrawItem(view, dragRect); view->SetHighColor(0, 0, 0, 255); view->StrokeRect(view->Bounds()); view->Sync(); dragBitmap->Unlock(); } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap != NULL) DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0)); else DragMessage(&message, dragRect.OffsetToCopy(point), this); return true; }
void TBarView::HandleDeskbarMenu(BMessage* messagewithdestination) { if (!Dragging()) return; // in mini-mode if (fVertical && fState != kExpandoState) { // if drop is in the team menu, bail if (fBarMenuBar->CountItems() >= 2) { uint32 buttons; BPoint location; GetMouse(&location, &buttons); if (fBarMenuBar->ItemAt(1)->Frame().Contains(location)) return; } } if (messagewithdestination) { entry_ref ref; if (messagewithdestination->FindRef("refs", &ref) == B_OK) { BEntry entry(&ref, true); if (entry.IsDirectory()) { // if the ref received (should only be 1) is a directory // then add the drag refs to the directory AddRefsToDeskbarMenu(DragMessage(), &ref); } else SendDragMessage(NULL, &ref); } } else { // adds drag refs to top level in deskbar menu AddRefsToDeskbarMenu(DragMessage(), NULL); } // clean up drag message and types list DragStop(true); }
bool MyListView::InitiateDrag(BPoint point, int32 index, bool wasSelected) { BMessage msg(B_MIME_DATA); MyItem *item; if (wasSelected && doDrags) { item = cast_as(ItemAt(index), MyItem); const char * text = item->DragStr(); msg.AddData("text/plain", B_MIME_TYPE, text, strlen(text)); DragMessage(&msg, ItemFrame(index)); // drag an outline return true; } else { return false; } }
bool DraggableListView::InitiateDrag(BPoint point, int32 index, bool wasSelected) { uint32 buttons = Looper()->CurrentMessage()->FindInt32("buttons"); if (buttons & B_PRIMARY_MOUSE_BUTTON) { snooze(200000); BPoint new_point; uint32 buttons; GetMouse(&new_point, &buttons); bool drag = ((new_point != point) && (buttons & B_PRIMARY_MOUSE_BUTTON)); if (drag && list_type == addon) { if (!wasSelected) Select(index); BRect drag_rect; int32 current_item = CurrentSelection(0); int32 item_count = CountItems(); drag_rect = ItemFrame(index); BMessage msg(SM_DRAG_FILTER); while (current_item < item_count) { if (ItemAt(current_item)->IsSelected()) { drag_rect = drag_rect | ItemFrame(current_item); if (list_type == filter) { msg.AddString("filter_name", ((FilterItem*)ItemAt(current_item))->Text()); msg.AddInt32("filter_id", ((FilterItem*)ItemAt(current_item))->FilterID()); } else { msg.AddString("filter_name", ((BStringItem*)ItemAt(current_item))->Text()); } } current_item++; } DragMessage(&msg, drag_rect); current_item = CurrentSelection(0); return true; } else if (list_type == filter) { BMessage app_msg(SM_PREFS_VIEW); app_msg.AddInt32("filter_id", ((FilterItem*)ItemAt(index))->FilterID()); be_app_messenger.SendMessage(&app_msg, Window()); } else { BMessage app_msg(SM_ABOUT_VIEW); app_msg.AddString("addon_name", ((BStringItem*)ItemAt(index))->Text()); be_app_messenger.SendMessage(&app_msg, Window()); } return false; } else return false; }
bool DormantNodeView::InitiateDrag( BPoint point, int32 index, bool wasSelected) { D_HOOK(("DormantNodeView::InitiateDrag()\n")); DormantNodeListItem *item = dynamic_cast<DormantNodeListItem *>(ItemAt(CurrentSelection())); if (item) { BMessage dragMsg(M_INSTANTIATE_NODE); dragMsg.AddData("which", B_RAW_TYPE, reinterpret_cast<const void *>(&item->info()), sizeof(item->info())); point -= ItemFrame(index).LeftTop(); DragMessage(&dragMsg, item->getDragBitmap(), B_OP_ALPHA, point); return true; } return false; }
void CCrossHairDragView::MouseDown(BPoint where) { // Send a message as drag message, which isn't understood // by the target. The target will respond with a // B_NOT_UNDERSTOOD message. The reply is ignored. BMessage dragMessage('!+#@'); float width = crossHair->Bounds().Width(); float height = crossHair->Bounds().Height(); SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); isDragged = true; // The drag bitmap is deleted by the system. Create a copy // of the crosshair bitmap. BBitmap *clone = CreateCloneBitmap(crossHair); DragMessage(&dragMessage, clone, B_OP_OVER, BPoint(width/2,height/2), this); }
void DataView::InitiateDrag(view_focus focus) { BMessage *drag = new BMessage(B_MIME_DATA); // Add originator and action drag->AddPointer("be:originator", this); //drag->AddString("be:clip_name", "Byte Clipping"); //drag->AddInt32("be_actions", B_TRASH_TARGET); // Add data (just like in Copy()) uint8 *data = fData + fStart; size_t length = fEnd + 1 - fStart; drag->AddData(B_FILE_MIME_TYPE, B_MIME_TYPE, data, length); if (is_valid_utf8(data, length)) drag->AddData("text/plain", B_MIME_TYPE, data, length); // get a frame that contains the whole selection - SelectionFrame() // only spans a rectangle between the start and the end point, so // we have to pass it the correct input values BRect frame; const int32 width = kBlockSize - 1; int32 first = fStart & ~width; int32 last = ((fEnd + width) & ~width) - 1; if (first == (last & ~width)) frame = SelectionFrame(focus, fStart, fEnd); else frame = SelectionFrame(focus, first, last); BRect bounds = Bounds(); if (!bounds.Contains(frame)) frame = bounds & frame; DragMessage(drag, frame, NULL); fStoredStart = fStart; fStoredEnd = fEnd; fDragMessageSize = length; }
bool ListView1::InitiateDrag(BPoint point, bool wasSelected) { printf("InitiateDrag():"); point.PrintToStream(); BRow *row=FocusRow(); if (row==NULL) return false; /* if ((CDMode==DATACD_INDEX) || (CDMode==BOOTABLECD_INDEX)) { // yes? then we are not in audio mode folderRow=new FolderRow(((FolderRow *)row)->GetFilename(), ((FolderRow *)row)->IsFolder(), ((FolderRow *)row)->GetBitmap()); } else */ if ((CDMode==AUDIOCD_INDEX) || (CDMode==CDEXTRA_INDEX)){ audioRow=new AudioRow(((AudioRow *)row)->GetTrackNumber(),((AudioRow *)row)->GetFilename(), ((AudioRow *)row)->GetPregap(), ((AudioRow *)row)->GetBytes(), ((AudioRow *)row)->GetLength()); audioRow->SetCDTitle(((AudioRow *)row)->GetCDTitle()); audioRow->SetIndexList(((AudioRow *)row)->GetIndexList()); audioRow->SetPregap(((AudioRow *)row)->GetPregap()); audioRow->SetStartFrame(((AudioRow *)row)->GetStartFrame()); audioRow->SetEndFrame(((AudioRow *)row)->GetEndFrame()); // audioRow->SetStartTime(((AudioRow *)row)->GetStartTime()); // audioRow->SetEndTime(((AudioRow *)row)->GetEndTime()); //audioRow=new AudioRow(*((AudioRow *)row)); } BMessage *message=new BMessage(LISTITEM_DROPPED); BRect rect; if (GetRowRect(row, &rect)) { void *r=(void *)row; message->AddPointer("from", r); if (!((FolderRow *)row)->IsFolder()) message->AddInt32("index", (int32)IndexOf(row)); DragMessage(message, rect); // if ((CDMode==AUDIOCD_INDEX) || (CDMode==CDEXTRA_INDEX)) // RemoveRow(IndexOf(row)); //delete row; } return true; }
bool PrefListView::InitiateDrag(BPoint point, int32 index, bool wasSelected) { BOutlineListView::InitiateDrag(point,index,wasSelected); if (wasSelected) { int idx = IndexOf(point); if (idx == B_ERROR) return false; BStringItem* item = (BStringItem*)ItemAt(idx); BRect r = ItemFrame(idx); BMessage msg('ITEM'); msg.AddInt32("Item", (int)item); msg.AddInt32("Item_nr", (int)index); msg.AddPoint("click_location", point); DragMessage( &msg, r, NULL ); return true; } return false; }
bool CTrackListView::InitiateDrag( BPoint point, int32 index, bool wasSelected) { D_HOOK(("CTrackListView::InitiateDrag()\n")); CTrackListItem *item = dynamic_cast<CTrackListItem *>(ItemAt(index)); if (item) { BMessage dragMsg(MeVDragMsg_ID); dragMsg.AddInt32("Type", DragTrack_ID); dragMsg.AddInt32("TrackID", item->GetTrackID()); dragMsg.AddInt32("Index", index); dragMsg.AddPointer("Document", m_doc); point -= ItemFrame(index).LeftTop(); DragMessage(&dragMsg, item->GetDragBitmap(), B_OP_ALPHA, point); return true; } return false; }
void SwatchView::MouseDown(BPoint where) { if (!IsEnabled()) return; // BMessage *mesg = Window()->CurrentMessage(); // int32 clicks = mesg->FindInt32("clicks"); // if (m_clicks == clicks) // SetColorWindow(ICommon, m_name, m_color, this); BPoint w2; uint32 mods; while(true) { GetMouse(&w2, &mods); if (!mods) //releasing the buttons without moving means no drag { Invoke(); return; } if (w2 != where) break; } snooze(40000); BMessage msg(B_PASTE); msg.AddData("RGBColor",B_RGB_COLOR_TYPE,(const void**)&m_color,sizeof(rgb_color)); BString s = RGBtoText(m_color); msg.AddData("text/plain",B_MIME_DATA,(const void**)s.String(),s.Length()); msg.AddString("be:types", "text/plain"); msg.AddInt32("be:actions", B_COPY_TARGET); msg.AddInt32("be:actions", B_TRASH_TARGET); BBitmap *bitmap = make_bitmap(); BPoint pt(bitmap->Bounds().Width()/2.0, bitmap->Bounds().Height()/2); DragMessage(&msg, bitmap, B_OP_ALPHA, pt, Window()); }
bool PartitionListView::InitiateDrag(BPoint rowPoint, bool wasSelected) { PartitionListRow* draggedRow = dynamic_cast<PartitionListRow*>(RowAt(rowPoint)); if (draggedRow == NULL) return false; const char* draggedPath = draggedRow->DevicePath(); if (draggedPath == NULL) return false; BRect draggedRowRect; GetRowRect(draggedRow, &draggedRowRect); BMessage dragMessage(B_MIME_DATA); dragMessage.AddData("text/plain", B_MIME_TYPE, draggedPath, strlen(draggedPath)); DragMessage(&dragMessage, draggedRowRect, NULL); return true; }
virtual bool InitiateDrag(BPoint pos, int32, bool) { BMessage msg('DATA'); for ( int c=0; CurrentSelection(c); c++ ) { TrackItem * item = dynamic_cast<TrackItem*>( CurrentSelection(c) ); if ( item ) { // item is a TrackItem msg.AddRef("refs",item->GetTrack()->GetEntry() ); } else { // item is an album or an artist, find out which and add all below EachItemUnder( CurrentSelection(c), false, each_adder, &msg); } } BRect dragrect(-20,-5,20,5); dragrect.OffsetTo( pos ); DragMessage(&msg, dragrect ); return true; };
// InitiateDrag bool DragSortableListView::InitiateDrag(BPoint point, int32 index, bool) { // supress drag&drop while an item is focused if (fFocusedIndex >= 0) return false; bool success = false; BListItem* item = ItemAt(CurrentSelection(0)); if (!item) { // workarround a timing problem Select(index); item = ItemAt(index); } if (item) { // create drag message BMessage msg(fDragCommand); MakeDragMessage(&msg); // figure out drag rect float width = Bounds().Width(); BRect dragRect(0.0, 0.0, width, -1.0); // figure out, how many items fit into our bitmap int32 numItems; bool fade = false; for (numItems = 0; BListItem* item = ItemAt(CurrentSelection(numItems)); numItems++) { dragRect.bottom += ceilf(item->Height()) + 1.0; if (dragRect.Height() > MAX_DRAG_HEIGHT) { fade = true; dragRect.bottom = MAX_DRAG_HEIGHT; numItems++; break; } } BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true); if (dragBitmap && dragBitmap->IsValid()) { if (BView *v = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW)) { dragBitmap->AddChild(v); dragBitmap->Lock(); BRect itemBounds(dragRect) ; itemBounds.bottom = 0.0; // let all selected items, that fit into our drag_bitmap, draw for (int32 i = 0; i < numItems; i++) { int32 index = CurrentSelection(i); BListItem* item = ItemAt(index); itemBounds.bottom = itemBounds.top + ceilf(item->Height()); if (itemBounds.bottom > dragRect.bottom) itemBounds.bottom = dragRect.bottom; DrawListItem(v, index, itemBounds); itemBounds.top = itemBounds.bottom + 1.0; } // make a black frame arround the edge v->SetHighColor(0, 0, 0, 255); v->StrokeRect(v->Bounds()); v->Sync(); uint8 *bits = (uint8 *)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); if (fade) { for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) { uint8 *line = bits + 3; for (uint8 *end = line + 4 * width; line < end; line += 4) *line = ALPHA; } for (int32 y = height - ALPHA / 2; y < height; y++, bits += bpr) { uint8 *line = bits + 3; for (uint8 *end = line + 4 * width; line < end; line += 4) *line = (height - y) << 1; } } else { for (int32 y = 0; y < height; y++, bits += bpr) { uint8 *line = bits + 3; for (uint8 *end = line + 4 * width; line < end; line += 4) *line = ALPHA; } } dragBitmap->Unlock(); } } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap) DragMessage(&msg, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0)); else DragMessage(&msg, dragRect.OffsetToCopy(point), this); _SetDragMessage(&msg); success = true; } return success; }
void HSVControl::MouseDown(BPoint point) { BRect plate_rect = BRect(Bounds().Width()-PLATE_WIDTH+2,2,Bounds().Width()-2,Bounds().Height()-2); if (plate_rect.Contains(point)) { // If the point is on the color-plate we drag that color. // Start a drag'n'drop session. BBitmap *dragged_map = new BBitmap(BRect(0,0,15,15),B_RGB32,TRUE); BView *dragger_view = new BView(BRect(0,0,15,15),"dragger_view",B_FOLLOW_NONE,B_WILL_DRAW); rgb_color c = ValueAsColor(); dragged_map->AddChild(dragger_view); dragged_map->Lock(); dragger_view->SetHighColor(c); dragger_view->FillRect(dragger_view->Bounds()); dragger_view->Sync(); dragged_map->Unlock(); BMessage dragger_message(B_PASTE); dragger_message.AddData("RGBColor",B_RGB_COLOR_TYPE,&c,sizeof(rgb_color)); DragMessage(&dragger_message,dragged_map,BPoint(7,7)); } else { uint32 buttons; Window()->CurrentMessage()->FindInt32("buttons",(int32*)&buttons); if (Message() != NULL) { // if invocation-message has "buttons" we should replace it if (Message()->HasInt32("buttons")) Message()->ReplaceInt32("buttons",buttons); } float previous_value = -500; float orig_h = h_value; float orig_s = s_value; float orig_v = v_value; int32 orig_x = (int32)point.x; if (modifiers() & B_LEFT_SHIFT_KEY) { float prev_h = -500; float prev_s = -500; float prev_v = -500; while (buttons) { // Change all the values linearily h_value = ((point.x-4-ramp_left_edge)/RAMP_WIDTH)*(max_value_at_1()-min_value_at_1()); h_value = min_c(h_value,max_value_at_1()); h_value = max_c(h_value,min_value_at_1()); s_value = min_value_at_2() + ((point.x-4-ramp_left_edge)/RAMP_WIDTH)*(max_value_at_2()-min_value_at_2()); s_value = min_c(s_value,max_value_at_2()); s_value = max_c(s_value,min_value_at_2()); v_value = min_value_at_3() + ((point.x-4-ramp_left_edge)/RAMP_WIDTH)*(max_value_at_3()-min_value_at_3()); v_value = min_c(v_value,max_value_at_3()); v_value = max_c(v_value,min_value_at_3()); // float red_value = max_c(0,min_c(255,(1*y_value + 0.956*i_value + 0.621*q_value))); // float green_value = max_c(0,min_c(255,(1*y_value - 0.272*i_value - 0.647*q_value))); // float blue_value = max_c(0,min_c(255,(1*y_value - 1.105*i_value + 1.702*q_value))); float red_value = 0.0; float green_value = 0.0; float blue_value = 0.0; hsv_to_rgb(h_value,s_value,v_value,&red_value,&green_value,&blue_value); value.bytes[0] = (uint8)blue_value; value.bytes[1] = (uint8)green_value; value.bytes[2] = (uint8)red_value; if ((h_value != prev_h) || (s_value != prev_s) || (v_value != prev_v)) { prev_h = h_value; prev_s = s_value; prev_v = v_value; CalcRamps(); Draw(Bounds()); } GetMouse(&point,&buttons); } } else if (modifiers() & B_LEFT_CONTROL_KEY) { float prev_h = -500; float prev_s = -500; float prev_v = -500; while (buttons) { // Change all the values proportionally h_value = orig_h - (orig_x-point.x); h_value = min_c(h_value,max_value_at_1()); h_value = max_c(h_value,min_value_at_1()); s_value = orig_s - (orig_x-point.x); s_value = min_c(s_value,max_value_at_2()); s_value = max_c(s_value,min_value_at_2()); v_value = orig_v - (orig_x-point.x); v_value = min_c(v_value,max_value_at_3()); v_value = max_c(v_value,min_value_at_3()); float red_value = 0.0; float green_value = 0.0; float blue_value = 0.0; hsv_to_rgb(h_value,s_value,v_value,&red_value,&green_value,&blue_value); value.bytes[0] = (uint8)blue_value; value.bytes[1] = (uint8)green_value; value.bytes[2] = (uint8)red_value; if ((h_value != prev_h) || (s_value != prev_s) || (v_value != prev_v)) { prev_h = h_value; prev_s = s_value; prev_v = v_value; CalcRamps(); Draw(Bounds()); } GetMouse(&point,&buttons); } } else if (((int32)(point.y / COLOR_HEIGHT)) == 0) { // Here we change the Hue-value while (buttons) { // make sure the value does not exceed limits h_value = ((point.x-4-ramp_left_edge)/RAMP_WIDTH)*(max_value_at_1()-min_value_at_1()); h_value = min_c(h_value,max_value_at_1()); h_value = max_c(h_value,min_value_at_1()); float red_value = 0.0; float green_value = 0.0; float blue_value = 0.0; hsv_to_rgb(h_value,s_value,v_value,&red_value,&green_value,&blue_value); value.bytes[0] = (uint8)blue_value; value.bytes[1] = (uint8)green_value; value.bytes[2] = (uint8)red_value; if (h_value != previous_value) { previous_value = h_value; CalcRamps(); Draw(Bounds()); } GetMouse(&point,&buttons); } } else if (((int32)(point.y / COLOR_HEIGHT)) == 1) { // Here we change the Saturation-value while (buttons) { // make sure the value does not exceed limits s_value = min_value_at_2() + ((point.x-4-ramp_left_edge)/RAMP_WIDTH)*(max_value_at_2()-min_value_at_2()); s_value = min_c(s_value,max_value_at_2()); s_value = max_c(s_value,min_value_at_2()); float red_value = 0.0; float green_value = 0.0; float blue_value = 0.0; hsv_to_rgb(h_value,s_value,v_value,&red_value,&green_value,&blue_value); value.bytes[0] = (uint8)blue_value; value.bytes[1] = (uint8)green_value; value.bytes[2] = (uint8)red_value; if (s_value != previous_value) { previous_value = s_value; CalcRamps(); Draw(Bounds()); } GetMouse(&point,&buttons); } } else if (((int32)(point.y / COLOR_HEIGHT)) == 2) { // Here we change the Value-value while (buttons) { // make sure the value does not exceed limits v_value = min_value_at_3() + ((point.x-4-ramp_left_edge)/RAMP_WIDTH)*(max_value_at_3()-min_value_at_3()); v_value = min_c(v_value,max_value_at_3()); v_value = max_c(v_value,min_value_at_3()); float red_value = 0.0; float green_value = 0.0; float blue_value = 0.0; hsv_to_rgb(h_value,s_value,v_value,&red_value,&green_value,&blue_value); value.bytes[0] = (uint8)blue_value; value.bytes[1] = (uint8)green_value; value.bytes[2] = (uint8)red_value; if (v_value != previous_value) { previous_value = v_value; CalcRamps(); Draw(Bounds()); } GetMouse(&point,&buttons); } } else { while (buttons) { // Change the alpha int32 alpha_value = (int32)(((point.x-4-ramp_left_edge)/RAMP_WIDTH)*255); alpha_value = min_c(alpha_value,255); alpha_value = max_c(alpha_value,0); value.bytes[3] = alpha_value; if (alpha_value != previous_value) { previous_value = alpha_value; CalcRamps(); Draw(Bounds()); } GetMouse(&point,&buttons); } } if (Message() != NULL) { // if invocation-message has "color" we should replace it if (Message()->HasInt32("color")) Message()->ReplaceInt32("color",value.word); } Invoke(); } }
// MouseMoved void ObjectView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) { // BRect dirty(where, where); // dirty.InsetBy(-10, -10); // Invalidate(dirty); if (dragMessage) { //printf("ObjectView::MouseMoved(BPoint(%.1f, %.1f)) - DRAG MESSAGE\n", where.x, where.y); //Window()->CurrentMessage()->PrintToStream(); } else { //printf("ObjectView::MouseMoved(BPoint(%.1f, %.1f))\n", where.x, where.y); } if (fScrolling) { BCursor cursor(kGrabCursor); SetViewCursor(&cursor); BPoint offset = fLastMousePos - where; ScrollBy(offset.x, offset.y); fLastMousePos = where + offset; } else if (fInitiatingDrag) { BPoint offset = fLastMousePos - where; if (sqrtf(offset.x * offset.x + offset.y * offset.y) > 5.0) { BMessage newDragMessage('drag'); BBitmap* dragBitmap = new BBitmap(BRect(0, 0, 40, 40), B_RGBA32, true); if (dragBitmap->Lock()) { BView* helper = new BView(dragBitmap->Bounds(), "offscreen view", B_FOLLOW_ALL, B_WILL_DRAW); dragBitmap->AddChild(helper); helper->SetDrawingMode(B_OP_ALPHA); helper->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); BRect r(helper->Bounds()); helper->SetHighColor(0, 0, 0, 128); helper->StrokeRect(r); helper->SetHighColor(200, 200, 200, 100); r.InsetBy(1, 1); helper->FillRect(r); helper->SetHighColor(0, 0, 0, 255); const char* text = B_TRANSLATE("Test"); float pos = (r.Width() - helper->StringWidth(text)) / 2; helper->DrawString(text, BPoint(pos, 25)); helper->Sync(); } DragMessage(&newDragMessage, dragBitmap, B_OP_ALPHA, B_ORIGIN, this); fInitiatingDrag = false; } } else { BCursor cursor(kMoveCursor); SetViewCursor(&cursor); if (fState && fState->IsTracking()) { BRect before = fState->Bounds(); fState->MouseMoved(where); BRect after = fState->Bounds(); BRect invalid(before | after); Invalidate(invalid); } } // SetViewCursor(); }
void BitmapView::MouseMoved( BPoint cNewPos, uint32 nCode, const BMessage* pcData ) { int32 nButtons = 0x01; Window()->CurrentMessage()->FindInt32("buttons", &nButtons); m_cLastPos = cNewPos; if ( (nButtons & 0x01) == 0 ) { return; } if ( m_bSelRectActive ) { SetDrawingMode( B_OP_INVERT ); DrawFrame( m_cSelRect, FRAME_TRANSPARENT | FRAME_THIN ); m_cSelRect.right = cNewPos.x; m_cSelRect.bottom = cNewPos.y; BRect cSelRect = m_cSelRect; if ( cSelRect.left > cSelRect.right ) { float nTmp = cSelRect.left; cSelRect.left = cSelRect.right; cSelRect.right = nTmp; } if ( cSelRect.top > cSelRect.bottom ) { float nTmp = cSelRect.top; cSelRect.top = cSelRect.bottom; cSelRect.bottom = nTmp; } BFont* pcFont = GetFont(); SetDrawingMode( B_OP_COPY ); for ( uint i = 0 ; i < m_cIcons.size() ; ++i ) { m_cIcons[i]->Select( this, cSelRect.Contains( m_cIcons[i]->GetFrame( pcFont ) ) ); } SetDrawingMode( B_OP_INVERT ); DrawFrame( m_cSelRect, FRAME_TRANSPARENT | FRAME_THIN ); Flush(); return; } if ( m_bCanDrag ) { Flush(); Icon* pcSelIcon = NULL; BRect cSelFrame( 1000000, 1000000, -1000000, -1000000 ); BFont* pcFont = GetFont(); BMessage cData(1234); for ( uint i = 0 ; i < m_cIcons.size() ; ++i ) { if ( m_cIcons[i]->m_bSelected ) { cData.AddString( "file/path", m_cIcons[i]->GetName().c_str() ); cSelFrame = cSelFrame | m_cIcons[i]->GetFrame( pcFont ); pcSelIcon = m_cIcons[i]; } } if ( pcSelIcon != NULL ) { m_cDragStartPos = cNewPos; // + cSelFrame.LeftTop() - cNewPos; if ( (cSelFrame.Width()+1.0f) * (cSelFrame.Height()+1.0f) < 12000 ) { BBitmap cDragBitmap( cSelFrame, B_RGB32, true ); BView* pcView = new BView( cSelFrame.OffsetToCopy(0,0), "", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW ); cDragBitmap.AddChild( pcView ); pcView->SetHighColor( 255, 255, 255, 0 ); pcView->FillRect( cSelFrame.OffsetToCopy(0,0) ); for ( uint i = 0 ; i < m_cIcons.size() ; ++i ) { if ( m_cIcons[i]->m_bSelected ) { m_cIcons[i]->Draw( pcView, -cSelFrame.LeftTop(), true, false ); } } cDragBitmap.Sync(); uint32* pRaster = (uint32*)cDragBitmap.Bits(); for ( int y = 0 ; y < cSelFrame.Height() + 1.0f ; ++y ) { for ( int x = 0 ; x < cSelFrame.Width()+1.0f ; ++x ) { if ( pRaster[x + y * int(cSelFrame.Width()+1.0f)] != 0x00ffffff && (pRaster[x + y * int(cSelFrame.Width()+1.0f)] & 0xff000000) == 0xff000000 ) { pRaster[x + y * int(cSelFrame.Width()+1.0f)] = (pRaster[x + y * int(cSelFrame.Width()+1.0f)] & 0x00ffffff) | 0xb0000000; } } } DragMessage( &cData, &cDragBitmap, cNewPos - cSelFrame.LeftTop() ); } else { DragMessage( &cData, cNewPos - cSelFrame.LeftTop(), cSelFrame.OffsetToCopy(0,0) ); } } m_bCanDrag = false; } Flush(); }
void PatternNrButton::MouseMoved( BPoint where, uint32 code, const BMessage *a_message) { int32 buttons; Window()->CurrentMessage()->FindInt32("buttons", &buttons); if (!buttons && fMousePressed) fMousePressed = false; if (!Value() || !buttons || !IsEnabled() || !fMousePressed ) return; // Pattern wird über ein anderes gezogen if (a_message && a_message->what=='drpt') { int32 wo = FindButtonNr( where ) - 1; if ( wo!=fMarked ) { if ( wo > -1 && (wo+1)!=Value() ) { SetHighColor( 30, 30, 30, 150 ); StrokeRoundRect( fBitmap[0][0]->Bounds().OffsetToCopy( wo * 17.0, 0.0 ), 3.0, 3.0 ); SetHighColor( 128, 128, 128, 90 ); FillRoundRect( fBitmap[0][0]->Bounds().OffsetToCopy( wo * 17.0, 0.0 ), 3.0, 3.0 ); } if (fMarked>-1) DrawBitmap( fBitmap[fMarked][Value()-1 == fMarked ? 1 : 0], BPoint( fMarked * 17.0, 0.0 ) ); fMarked = wo; } } // Keine Drop-Message -> Nummer wird herausgezogen else { BBitmap *dragBitmap = new BBitmap( BRect( 0.0, 0.0, fBitmap[0][0]->Bounds().right + 1, fBitmap[0][0]->Bounds().bottom + 1 ), B_RGBA32, true ); BView view( dragBitmap->Bounds(), 0, 0, 0 ); dragBitmap->Lock(); dragBitmap->AddChild( &view ); view.SetHighColor( B_TRANSPARENT_COLOR ); view.FillRect( view.Bounds() ); // Bitmap view.SetDrawingMode(B_OP_ALPHA); view.SetHighColor(255, 0, 0, 150); view.SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); view.DrawBitmap( fBitmap[Value()-1][1], BPoint( 0.0, 0.0 ) ); // Transparenz view.SetDrawingMode(B_OP_COPY); view.SetHighColor( B_TRANSPARENT_COLOR ); BRect bounds( Bounds() ); bounds.right = 14; bounds.bottom--; view.SetPenSize( 2 ); view.StrokeRoundRect( bounds.InsetByCopy( -2.0, -2.0), 5, 5 ); bounds.InsetBy( -1.0, -1.0); view.StrokeLine( BPoint( bounds.right, bounds.bottom ), BPoint(bounds.right - 1, bounds.bottom - 1) ); // Schatten view.SetHighColor( 0, 0, 0, 30 ); view.SetPenSize( 1.0 ); view.StrokeLine( BPoint( bounds.right, 4.0 ), BPoint( bounds.right, bounds.bottom - 3.0 ) ); view.StrokeLine( BPoint( bounds.right - 3.0, bounds.bottom ) ); view.StrokeLine( BPoint( 4.0, bounds.bottom) ); bounds.right++; bounds.bottom++; view.SetHighColor( 0, 0, 0, 10 ); view.StrokeLine( BPoint( bounds.right, 4.0 ), BPoint( bounds.right, bounds.bottom - 4.0 ) ); view.StrokeLine( BPoint( bounds.right - 4.0, bounds.bottom ) ); view.StrokeLine( BPoint( 4.0, bounds.bottom) ); view.StrokeLine( BPoint( bounds.right, bounds.bottom - 2.0 ), BPoint( bounds.right - 2.0, bounds.bottom ) ); dragBitmap->RemoveChild( &view ); dragBitmap->Unlock(); BMessage drag_message('drpt'); drag_message.AddInt32("source", Value() ); drag_message.AddInt32("be:actions", B_TRASH_TARGET); DragMessage(&drag_message, dragBitmap, B_OP_ALPHA, BPoint( where.x - (Value() - 1) * 17.0, where.y ) ); } }
void KlondikeView::MouseDown(BPoint point) { if (fMouseLock) return; fMouseLock = true; uint32 mouse; GetMouse(&point, &mouse); if (mouse == B_SECONDARY_MOUSE_BUTTON) { // stop auto-play if it's started if (fAutoPlayStarted) { fAutoPlayStarted = false; return; } if (fQuickAutoPlay) { while(MoveOneToFoundation()); Invalidate(); CheckBoard(); } else { fAutoPlayStarted = true; } return; } int hSpacing = _CardHSpacing(); short stack = (int)((point.x - hSpacing) / (CARD_WIDTH + hSpacing)); if (point.x > (stack + 1) * (CARD_WIDTH + hSpacing)) return; // stock if (point.y < 15 + CARD_HEIGHT && point.y > 15 && stack == 0 && point.x > hSpacing) { int revealed = 0; for (short i = 0; i < 24; i++) if (fStock[i]->fRevealed) revealed++; if (revealed < 24 && ++fWasteCard == 24) { fWasteCard = -1; fPoints -= 100; if (fPoints < 0) fPoints = 0; } Invalidate(); return; } // pick up a card from waste if (stack == 1 && point.y < 15 + CARD_HEIGHT) { if (fWasteCard == -1) return; if (fDoubleClick == -1) fDoubleClick = 1; else if (fDoubleClick > -1) { _MoveWasteToFoundation(); CheckBoard(); Invalidate(); fDoubleClick = -1; return; } card* picked = fStock[fWasteCard]; fPickedCard = picked; fIsWasteCardPicked = true; BMessage msg(B_SIMPLE_DATA); msg.AddPointer("view", this); BBitmap* img = new BBitmap( fCards[picked->fColor * CARDS_IN_SUIT + picked->fValue]); DragMessage(&msg, img, B_OP_BLEND, BPoint((int)(point.x - hSpacing) % (CARD_WIDTH + hSpacing), point.y - 15)); Invalidate(); return; } // pick up a card from a foundation if (stack > 2 && stack < 7 && point.y < 15 + CARD_HEIGHT) { short foundation = stack - 3; short value = fFoundations[foundation]; short color = fFoundationsColors[foundation]; if (fFoundations[foundation] == -1) return; // find picked card for (short i = 0; i < CARDS_IN_DECK; i++) { if (fAllCards[i]->fValue == value && fAllCards[i]->fColor == color) fPickedCard = fAllCards[i]; } BMessage msg(B_SIMPLE_DATA); msg.AddPointer("view", this); BBitmap* img = new BBitmap( fCards[fPickedCard->fColor * CARDS_IN_SUIT + fPickedCard->fValue]); fIsFoundationCardPicked = true; fPickedCardBoardPos = foundation; fFoundations[foundation]--; DragMessage(&msg, img, B_OP_BLEND, BPoint((int)(point.x - hSpacing) % (CARD_WIDTH + hSpacing), point.y - 15)); Invalidate(); return; } // pick up a stack if (stack < 7 && fBoard[stack] != NULL && point.x > hSpacing && point.y > 2 * 15 + CARD_HEIGHT) { // find clicked on card int cardNumber = 1; card* picked = fBoard[stack]; while (picked->fNextCard != NULL) { if (point.y - 18 * cardNumber - CARD_HEIGHT - 15 < 18) { break; } picked = picked->fNextCard; cardNumber++; } if (picked->fNextCard == NULL) { // on last card, if below than not clicking on card if (point.y - 18 * cardNumber - CARD_HEIGHT - 15 >= CARD_HEIGHT) { return; } if (fDoubleClick == -1) fDoubleClick = 1; else if (fDoubleClick > -1 && fAutoPlayEnabled) { MoveOneToFoundation(stack, stack); CheckBoard(); Invalidate(); fDoubleClick = -1; return; } } if (picked->fRevealed == false) return; card* currentCard = picked->fNextCard; card* lastCard = picked; short pickedHeight = 1; for (short i = 1; currentCard != NULL; i++) { pickedHeight++; if (lastCard->fIsColorRed == currentCard->fIsColorRed) return; lastCard = currentCard; currentCard = currentCard->fNextCard; } fPickedCardBoardPos = stack; fPickedCard = picked; fIsCardPicked = true; _RemoveCardFromPile(stack, picked); BMessage msg(B_SIMPLE_DATA); msg.AddPointer("view", this); BBitmap* img; if (pickedHeight == 1) img = new BBitmap( fCards[picked->fColor * CARDS_IN_SUIT + picked->fValue]); else { img = new BBitmap(BRect(0, 0, CARD_WIDTH - 1, CARD_HEIGHT + (pickedHeight - 1) * 18), fBack[0]->ColorSpace(), true); BView* imgView = new BView(img->Bounds(), NULL, 0, 0); BRect destRect = fBack[0]->Bounds(); img->AddChild(imgView); img->Lock(); currentCard = picked; imgView->SetDrawingMode(B_OP_COPY); imgView->DrawBitmap(fCards [currentCard->fColor * CARDS_IN_SUIT + currentCard->fValue], destRect); destRect.top = (pickedHeight - 1) * 18; destRect.bottom = destRect.top + CARD_HEIGHT; imgView->DrawBitmap(fBack[0], destRect); // we don't know the top card yet, so we'll overwrite this imgView->SetDrawingMode(B_OP_ALPHA); for (short j = 0; j < pickedHeight; j++) { destRect.top = j * 18; destRect.bottom = destRect.top + CARD_HEIGHT; imgView->DrawBitmap(fCards[currentCard->fColor * CARDS_IN_SUIT + currentCard->fValue], destRect); currentCard = currentCard->fNextCard; } imgView->Sync(); img->Unlock(); img->RemoveChild(imgView); delete imgView; } DragMessage(&msg, img, B_OP_BLEND, BPoint((int)(point.x - hSpacing) % (CARD_WIDTH + hSpacing), point.y - cardNumber * 18 - 131)); Invalidate(); } }
void GameView::MouseDown(BPoint point) { if(mouselock) return; mouselock=true; card* card=NULL; short row=0; short stack=0; short saved=-1; bool special=false; for (short i=8;i<200;i++) { BPoint pt(85*(stack+1),40*(row+4)); BRect rect(pt,BPoint(pt.x+80,pt.y+116)); if (board[i]!=NULL) { if (rect.Contains(point)) { saved=i; } } row++; if (row==26) { row=0; stack++; } } BPoint deckPoints[]={ BPoint(-80,4),BPoint(-80,116),BPoint(0,116), BPoint(0,4)}; BPolygon* deck; for (short i=0;i<8;i++) { if (i==4) { for (int j=0;j<4;j++) { deckPoints[j].x+=80+4; } } for (int j=0;j<4;j++) { deckPoints[j].x+=80+4; } deck=new BPolygon(deckPoints,4); if (deck->Frame().Contains(point)) { special=true; saved=i; } } if (special) { if (saved<4) { if (board[saved]==NULL) return; selected=board[saved]; selected->oldNumber=saved; DragMessage(new BMessage(B_SIMPLE_DATA),new BBitmap(selected->img), B_OP_BLEND,BPoint(0,0)); } return; } if (saved>=0 && this->CheckStack(saved)) { short j=0; while (board[saved+j+1]!=NULL) { board[saved+j+1]->oldNumber=saved+j+1; board[saved+j]->fNextCard=board[saved+j+1]; j++; } selected=board[saved]; selected->oldNumber=saved; DragMessage(new BMessage(B_SIMPLE_DATA),new BBitmap(selected->img), B_OP_BLEND,BPoint(0,0)); } }
bool AudioListView::InitiateDrag(BPoint point, int32 dragIndex, bool) { BListItem* item = ItemAt(CurrentSelection(0)); if (item == NULL) { // workaround for a timing problem (see Locale prefs) Select(dragIndex); item = ItemAt(dragIndex); } if (item == NULL) return false; // create drag message BMessage message(kDraggedItem); for (int32 i = 0;; i++) { int32 index = CurrentSelection(i); if (index < 0) break; message.AddPointer("trackitem", ItemAt(CurrentSelection(i))); } // figure out drag rect BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0); // figure out, how many items fit into our bitmap bool fade = false; for (int32 i = 0; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)) == B_OK; i++) { dragRect.bottom += ceilf(item->Height()) + 1.0; if (dragRect.Height() > MAX_DRAG_HEIGHT) { dragRect.bottom = MAX_DRAG_HEIGHT; fade = true; break; } } BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true); if (dragBitmap->IsValid()) { BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); dragBitmap->AddChild(view); dragBitmap->Lock(); BRect itemBounds(dragRect) ; itemBounds.bottom = 0.0; // let all selected items, that fit into our drag_bitmap, draw for (int32 i = 0; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)) == B_OK; i++) { AudioListItem* item; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)); itemBounds.bottom = itemBounds.top + ceilf(item->Height()); if (itemBounds.bottom > dragRect.bottom) itemBounds.bottom = dragRect.bottom; item->DrawItem(view, itemBounds); itemBounds.top = itemBounds.bottom + 1.0; } // make a black frame around the edge view->SetHighColor(0, 0, 0, 255); view->StrokeRect(view->Bounds()); view->Sync(); uint8* bits = (uint8*)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); if (fade) { for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } for (int32 y = height - ALPHA / 2; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = (height - y) << 1; } } else { for (int32 y = 0; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } } dragBitmap->Unlock(); } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap != NULL) DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0)); else DragMessage(&message, dragRect.OffsetToCopy(point), this); return true; }