/*********************************************************** * Make outside state picture. ***********************************************************/ BPicture* HToolbarButton::MakeOutsidePicture(BBitmap *in) { HToolbar *toolbar = cast_as(Parent(),HToolbar); BRect buttonRect = toolbar->ButtonRect(); BView *view = new BView(BRect(0,0,buttonRect.Width(),buttonRect.Height()) ,"offview",0,0); BBitmap *bitmap = new BBitmap(BRect(0,0,15,15), in->ColorSpace(), true); BPicture *pict; bitmap->AddChild(view); bitmap->Lock(); view->SetDrawingMode(B_OP_ALPHA); view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); view->BeginPicture(new BPicture); DrawBitmap(view,in); DrawString(view,fName.String()); pict = view->EndPicture(); bitmap->Unlock(); delete bitmap; return pict; }
void IconView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) { if (fTracking && !fDragging && fIcon != NULL && (abs((int32)(where.x - fDragPoint.x)) > 3 || abs((int32)(where.y - fDragPoint.y)) > 3)) { // Start drag BMessage message(B_SIMPLE_DATA); ::Icon* icon = fIconData; if (fHasRef || fHasType) { icon = new ::Icon; if (fHasRef) icon->SetTo(fRef, fType.Type()); else if (fHasType) icon->SetTo(fType); } icon->CopyTo(message); if (icon != fIconData) delete icon; BBitmap *dragBitmap = new BBitmap(fIcon->Bounds(), B_RGBA32, true); dragBitmap->Lock(); BView *view = new BView(dragBitmap->Bounds(), B_EMPTY_STRING, B_FOLLOW_NONE, 0); dragBitmap->AddChild(view); view->SetHighColor(B_TRANSPARENT_COLOR); view->FillRect(dragBitmap->Bounds()); view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); view->SetDrawingMode(B_OP_ALPHA); view->SetHighColor(0, 0, 0, 160); view->DrawBitmap(fIcon); view->Sync(); dragBitmap->Unlock(); DragMessage(&message, dragBitmap, B_OP_ALPHA, fDragPoint - BitmapRect().LeftTop(), this); fDragging = true; SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); } if (dragMessage != NULL && !fDragging && AcceptsDrag(dragMessage)) { bool dropTarget = transit == B_ENTERED_VIEW || transit == B_INSIDE_VIEW; if (dropTarget != fDropTarget) { fDropTarget = dropTarget; Invalidate(); } } else if (fDropTarget) { fDropTarget = false; Invalidate(); } }
BBitmap *DragonView::_MakeDragBitmap( void ) { // If the currently displayed bitmap is too large to drag around, // we'll just drag around a rectangle. BRect drag_rect = _bits->Bounds(); if( drag_rect.Width() > _drag_max_size.x || drag_rect.Height() > _drag_max_size.y ) return NULL; // If we've got a PNG image, we'll assume that it's got // "interesting" alpha information. The ones that are built // into DragonDrop's resources all have "interesting" alpha // channels. if( _image_is_png ) { BBitmap *drag_me = new BBitmap( _bits ); memcpy( drag_me->Bits(), _bits->Bits(), _bits->BitsLength() ); return drag_me; } // If you've made it here, we'll need to build a semi-transparent image // to drag around. This magic is from Pavel Cisler, and it ensures that // you've got a drag bitmap that's translucent. BRect rect( _bits->Bounds() ); BBitmap *bitmap = new BBitmap( rect, B_RGBA32, true ); BView *view = new BView( rect, "drag view", B_FOLLOW_NONE, 0 ); bitmap->Lock(); bitmap->AddChild( view ); BRegion new_clip; new_clip.Set( rect ); view->ConstrainClippingRegion( &new_clip ); view->SetHighColor( 0, 0, 0, 0 ); view->FillRect( rect ); view->SetDrawingMode( B_OP_ALPHA ); view->SetHighColor( 0, 0, 0, 128 ); view->SetBlendingMode( B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE ); view->DrawBitmap( _bits ); view->Sync(); bitmap->Unlock(); return bitmap; }
/* * Make inside state picture. */ BPicture* HToolbarButton::MakeInsidePicture(BBitmap *in) { HToolbar *toolbar = cast_as(Parent(),HToolbar); BRect buttonRect = toolbar->ButtonRect(); BView *view = new BView(BRect(0,0,buttonRect.Width(),buttonRect.Height()) ,"offview",0,0); BBitmap *bitmap = new BBitmap(view->Bounds(), in->ColorSpace(), true); BPicture *pict; bitmap->AddChild(view); bitmap->Lock(); view->SetDrawingMode(B_OP_ALPHA); view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); view->BeginPicture(new BPicture); DrawBitmap(view,in); DrawString(view,fName.String()); //view->SetHighColor(White); //view->FillRect(BRect(0,0,0,22)); //view->FillRect(BRect(0,0,22,0)); //view->SetHighColor(BeShadow); //view->FillRect(BRect(21,0,21,21)); //view->FillRect(BRect(0,21,21,21)); BRect rect(Bounds()); view->SetDrawingMode(B_OP_OVER); rect.InsetBy(1,1); view->BeginLineArray(5); view->AddLine(rect.LeftTop(), rect.LeftBottom(), tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT)); view->AddLine(rect.LeftTop(), rect.RightTop(), tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_MAX_TINT)); view->AddLine(rect.LeftBottom(), rect.RightBottom(), tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_3_TINT)); rect.bottom--; view->AddLine(rect.LeftBottom(), rect.RightBottom(), tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT)); view->AddLine(rect.RightTop(), rect.RightBottom(), tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_3_TINT)); view->EndLineArray(); view->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_3_TINT)); view->StrokeRect(Bounds()); pict = view->EndPicture(); bitmap->Unlock(); delete bitmap; return pict; }
status_t CanvasMessage::ReadViewState(BView& view, ::pattern& pattern) { bool subPixelPrecise; float penSize, miterLimit; drawing_mode drawingMode; source_alpha sourceAlpha; alpha_function alphaFunction; cap_mode capMode; join_mode joinMode; rgb_color highColor, lowColor; Read(penSize); Read(subPixelPrecise); Read(drawingMode); Read(sourceAlpha); Read(alphaFunction); Read(pattern); Read(capMode); Read(joinMode); Read(miterLimit); Read(highColor); status_t result = Read(lowColor); if (result != B_OK) return result; uint32 flags = view.Flags() & ~B_SUBPIXEL_PRECISE; view.SetFlags(flags | (subPixelPrecise ? B_SUBPIXEL_PRECISE : 0)); view.SetPenSize(penSize); view.SetDrawingMode(drawingMode); view.SetBlendingMode(sourceAlpha, alphaFunction); view.SetLineMode(capMode, joinMode, miterLimit); view.SetHighColor(highColor); view.SetLowColor(lowColor); return B_OK; }
// 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 RemoteView::_DrawThread() { RemoteMessage reply(NULL, fSendBuffer); RemoteMessage message(fReceiveBuffer, NULL); // cursor BPoint cursorHotSpot(0, 0); while (!fStopThread) { uint16 code; status_t status = message.NextMessage(code); if (status != B_OK) { TRACE_ERROR("failed to read message from receiver\n"); break; } TRACE("code %u with %ld bytes data\n", code, message.DataLeft()); BAutolock locker(this->Looper()); if (!locker.IsLocked()) break; // handle stuff that doesn't go to a specicifc engine switch (code) { case RP_INIT_CONNECTION: { uint16 port; status_t result = message.Read(port); if (result != B_OK) { TRACE_ERROR("failed to read remote port\n"); continue; } BNetEndpoint *endpoint = fReceiver->Endpoint(); if (endpoint == NULL) { TRACE_ERROR("receiver not connected anymore\n"); continue; } in_addr remoteHost; char hostName[MAXHOSTNAMELEN + 1]; BNetAddress address(endpoint->RemoteAddr()); address.GetAddr(remoteHost); address.GetAddr(hostName, NULL); address.SetTo(remoteHost, port); TRACE("connecting to host \"%s\" port %u\n", hostName, port); result = fSendEndpoint->Connect(address); if (result != B_OK) { TRACE_ERROR("failed to connect to host \"%s\" port %u\n", hostName, port); continue; } BRect bounds = fOffscreenBitmap->Bounds(); reply.Start(RP_UPDATE_DISPLAY_MODE); reply.Add(bounds.IntegerWidth() + 1); reply.Add(bounds.IntegerHeight() + 1); if (reply.Flush() == B_OK) fIsConnected = true; continue; } case RP_CLOSE_CONNECTION: { be_app->PostMessage(B_QUIT_REQUESTED); continue; } case RP_CREATE_STATE: case RP_DELETE_STATE: { uint32 token; message.Read(token); if (code == RP_CREATE_STATE) _CreateState(token); else _DeleteState(token); continue; } case RP_SET_CURSOR: { BBitmap *bitmap; BPoint oldHotSpot = cursorHotSpot; message.Read(cursorHotSpot); if (message.ReadBitmap(&bitmap) != B_OK) continue; delete fCursorBitmap; fCursorBitmap = bitmap; Invalidate(fCursorFrame); BRect bounds = fCursorBitmap->Bounds(); fCursorFrame.right = fCursorFrame.left + bounds.IntegerWidth() + 1; fCursorFrame.bottom = fCursorFrame.bottom + bounds.IntegerHeight() + 1; fCursorFrame.OffsetBy(oldHotSpot - cursorHotSpot); Invalidate(fCursorFrame); continue; } case RP_SET_CURSOR_VISIBLE: { bool wasVisible = fCursorVisible; message.Read(fCursorVisible); if (wasVisible != fCursorVisible) Invalidate(fCursorFrame); continue; } case RP_MOVE_CURSOR_TO: { BPoint position; message.Read(position); if (fCursorVisible) Invalidate(fCursorFrame); fCursorFrame.OffsetTo(position - cursorHotSpot); Invalidate(fCursorFrame); continue; } case RP_INVALIDATE_RECT: { BRect rect; if (message.Read(rect) != B_OK) continue; Invalidate(rect); continue; } case RP_INVALIDATE_REGION: { BRegion region; if (message.ReadRegion(region) != B_OK) continue; Invalidate(®ion); continue; } case RP_FILL_REGION_COLOR_NO_CLIPPING: { BRegion region; rgb_color color; message.ReadRegion(region); if (message.Read(color) != B_OK) continue; fOffscreen->LockLooper(); fOffscreen->SetHighColor(color); fOffscreen->FillRegion(®ion); fOffscreen->UnlockLooper(); Invalidate(®ion); continue; } case RP_COPY_RECT_NO_CLIPPING: { int32 xOffset, yOffset; BRect rect; message.Read(xOffset); message.Read(yOffset); if (message.Read(rect) != B_OK) continue; BRect dest = rect.OffsetByCopy(xOffset, yOffset); fOffscreen->LockLooper(); fOffscreen->CopyBits(rect, dest); fOffscreen->UnlockLooper(); continue; } } uint32 token; message.Read(token); engine_state *state = _FindState(token); if (state == NULL) { TRACE_ERROR("didn't find state for token %lu\n", token); continue; } BView *offscreen = state->view; ::pattern &pattern = state->pattern; BRegion &clippingRegion = state->clipping_region; float &penSize = state->pen_size; bool &syncDrawing = state->sync_drawing; BRegion invalidRegion; BAutolock offscreenLocker(offscreen->Looper()); if (!offscreenLocker.IsLocked()) break; switch (code) { case RP_ENABLE_SYNC_DRAWING: syncDrawing = true; continue; case RP_DISABLE_SYNC_DRAWING: syncDrawing = false; continue; case RP_SET_OFFSETS: { int32 xOffset, yOffset; message.Read(xOffset); if (message.Read(yOffset) != B_OK) continue; offscreen->MovePenTo(xOffset, yOffset); break; } case RP_SET_HIGH_COLOR: case RP_SET_LOW_COLOR: { rgb_color color; if (message.Read(color) != B_OK) continue; if (code == RP_SET_HIGH_COLOR) offscreen->SetHighColor(color); else offscreen->SetLowColor(color); break; } case RP_SET_PEN_SIZE: { float newPenSize; if (message.Read(newPenSize) != B_OK) continue; offscreen->SetPenSize(newPenSize); penSize = newPenSize / 2; break; } case RP_SET_STROKE_MODE: { cap_mode capMode; join_mode joinMode; float miterLimit; message.Read(capMode); message.Read(joinMode); if (message.Read(miterLimit) != B_OK) continue; offscreen->SetLineMode(capMode, joinMode, miterLimit); break; } case RP_SET_BLENDING_MODE: { source_alpha sourceAlpha; alpha_function alphaFunction; message.Read(sourceAlpha); if (message.Read(alphaFunction) != B_OK) continue; offscreen->SetBlendingMode(sourceAlpha, alphaFunction); break; } case RP_SET_PATTERN: { if (message.Read(pattern) != B_OK) continue; break; } case RP_SET_DRAWING_MODE: { drawing_mode drawingMode; if (message.Read(drawingMode) != B_OK) continue; offscreen->SetDrawingMode(drawingMode); break; } case RP_SET_FONT: { BFont font; if (message.ReadFontState(font) != B_OK) continue; offscreen->SetFont(&font); break; } case RP_CONSTRAIN_CLIPPING_REGION: { if (message.ReadRegion(clippingRegion) != B_OK) continue; offscreen->ConstrainClippingRegion(&clippingRegion); break; } case RP_INVERT_RECT: { BRect rect; if (message.Read(rect) != B_OK) continue; offscreen->InvertRect(rect); invalidRegion.Include(rect); break; } case RP_DRAW_BITMAP: { BBitmap *bitmap; BRect bitmapRect, viewRect; uint32 options; message.Read(bitmapRect); message.Read(viewRect); message.Read(options); if (message.ReadBitmap(&bitmap) != B_OK || bitmap == NULL) continue; offscreen->DrawBitmap(bitmap, bitmapRect, viewRect, options); invalidRegion.Include(viewRect); delete bitmap; break; } case RP_DRAW_BITMAP_RECTS: { color_space colorSpace; int32 rectCount; uint32 flags, options; message.Read(options); message.Read(colorSpace); message.Read(flags); message.Read(rectCount); for (int32 i = 0; i < rectCount; i++) { BBitmap *bitmap; BRect viewRect; message.Read(viewRect); if (message.ReadBitmap(&bitmap, true, colorSpace, flags) != B_OK || bitmap == NULL) { continue; } offscreen->DrawBitmap(bitmap, bitmap->Bounds(), viewRect, options); invalidRegion.Include(viewRect); delete bitmap; } break; } case RP_STROKE_ARC: case RP_FILL_ARC: case RP_FILL_ARC_GRADIENT: { BRect rect; float angle, span; message.Read(rect); message.Read(angle); if (message.Read(span) != B_OK) continue; if (code == RP_STROKE_ARC) { offscreen->StrokeArc(rect, angle, span, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ARC) offscreen->FillArc(rect, angle, span, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillArc(rect, angle, span, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_BEZIER: case RP_FILL_BEZIER: case RP_FILL_BEZIER_GRADIENT: { BPoint points[4]; if (message.ReadList(points, 4) != B_OK) continue; BRect bounds = _BuildInvalidateRect(points, 4); if (code == RP_STROKE_BEZIER) { offscreen->StrokeBezier(points, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_BEZIER) offscreen->FillBezier(points, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillBezier(points, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_ELLIPSE: case RP_FILL_ELLIPSE: case RP_FILL_ELLIPSE_GRADIENT: { BRect rect; if (message.Read(rect) != B_OK) continue; if (code == RP_STROKE_ELLIPSE) { offscreen->StrokeEllipse(rect, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ELLIPSE) offscreen->FillEllipse(rect, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillEllipse(rect, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_POLYGON: case RP_FILL_POLYGON: case RP_FILL_POLYGON_GRADIENT: { BRect bounds; bool closed; int32 numPoints; message.Read(bounds); message.Read(closed); if (message.Read(numPoints) != B_OK) continue; BPoint points[numPoints]; for (int32 i = 0; i < numPoints; i++) message.Read(points[i]); if (code == RP_STROKE_POLYGON) { offscreen->StrokePolygon(points, numPoints, bounds, closed, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_POLYGON) offscreen->FillPolygon(points, numPoints, bounds, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillPolygon(points, numPoints, bounds, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_RECT: case RP_FILL_RECT: case RP_FILL_RECT_GRADIENT: { BRect rect; if (message.Read(rect) != B_OK) continue; if (code == RP_STROKE_RECT) { offscreen->StrokeRect(rect, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_RECT) offscreen->FillRect(rect, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRect(rect, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_ROUND_RECT: case RP_FILL_ROUND_RECT: case RP_FILL_ROUND_RECT_GRADIENT: { BRect rect; float xRadius, yRadius; message.Read(rect); message.Read(xRadius); if (message.Read(yRadius) != B_OK) continue; if (code == RP_STROKE_ROUND_RECT) { offscreen->StrokeRoundRect(rect, xRadius, yRadius, pattern); rect.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_ROUND_RECT) offscreen->FillRoundRect(rect, xRadius, yRadius, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRoundRect(rect, xRadius, yRadius, *gradient); delete gradient; } invalidRegion.Include(rect); break; } case RP_STROKE_SHAPE: case RP_FILL_SHAPE: case RP_FILL_SHAPE_GRADIENT: { BRect bounds; int32 opCount, pointCount; message.Read(bounds); if (message.Read(opCount) != B_OK) continue; BMessage archive; for (int32 i = 0; i < opCount; i++) { int32 op; message.Read(op); archive.AddInt32("ops", op); } if (message.Read(pointCount) != B_OK) continue; for (int32 i = 0; i < pointCount; i++) { BPoint point; message.Read(point); archive.AddPoint("pts", point); } BPoint offset; message.Read(offset); float scale; if (message.Read(scale) != B_OK) continue; offscreen->PushState(); offscreen->MovePenTo(offset); offscreen->SetScale(scale); BShape shape(&archive); if (code == RP_STROKE_SHAPE) { offscreen->StrokeShape(&shape, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_SHAPE) offscreen->FillShape(&shape, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) { offscreen->PopState(); continue; } offscreen->FillShape(&shape, *gradient); delete gradient; } offscreen->PopState(); invalidRegion.Include(bounds); break; } case RP_STROKE_TRIANGLE: case RP_FILL_TRIANGLE: case RP_FILL_TRIANGLE_GRADIENT: { BRect bounds; BPoint points[3]; message.ReadList(points, 3); if (message.Read(bounds) != B_OK) continue; if (code == RP_STROKE_TRIANGLE) { offscreen->StrokeTriangle(points[0], points[1], points[2], bounds, pattern); bounds.InsetBy(-penSize, -penSize); } else if (code == RP_FILL_TRIANGLE) { offscreen->FillTriangle(points[0], points[1], points[2], bounds, pattern); } else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillTriangle(points[0], points[1], points[2], bounds, *gradient); delete gradient; } invalidRegion.Include(bounds); break; } case RP_STROKE_LINE: { BPoint points[2]; if (message.ReadList(points, 2) != B_OK) continue; offscreen->StrokeLine(points[0], points[1], pattern); BRect bounds = _BuildInvalidateRect(points, 2); invalidRegion.Include(bounds.InsetBySelf(-penSize, -penSize)); break; } case RP_STROKE_LINE_ARRAY: { int32 numLines; if (message.Read(numLines) != B_OK) continue; BRect bounds; offscreen->BeginLineArray(numLines); for (int32 i = 0; i < numLines; i++) { rgb_color color; BPoint start, end; message.ReadArrayLine(start, end, color); offscreen->AddLine(start, end, color); bounds.left = min_c(bounds.left, min_c(start.x, end.x)); bounds.top = min_c(bounds.top, min_c(start.y, end.y)); bounds.right = max_c(bounds.right, max_c(start.x, end.x)); bounds.bottom = max_c(bounds.bottom, max_c(start.y, end.y)); } offscreen->EndLineArray(); invalidRegion.Include(bounds); break; } case RP_FILL_REGION: case RP_FILL_REGION_GRADIENT: { BRegion region; if (message.ReadRegion(region) != B_OK) continue; if (code == RP_FILL_REGION) offscreen->FillRegion(®ion, pattern); else { BGradient *gradient; if (message.ReadGradient(&gradient) != B_OK) continue; offscreen->FillRegion(®ion, *gradient); delete gradient; } invalidRegion.Include(®ion); break; } case RP_STROKE_POINT_COLOR: { BPoint point; rgb_color color; message.Read(point); if (message.Read(color) != B_OK) continue; rgb_color oldColor = offscreen->HighColor(); offscreen->SetHighColor(color); offscreen->StrokeLine(point, point); offscreen->SetHighColor(oldColor); invalidRegion.Include( BRect(point, point).InsetBySelf(-penSize, -penSize)); break; } case RP_STROKE_LINE_1PX_COLOR: { BPoint points[2]; rgb_color color; message.ReadList(points, 2); if (message.Read(color) != B_OK) continue; float oldSize = offscreen->PenSize(); rgb_color oldColor = offscreen->HighColor(); drawing_mode oldMode = offscreen->DrawingMode(); offscreen->SetPenSize(1); offscreen->SetHighColor(color); offscreen->SetDrawingMode(B_OP_OVER); offscreen->StrokeLine(points[0], points[1]); offscreen->SetDrawingMode(oldMode); offscreen->SetHighColor(oldColor); offscreen->SetPenSize(oldSize); invalidRegion.Include(_BuildInvalidateRect(points, 2)); break; } case RP_STROKE_RECT_1PX_COLOR: case RP_FILL_RECT_COLOR: { BRect rect; rgb_color color; message.Read(rect); if (message.Read(color) != B_OK) continue; rgb_color oldColor = offscreen->HighColor(); offscreen->SetHighColor(color); if (code == RP_STROKE_RECT_1PX_COLOR) { float oldSize = PenSize(); offscreen->SetPenSize(1); offscreen->StrokeRect(rect); offscreen->SetPenSize(oldSize); } else offscreen->FillRect(rect); offscreen->SetHighColor(oldColor); invalidRegion.Include(rect); break; } case RP_DRAW_STRING: { BPoint point; size_t length; char *string; bool hasDelta; message.Read(point); message.ReadString(&string, length); if (message.Read(hasDelta) != B_OK) { free(string); continue; } if (hasDelta) { escapement_delta delta[length]; message.ReadList(delta, length); offscreen->DrawString(string, point, delta); } else offscreen->DrawString(string, point); free(string); reply.Start(RP_DRAW_STRING_RESULT); reply.Add(token); reply.Add(offscreen->PenLocation()); reply.Flush(); font_height height; offscreen->GetFontHeight(&height); BRect bounds(point, offscreen->PenLocation()); bounds.top -= height.ascent; bounds.bottom += height.descent; invalidRegion.Include(bounds); break; } case RP_DRAW_STRING_WITH_OFFSETS: { size_t length; char *string; message.ReadString(&string, length); int32 count = UTF8CountChars(string, length); BPoint offsets[count]; if (message.ReadList(offsets, count) != B_OK) { free(string); continue; } offscreen->DrawString(string, offsets, count); free(string); reply.Start(RP_DRAW_STRING_RESULT); reply.Add(token); reply.Add(offscreen->PenLocation()); reply.Flush(); BFont font; offscreen->GetFont(&font); BRect boxes[count]; font.GetBoundingBoxesAsGlyphs(string, count, B_SCREEN_METRIC, boxes); font_height height; offscreen->GetFontHeight(&height); for (int32 i = 0; i < count; i++) { // TODO: validate boxes[i].OffsetBy(offsets[i] + BPoint(0, -height.ascent)); invalidRegion.Include(boxes[i]); } break; } case RP_READ_BITMAP: { BRect bounds; bool drawCursor; message.Read(bounds); if (message.Read(drawCursor) != B_OK) continue; // TODO: support the drawCursor flag BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_RGB32); bitmap.ImportBits(fOffscreenBitmap, bounds.LeftTop(), BPoint(0, 0), bounds.IntegerWidth() + 1, bounds.IntegerHeight() + 1); reply.Start(RP_READ_BITMAP_RESULT); reply.Add(token); reply.AddBitmap(&bitmap); reply.Flush(); break; } default: TRACE_ERROR("unknown protocol code: %u\n", code); break; } if (syncDrawing) { offscreen->Sync(); Invalidate(&invalidRegion); } } }
/*------------------------------------------------------------------------------*\ ( ) - \*------------------------------------------------------------------------------*/ BPicture* BmToolbarButton::CreatePicture( int32 mode, float width, float height) { const char* label = mLabel.String(); BmBitmapHandle* imageHandle = TheResources->IconByName(BmString("Button_")<<mResourceName); BBitmap* image = imageHandle ? imageHandle->bitmap : NULL; // Calc icon/label positions BFont font( be_plain_font); bool showIcons = ThePrefs->GetBool( "ShowToolbarIcons", true); BmString labelMode = ThePrefs->GetString( "ShowToolbarLabel", "Bottom"); float labelWidth = (label && labelMode != "Hide") ? font.StringWidth( label) : 0; float labelHeight = (label && labelMode != "Hide") ? TheResources->FontLineHeight( &font) : 0; float iconWidth = (showIcons && image) ? image->Bounds().Width() : 0; float iconHeight = (showIcons && image) ? image->Bounds().Height() : 0; BPoint posIcon( 0,0), posLabel( 0,0); if (showIcons && (labelMode == "Left")) { // Icon + Label/Left float d = (width-(mNeedsLatch ? DIVLATCHW : 0)-DIVW-labelWidth-iconWidth)/2; posLabel = BPoint( d,(height-labelHeight)/2); posIcon = BPoint( d+DIVW+labelWidth+(mNeedsLatch ? DIVLATCHW : 0), (height-iconHeight)/2-1); } else if (showIcons && (labelMode == "Right")) { // Icon + Label/Right float d = (width-(mNeedsLatch ? DIVLATCHW : 0)-DIVW-labelWidth-iconWidth)/2; posLabel = BPoint( d+DIVW+iconWidth,(height-labelHeight)/2); posIcon = BPoint( d,(height-iconHeight)/2-1); } else if (showIcons && (labelMode == "Top")) { // Icon + Label/top float d = (height-DIVH-labelHeight-iconHeight)/2-2; posLabel = BPoint( (width-labelWidth-(mNeedsLatch ? DIVLATCHW : 0))/2, d); posIcon = BPoint( (width-iconWidth)/2-1,d+DIVH+labelHeight); } else if (showIcons && (labelMode == "Bottom")) { // Icon + Label/bottom float d = (height-DIVH-labelHeight-iconHeight)/2; posLabel = BPoint( (width-labelWidth-(mNeedsLatch ? DIVLATCHW : 0))/2, d+DIVH+iconHeight); posIcon = BPoint( (width-iconWidth)/2-1,d); } else if (!showIcons && labelMode != "Hide") { // Label only posLabel = BPoint( (width-labelWidth-(mNeedsLatch ? DIVLATCHW : 0))/2, (height-labelHeight)/2); } else if (showIcons && labelMode == "Hide") { // Icon only posIcon = BPoint( (width-iconWidth-(mNeedsLatch ? DIVLATCHW : 0))/2, (height-iconHeight)/2); } if (mNeedsLatch) { if (labelMode == "Hide") mLatchRect.Set( posIcon.x+iconWidth+2, posIcon.y+iconHeight/2-LATCHSZ/2, width, height); else mLatchRect.Set( posLabel.x+labelWidth+2, posLabel.y+labelHeight/2-LATCHSZ/2, width, height); } else mLatchRect.Set( -1, -1, -1, -1); // Draw BRect rect(0,0,width-1,height-1); BView* view = new BView( rect, NULL, B_FOLLOW_NONE, 0); BBitmap* drawImage = new BBitmap( rect, B_RGBA32, true); drawImage->AddChild( view); drawImage->Lock(); BPicture* picture = new BPicture(); view->BeginPicture( picture); view->SetHighColor( ui_color( B_PANEL_TEXT_COLOR)); view->SetViewColor( B_TRANSPARENT_COLOR); view->SetLowColor( ui_color( B_PANEL_BACKGROUND_COLOR)); #ifndef __HAIKU__ BmToolbar* toolbar = dynamic_cast<BmToolbar*>(Parent()->Parent()); BBitmap* toolbarBackground = NULL; if (toolbar) { toolbarBackground = toolbar->BackgroundBitmap(); if (toolbarBackground) view->DrawBitmap( toolbarBackground, Frame(), rect); } if (mode == STATE_ON) { rect.InsetBy( 1, 1); view->BeginLineArray(4); view->AddLine( rect.LeftBottom(), rect.LeftTop(), BmWeakenColor(B_SHADOW_COLOR, BeShadowMod)); view->AddLine( rect.LeftTop(), rect.RightTop(), BmWeakenColor(B_SHADOW_COLOR, BeShadowMod)); view->AddLine( rect.LeftBottom(), rect.RightBottom(), ui_color( B_SHINE_COLOR)); view->AddLine( rect.RightBottom(), rect.RightTop(), ui_color( B_SHINE_COLOR)); view->EndLineArray(); } #endif // Draw Icon if (showIcons && image) { view->SetDrawingMode( B_OP_ALPHA); view->SetBlendingMode( B_PIXEL_ALPHA, B_ALPHA_OVERLAY); #ifdef __HAIKU__ BBitmap disabledImage(image); if (mode == STATE_DISABLED) { image = &disabledImage; uint8* bits = (uint8*)image->Bits(); uint32 width = image->Bounds().IntegerWidth() + 1; uint32 height = image->Bounds().IntegerWidth() + 1; uint32 bpr = image->BytesPerRow(); for (uint32 y = 0; y < height; y++) { uint8* b = bits; for (uint32 x = 0; x < width; x++) { b[3] = (uint8)(((int)b[3] * 100) >> 8); b += 4; } bits += bpr; } }
void URLView::DoPersonDrag() { // Handle all of the bookmark dragging. This includes setting up // the drag message and drawing the dragged bitmap. // Set up the drag message to support both BTextView dragging (using // the e-mail address) and file dropping (to Tracker). BMessage *dragMessage = new BMessage( B_MIME_DATA ); dragMessage->AddInt32( "be:actions", B_COPY_TARGET ); dragMessage->AddString( "be:types", "application/octet-stream" ); dragMessage->AddString( "be:filetypes", "application/x-person" ); dragMessage->AddString( "be:type_descriptions", "person" ); dragMessage->AddString( "be:clip_name", Text() ); // This allows the user to drag the e-mail address into a // standard BTextView. BString email = GetImportantURL(); dragMessage->AddData( "text/plain", B_MIME_DATA, email.String(), email.Length() + 1 ); // Query for the system's icon for bookmarks. BBitmap *personIcon = new BBitmap( BRect( 0, 0, iconSize - 1, iconSize - 1 ), B_CMAP8 ); #ifdef ZETA BMimeType mime( "application/x-vnd.Be-PEPL" ); #else BMimeType mime( "application/x-person" ); #endif if( iconSize == 16 ) mime.GetIcon( personIcon, B_MINI_ICON ); else mime.GetIcon( personIcon, B_LARGE_ICON ); // Find the size of the bitmap to drag. If the text is bigger than the // icon, use that size. Otherwise, use the icon's. Center the icon // vertically in the bitmap. BRect rect = GetTextRect(); rect.right += iconSize + 4; if( (rect.bottom - rect.top) < iconSize ) { int adjustment = (int) ((iconSize - (rect.bottom - rect.top)) / 2) + 1; rect.top -= adjustment; rect.bottom += adjustment; } // Make sure the rectangle starts at 0,0. rect.bottom += 0 - rect.top; rect.top = 0; // Create the bitmap to draw the dragged image in. BBitmap *dragBitmap = new BBitmap( rect, B_RGBA32, true ); BView *dragView = new BView( rect, "Drag View", 0, 0 ); dragBitmap->Lock(); dragBitmap->AddChild( dragView ); BRect frameRect = dragView->Frame(); // Make the background of the dragged image transparent. dragView->SetHighColor( B_TRANSPARENT_COLOR ); dragView->FillRect( frameRect ); // We want 'g's, etc. to go below the underline. When the BeOS can // do underlining of any font, this code can be removed. font_height height; GetFontHeight( &height ); float descent = height.descent; // Find the vertical center of the view so we can vertically // center everything. int centerPixel = (int) ((frameRect.bottom - frameRect.top) / 2); int textCenter = (int) (descent + underlineThickness) + centerPixel; // We want to draw everything only half opaque. dragView->SetDrawingMode( B_OP_ALPHA ); dragView->SetHighColor( 0.0, 0.0, 0.0, 128.0 ); dragView->SetBlendingMode( B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE ); // Center the icon in the view. dragView->MovePenTo( BPoint( frameRect.left, centerPixel - (iconSize / 2) ) ); dragView->DrawBitmap( personIcon ); // Draw the text in the same font (size, etc.) as the link view. // Note: DrawString() draws the text at one pixel above the pen's // current y coordinate. BFont font; GetFont( &font ); dragView->SetFont( &font ); dragView->MovePenTo( BPoint( frameRect.left + iconSize + 4, textCenter ) ); dragView->DrawString( Text() ); // Be sure to flush the view buffer so everything is drawn. dragView->Flush(); dragBitmap->Unlock(); // The Person icon adds some width to the bitmap that we are // going to draw. So horizontally offset the bitmap proportionally // to where the user clicked on the link. float horiz = dragOffset.x / GetTextRect().Width(); dragOffset.x = horiz * frameRect.right; DragMessage( dragMessage, dragBitmap, B_OP_ALPHA, BPoint( dragOffset.x, (rect.Height() + underlineThickness) / 2 + 2), this ); delete dragMessage; draggedOut = true; }
void KeyboardLayoutView::MouseMoved(BPoint point, uint32 transit, const BMessage* dragMessage) { if (fKeymap == NULL) return; // prevent dragging for tertiary mouse button if ((fButtons & B_TERTIARY_MOUSE_BUTTON) != 0) return; if (dragMessage != NULL) { if (fEditable) { _InvalidateKey(fDropTarget); fDropPoint = point; _EvaluateDropTarget(point); } return; } int32 buttons; if (Window()->CurrentMessage() == NULL || Window()->CurrentMessage()->FindInt32("buttons", &buttons) != B_OK || buttons == 0) return; if (fDragKey == NULL && (fabs(point.x - fClickPoint.x) > 4 || fabs(point.y - fClickPoint.y) > 4)) { // start dragging Key* key = _KeyAt(fClickPoint); if (key == NULL) return; BRect frame = _FrameFor(key); BPoint offset = fClickPoint - frame.LeftTop(); frame.OffsetTo(B_ORIGIN); BRect rect = frame; rect.right--; rect.bottom--; BBitmap* bitmap = new BBitmap(rect, B_RGBA32, true); bitmap->Lock(); BView* view = new BView(rect, "drag", B_FOLLOW_NONE, 0); bitmap->AddChild(view); view->SetHighColor(0, 0, 0, 0); view->FillRect(view->Bounds()); view->SetDrawingMode(B_OP_ALPHA); view->SetHighColor(0, 0, 0, 128); // set the level of transparency by value view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); _DrawKey(view, frame, key, frame, false); view->Sync(); bitmap->Unlock(); BMessage drag(B_MIME_DATA); drag.AddInt32("key", key->code); char* string; int32 numBytes; fKeymap->GetChars(key->code, fModifiers, fDeadKey, &string, &numBytes); if (string != NULL) { drag.AddData("text/plain", B_MIME_DATA, string, numBytes); delete[] string; } DragMessage(&drag, bitmap, B_OP_ALPHA, offset); fDragKey = key; fDragModifiers = fModifiers; fKeyState[key->code / 8] &= ~(1 << (7 - (key->code & 7))); _InvalidateKey(key); } }