Beispiel #1
0
void
ActivityView::_UpdateOffscreenBitmap()
{
	BRect frame = _HistoryFrame();
	frame.OffsetTo(B_ORIGIN);

	if (fOffscreen != NULL && frame == fOffscreen->Bounds())
		return;

	delete fOffscreen;

	// create offscreen bitmap

	fOffscreen = new(std::nothrow) BBitmap(frame, B_BITMAP_ACCEPTS_VIEWS,
		B_RGB32);
	if (fOffscreen == NULL || fOffscreen->InitCheck() != B_OK) {
		delete fOffscreen;
		fOffscreen = NULL;
		return;
	}

	BView* view = new BView(frame, NULL, B_FOLLOW_NONE, B_SUBPIXEL_PRECISE);
	view->SetViewColor(fHistoryBackgroundColor);
	view->SetLowColor(view->ViewColor());
	fOffscreen->AddChild(view);
}
Beispiel #2
0
float
ActivityView::_PositionForValue(DataSource* source, DataHistory* values,
	int64 value)
{
	int64 min = source->Minimum();
	int64 max = source->Maximum();
	if (source->AdaptiveScale()) {
		int64 adaptiveMax = int64(values->MaximumValue() * 1.2);
		if (adaptiveMax < max)
			max = adaptiveMax;
	}

	if (value > max)
		value = max;
	if (value < min)
		value = min;

	float height = _HistoryFrame().Height();
	return height - (value - min) * height / (max - min);
}
Beispiel #3
0
void
ActivityView::_DrawHistory(bool drawBackground)
{
	_UpdateOffscreenBitmap();

	BView* view = this;
	if (fOffscreen != NULL) {
		fOffscreen->Lock();
		view = _OffscreenView();
	}

	BRect frame = _HistoryFrame();
	BRect outerFrame = frame.InsetByCopy(-2, -2);

	// draw the outer frame
	uint32 flags = 0;
	if (!drawBackground)
		flags |= BControlLook::B_BLEND_FRAME;
	be_control_look->DrawTextControlBorder(this, outerFrame,
		outerFrame, fLegendBackgroundColor, flags);

	// convert to offscreen view if necessary
	if (view != this)
		frame.OffsetTo(B_ORIGIN);

	view->SetLowColor(fHistoryBackgroundColor);
	view->FillRect(frame, B_SOLID_LOW);

	uint32 step = 2;
	uint32 resolution = fDrawResolution;
	if (fDrawResolution > 1) {
		step = 1;
		resolution--;
	}

	// We would get a negative number of steps which isn't a good idea.
	if (frame.IntegerWidth() <= 10)
		return;

	uint32 width = frame.IntegerWidth() - 10;
	uint32 steps = width / step;
	bigtime_t timeStep = RefreshInterval() * resolution;
	bigtime_t now = system_time();

	// Draw scale
	// TODO: add second markers?

	view->SetPenSize(1);

	rgb_color scaleColor = view->LowColor();
	uint32 average = (scaleColor.red + scaleColor.green + scaleColor.blue) / 3;
	if (average < 96)
		scaleColor = tint_color(scaleColor, B_LIGHTEN_2_TINT);
	else
		scaleColor = tint_color(scaleColor, B_DARKEN_2_TINT);

	view->SetHighColor(scaleColor);
	view->StrokeLine(BPoint(frame.left, frame.top + frame.Height() / 2),
		BPoint(frame.right, frame.top + frame.Height() / 2));

	// Draw values

	view->SetPenSize(1.5);
	BAutolock _(fSourcesLock);

	for (uint32 i = fSources.CountItems(); i-- > 0;) {
		ViewHistory* viewValues = fViewValues.ItemAt(i);
		DataSource* source = fSources.ItemAt(i);
		DataHistory* values = fValues.ItemAt(i);

		viewValues->Update(values, steps, fDrawResolution, now, timeStep,
			RefreshInterval());

		if (viewValues->Start() >= (int32)steps - 1)
			continue;

		uint32 x = viewValues->Start() * step;

		bool first = true;

		view->SetHighColor(source->Color());
		view->SetLineMode(B_BUTT_CAP, B_ROUND_JOIN);
		view->MovePenTo(B_ORIGIN);

		try {
			view->BeginLineArray(steps - viewValues->Start() - 1);

			BPoint prev;

			for (uint32 j = viewValues->Start(); j < steps; x += step, j++) {
				float y = _PositionForValue(source, values,
					viewValues->ValueAt(j));

				if (first) {
					first = false;
				} else
					view->AddLine(prev, BPoint(x, y), source->Color());

				prev.Set(x, y);
			}

		} catch (std::bad_alloc) {
			// Not enough memory to allocate the line array.
			// TODO we could try to draw using the slower but less memory
			// consuming solution using StrokeLine.
		}

		view->EndLineArray();
	}

	// TODO: add marks when an app started or quit
	view->Sync();
	if (fOffscreen != NULL) {
		fOffscreen->Unlock();
		DrawBitmap(fOffscreen, outerFrame.LeftTop());
	}
}
Beispiel #4
0
void
ActivityView::MessageReceived(BMessage* message)
{
	// if a color is dropped, use it as background
	if (message->WasDropped()) {
		rgb_color* color;
		ssize_t size;
		if (message->FindData("RGBColor", B_RGB_COLOR_TYPE, 0,
				(const void**)&color, &size) == B_OK
			&& size == sizeof(rgb_color)) {
			BPoint dropPoint = message->DropPoint();
			ConvertFromScreen(&dropPoint);

			if (_HistoryFrame().Contains(dropPoint)) {
				fHistoryBackgroundColor = *color;
				Invalidate(_HistoryFrame());
			} else {
				// check each legend color box
				BAutolock _(fSourcesLock);

				BRect legendFrame = _LegendFrame();
				for (int32 i = 0; i < fSources.CountItems(); i++) {
					BRect frame = _LegendColorFrameAt(legendFrame, i);
					if (frame.Contains(dropPoint)) {
						fSources.ItemAt(i)->SetColor(*color);
						Invalidate(_HistoryFrame());
						Invalidate(frame);
						return;
					}
				}

				if (dynamic_cast<ActivityMonitor*>(be_app) == NULL) {
					// allow background color change in the replicant only
					fLegendBackgroundColor = *color;
					SetLowColor(fLegendBackgroundColor);
					Invalidate(legendFrame);
				}
			}
			return;
		}
	}

	switch (message->what) {
		case B_ABOUT_REQUESTED:
		{
			BAboutWindow* window = new BAboutWindow(kAppName, kSignature);

			const char* authors[] = {
				"Axel Dörfler",
				NULL
			};

			window->AddCopyright(2008, "Haiku, Inc.");
			window->AddAuthors(authors);

			window->Show();

			break;
		}
		case kMsgUpdateResolution:
		{
			int32 resolution;
			if (message->FindInt32("resolution", &resolution) != B_OK)
				break;

			_UpdateResolution(resolution, false);
			break;
		}

		case kMsgTimeIntervalUpdated:
			bigtime_t interval;
			if (message->FindInt64("interval", &interval) != B_OK)
				break;

			if (interval < 10000)
				interval = 10000;

			atomic_set64(&fRefreshInterval, interval);
			break;

		case kMsgToggleDataSource:
		{
			int32 index;
			if (message->FindInt32("index", &index) != B_OK)
				break;

			const DataSource* baseSource = DataSource::SourceAt(index);
			if (baseSource == NULL)
				break;

			DataSource* source = FindDataSource(baseSource);
			if (source == NULL)
				AddDataSource(baseSource);
			else
				RemoveDataSource(baseSource);

			Invalidate();
			break;
		}

		case kMsgToggleLegend:
			fShowLegend = !fShowLegend;
			Invalidate();
			break;

		case B_MOUSE_WHEEL_CHANGED:
		{
			float deltaY = 0.0f;
			if (message->FindFloat("be:wheel_delta_y", &deltaY) != B_OK
				|| deltaY == 0.0f)
				break;

			int32 resolution = fDrawResolution;
			if (deltaY > 0)
				resolution *= 2;
			else
				resolution /= 2;

			_UpdateResolution(resolution);
			break;
		}

		default:
			BView::MessageReceived(message);
			break;
	}
}
void
ActivityView::_DrawHistory(bool drawBackground)
{
	_UpdateOffscreenBitmap();

	BView* view = this;
	if (fOffscreen != NULL) {
		fOffscreen->Lock();
		view = _OffscreenView();
	}

	BRect frame = _HistoryFrame();
	BRect outerFrame = frame.InsetByCopy(-2, -2);

	// draw the outer frame
	uint32 flags = 0;
	if (!drawBackground)
		flags |= BControlLook::B_BLEND_FRAME;
	be_control_look->DrawTextControlBorder(this, outerFrame,
		outerFrame, fLegendBackgroundColor, flags);

	// convert to offscreen view if necessary
	if (view != this)
		frame.OffsetTo(B_ORIGIN);

	view->SetLowColor(fHistoryBackgroundColor);
	view->FillRect(frame, B_SOLID_LOW);

	uint32 step = 2;
	uint32 resolution = fDrawResolution;
	if (fDrawResolution > 1) {
		step = 1;
		resolution--;
	}

	uint32 width = frame.IntegerWidth() - 10;
	uint32 steps = width / step;
	bigtime_t timeStep = RefreshInterval() * resolution;
	bigtime_t now = system_time();

	// Draw scale
	// TODO: add second markers?

	view->SetPenSize(1);

	rgb_color scaleColor = view->LowColor();
	uint32 average = (scaleColor.red + scaleColor.green + scaleColor.blue) / 3;
	if (average < 96)
		scaleColor = tint_color(scaleColor, B_LIGHTEN_2_TINT);
	else
		scaleColor = tint_color(scaleColor, B_DARKEN_2_TINT);

	view->SetHighColor(scaleColor);
	view->StrokeLine(BPoint(frame.left, frame.top + frame.Height() / 2),
		BPoint(frame.right, frame.top + frame.Height() / 2));

	// Draw values

	view->SetPenSize(1.5);
	BAutolock _(fSourcesLock);

	for (uint32 i = fSources.CountItems(); i-- > 0;) {
		ViewHistory* viewValues = fViewValues.ItemAt(i);
		DataSource* source = fSources.ItemAt(i);
		DataHistory* values = fValues.ItemAt(i);

		viewValues->Update(values, steps, fDrawResolution, now, timeStep,
			RefreshInterval());

		uint32 x = viewValues->Start() * step;
		BShape shape;
		bool first = true;

		for (uint32 i = viewValues->Start(); i < steps; x += step, i++) {
			float y = _PositionForValue(source, values,
				viewValues->ValueAt(i));

			if (first) {
				shape.MoveTo(BPoint(x, y));
				first = false;
			} else
				shape.LineTo(BPoint(x, y));
		}

		view->SetHighColor(source->Color());
		view->SetLineMode(B_BUTT_CAP, B_ROUND_JOIN);
		view->MovePenTo(B_ORIGIN);
		view->StrokeShape(&shape);
	}

	// TODO: add marks when an app started or quit
	view->Sync();
	if (fOffscreen != NULL) {
		fOffscreen->Unlock();
		DrawBitmap(fOffscreen, outerFrame.LeftTop());
	}
}