Пример #1
0
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(&region);
				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(&region);
				fOffscreen->UnlockLooper();
				Invalidate(&region);
				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(&region, pattern);
				else {
					BGradient *gradient;
					if (message.ReadGradient(&gradient) != B_OK)
						continue;

					offscreen->FillRegion(&region, *gradient);
					delete gradient;
				}

				invalidRegion.Include(&region);
				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);
		}
	}
}
/*!	\function		ColorUpdateWindow::MessageReceived
 *	\brief			Main function
 */
void ColorUpdateWindow::MessageReceived( BMessage* in )
{
	BAlert* al = NULL;
	DebuggerPrintout* deb = NULL;
	BTextView* textView = NULL;
	BView* background = NULL;
	BMessenger* mesg = NULL;
	status_t errorCode = B_OK;
	BString currentString( this->originalString );
	rgb_color previousHighColor;
	BRect tempRect;
	switch ( in->what )
	{
		case kColorSelected:
			/* The user had make his choise. */
			/* Checking if the color has changed... */
			if ( colorControl )
			{
				currentColor = colorControl->ValueAsColor();
				if ( currentColor != originalColor )
				{
					this->dirty = true;
				}
			}
			
			/* Checking if the string has changed... */
			if ( enableEditingLabel )
			{
				if ( labelView )
				{
					// textView = ( BTextView* )labelView;	// For matter of simplicity only
					currentString.SetTo( ( ( BTextControl* )labelView )->Text() );
					
					if ( currentString != originalString )	// If there were changes
					{
						if ( ! utl_CheckStringValidity( currentString ) )
						{
							// User has changed the string to an invalid one -
							// he must correct it before proceeding
							al = new BAlert("Error detected!",
											"The string you've entered is invalid. Please correct.",
											"Ok",
											NULL,
											NULL,
											B_WIDTH_AS_USUAL,
											B_STOP_ALERT );
							if ( al ) { 
								al->Go();
								break; 		// Returning to main window
							} else {
								/* Panic! */
								exit(1);
							}						
						}	// <-- end of "if (string is not valid) "
						else
						{
							// String is valid - verify it's different
							if ( currentString != originalString )
							{
								this->dirty = true;
							}							
						}						
					}	// <-- end of "if (user changed the string)					
				}	// <-- end of "if ( BTextView exists )"
			}	// <-- end of "if (user has possibility to change the string)"
		
			// If anything has changed, send the update message. Else, send revert message.
			if ( ! messageToSend )
			{
				if ( this->dirty )
				{
					this->messageToSend = new BMessage( kColorSelected );
				} else {
					this->messageToSend = new BMessage( kColorReverted );
				}
				if ( ! this->messageToSend ) {
					/* Panic! */
					exit(1);
				}
			}
			
			// Stuff the message with needed data
			messageToSend->AddBool( "Dirty", this->dirty );
			messageToSend->AddString ( "Original string", this->originalString );
			if ( this->dirty ) {
				messageToSend->AddString("New string", currentString );
			}

			messageToSend->AddInt32( "Original color", RepresentColorAsUint32( this->originalColor ) );
			messageToSend->AddInt32( "New color", RepresentColorAsUint32( this->currentColor ) );
			
			// Send the message and close current window
			// mesg = new BMessenger( (BHandler* )target, NULL,  &errorCode );
			mesg = new BMessenger( "application/x-vnd.Hitech.Skeleton", -1, &errorCode );
			
			if ( errorCode == B_OK ) {
				
				mesg->SendMessage( messageToSend, ( BHandler* )NULL );
				
				deb = new DebuggerPrintout( "Message was sent" );
			} else {
				deb = new DebuggerPrintout( "Message wasn't sent" );
			}
			
			this->Quit();
			
			break;

		case kColorReverted:
			/* Returning to original settings */
			if ( colorControl )
			{
				colorControl->SetValue( originalColor );
				colorControl->Invoke();
			}

			if ( enableEditingLabel && this->labelView )
			{
				( (BTextControl*)this->labelView )->SetText( this->originalString.String() );
				( (BTextControl*)this->labelView )->MakeFocus( false );	// Prevent accidental change of text
			}
			
			break;
			
		case kColorChanged:
		
			// We need to reflect the change in color.
			// We'll do it using the current view's high color. For this, we need to
			// back up current high color in order to restore it later.
			background = this->FindView( "Background" );
			if ( ! background )
			{
				deb = new DebuggerPrintout( "Didn't find background!" );
				return;
			}
			previousHighColor = background->HighColor();

			background->SetHighColor( 0, 0, 1 );	// almost black
			
			tempRect = BRect( ( revertButton->Frame() ).right + 10,
							  ( revertButton->Frame() ).top,
							  ( okButton->Frame() ).left - 10,
							  ( revertButton->Frame() ).bottom );

			// Actual drawing
			if ( this->Lock() ) {
				background->SetPenSize( 1 );
				
				// Create border
				background->StrokeRoundRect( tempRect.InsetBySelf( 1, 1 ), 4, 4 );
				
				// Fill the rectangle
				background->SetHighColor( colorControl->ValueAsColor() );
				background->FillRoundRect( tempRect.InsetBySelf( 1, 1 ), 4, 4 );
				background->Flush();
				this->Flush();
				this->Unlock();	
			}		

			background->SetHighColor( previousHighColor );
			break;

		default:
			BWindow::MessageReceived( in );
	};
	
}	// <-- end of function "ColorUpdateWindow::MessageReceived"
Пример #3
0
void
TouchpadView::DrawSliders()
{
	BView* view;
	if (fOffScreenView != NULL)
		view = fOffScreenView;
	else
		view = this;

	if (!LockLooper())
		return;

	if (fOffScreenBitmap->Lock()) {
		view->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
		view->FillRect(Bounds());
		view->SetHighColor(100, 100, 100);
		view->FillRoundRect(fPadRect, 4, 4);

		int32 dragSize = 3; // half drag size

		// scroll areas
		view->SetHighColor(145, 100, 100);
		BRect rightRect(fPadRect.left + fXScrollRange,  fPadRect.top,
			fPadRect.right, fPadRect.bottom);
		view->FillRoundRect(rightRect, 4, 4);

		BRect bottomRect(fPadRect.left, fPadRect.top + fYScrollRange,
			fPadRect.right, fPadRect.bottom);
		view->FillRoundRect(bottomRect, 4, 4);

		// Stroke Rect
		view->SetHighColor(100, 100, 100);
		view->SetPenSize(2);
		view->StrokeRoundRect(fPadRect, 4, 4);

		// x scroll range line
		view->SetHighColor(200, 0, 0);
		view->StrokeLine(BPoint(fPadRect.left + fXScrollRange, fPadRect.top),
			BPoint(fPadRect.left + fXScrollRange, fPadRect.bottom));

		fXScrollDragZone = BRect(fPadRect.left + fXScrollRange - dragSize,
			fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
			fPadRect.bottom + dragSize);
		fXScrollDragZone1 = BRect(fPadRect.left + fXScrollRange - dragSize,
			fPadRect.top - dragSize, fPadRect.left + fXScrollRange + dragSize,
			fPadRect.top + dragSize);
		view->FillRect(fXScrollDragZone1);
		fXScrollDragZone2 = BRect(fPadRect.left + fXScrollRange - dragSize,
			fPadRect.bottom - dragSize,
			fPadRect.left + fXScrollRange + dragSize,
			fPadRect.bottom + dragSize);
		view->FillRect(fXScrollDragZone2);

		// y scroll range line
		view->StrokeLine(BPoint(fPadRect.left, fPadRect.top + fYScrollRange),
			BPoint(fPadRect.right, fPadRect.top  + fYScrollRange));

		fYScrollDragZone = BRect(fPadRect.left - dragSize,
			fPadRect.top + fYScrollRange - dragSize,
			fPadRect.right  + dragSize,
			fPadRect.top + fYScrollRange + dragSize);
		fYScrollDragZone1 = BRect(fPadRect.left - dragSize,
			fPadRect.top + fYScrollRange - dragSize, fPadRect.left  + dragSize,
			fPadRect.top + fYScrollRange + dragSize);
		view->FillRect(fYScrollDragZone1);
		fYScrollDragZone2 = BRect(fPadRect.right - dragSize,
			fPadRect.top + fYScrollRange - dragSize, fPadRect.right  + dragSize,
			fPadRect.top + fYScrollRange + dragSize);
		view->FillRect(fYScrollDragZone2);

		fOffScreenView->Sync();
		fOffScreenBitmap->Unlock();
		DrawBitmap(fOffScreenBitmap, B_ORIGIN);
	}

	UnlockLooper();
}