#include "NormalPulseView.h"
#include "Common.h"
#include "Pictures"
#include <Catalog.h>
#include <Bitmap.h>
#include <Dragger.h>
#include <Window.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cpu_type.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "NormalPulseView"
float
max_font_size(BFont font, const char* text, float maxSize, float maxWidth)
{
const float steps = 0.5f;
for (float size = maxSize; size > 4; size -= steps) {
font.SetSize(size);
if (font.StringWidth(text) <= maxWidth)
return size;
}
return 4;
}
NormalPulseView::NormalPulseView(BRect rect)
: PulseView(rect, "NormalPulseView"),
fHasBrandLogo(false)
{
SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
SetLowUIColor(ViewUIColor());
mode1->SetLabel(B_TRANSLATE("Mini mode"));
mode1->SetMessage(new BMessage(PV_MINI_MODE));
mode2->SetLabel(B_TRANSLATE("Deskbar mode"));
mode2->SetMessage(new BMessage(PV_DESKBAR_MODE));
DetermineVendorAndProcessor();
system_info systemInfo;
get_system_info(&systemInfo);
fCpuCount = systemInfo.cpu_count;
fProgressBars = new ProgressBar *[fCpuCount];
fCpuButtons = new CPUButton *[fCpuCount];
for (int x = 0; x < fCpuCount; x++) {
BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x,
PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH,
PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT);
char* str2 = (char *)B_TRANSLATE("CPU progress bar");
fProgressBars[x] = new ProgressBar(r, str2);
AddChild(fProgressBars[x]);
r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x,
CPUBUTTON_MLEFT + CPUBUTTON_WIDTH + 7,
CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT + 7);
char temp[4];
snprintf(temp, sizeof(temp), "%hhd", x + 1);
fCpuButtons[x] = new CPUButton(r, B_TRANSLATE("Pulse"), temp, NULL);
AddChild(fCpuButtons[x]);
}
if (fCpuCount == 1) {
fProgressBars[0]->MoveBy(-3, 12);
fCpuButtons[0]->Hide();
}
}
NormalPulseView::~NormalPulseView()
{
delete fCpuLogo;
delete[] fCpuButtons;
delete[] fProgressBars;
}
void
NormalPulseView::CalculateFontSizes()
{
BFont font;
GetFont(&font);
fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f);
if (!fHasBrandLogo)
fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f);
}
void
NormalPulseView::DetermineVendorAndProcessor()
{
system_info sys_info;
get_system_info(&sys_info);
fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8);
unsigned char *logo = BlankLogo;
#if __POWERPC__
logo = PowerPCLogo;
#elif __INTEL__
uint32 topologyNodeCount = 0;
cpu_topology_node_info* topology = NULL;
get_cpu_topology_info(NULL, &topologyNodeCount);
if (topologyNodeCount != 0)
topology = new cpu_topology_node_info[topologyNodeCount];
get_cpu_topology_info(topology, &topologyNodeCount);
for (uint32 i = 0; i < topologyNodeCount; i++) {
if (topology[i].type == B_TOPOLOGY_PACKAGE) {
switch (topology[i].data.package.vendor) {
case B_CPU_VENDOR_INTEL:
logo = IntelLogo;
break;
case B_CPU_VENDOR_AMD:
logo = AmdLogo;
break;
default:
break;
}
break;
}
}
delete[] topology;
#endif
fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8);
fHasBrandLogo = (logo != BlankLogo);
get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor));
}
void
NormalPulseView::Draw(BRect rect)
{
PushState();
SetHighColor(0, 0, 0);
BRect frame = Bounds();
frame.right--;
frame.bottom--;
StrokeRect(frame);
SetHighColor(255, 255, 255);
StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
SetHighColor(80, 80, 80);
StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
SetHighColor(96, 96, 96);
StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
SetHighColor(255, 255, 255);
StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
DrawBitmap(fCpuLogo, BPoint(10, 10));
#if __INTEL__
if (!fHasBrandLogo) {
SetDrawingMode(B_OP_OVER);
SetHighColor(240, 240, 240);
SetFontSize(fVendorFontSize);
float width = StringWidth(fVendor);
MovePenTo(10 + (32 - width / 2), 30);
DrawString(fVendor);
}
#endif
SetDrawingMode(B_OP_OVER);
SetHighColor(240, 240, 240);
SetFontSize(fProcessorFontSize);
float width = StringWidth(fProcessor);
MovePenTo(10 + (32 - width / 2), 48);
DrawString(fProcessor);
char buffer[64];
int32 cpuSpeed = get_rounded_cpu_speed();
if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0)
snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.2f GHz"), cpuSpeed / 1000.0f);
else
snprintf(buffer, sizeof(buffer), B_TRANSLATE("%ld MHz"), cpuSpeed);
BFont font;
GetFont(&font);
SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f));
width = StringWidth(buffer);
MovePenTo(10 + (32 - width / 2), 60);
DrawString(buffer);
PopState();
}
void
NormalPulseView::Pulse()
{
if (!IsHidden()) {
Update();
if (Window()->Lock()) {
for (int x = 0; x < fCpuCount; x++) {
fProgressBars[x]->Set((int32)max_c(0, cpu_times[x] * 100));
}
Sync();
Window()->Unlock();
}
}
}
void
NormalPulseView::AttachedToWindow()
{
SetFont(be_bold_font);
CalculateFontSizes();
fPreviousTime = system_time();
BMessenger messenger(Window());
mode1->SetTarget(messenger);
mode2->SetTarget(messenger);
preferences->SetTarget(messenger);
about->SetTarget(messenger);
system_info sys_info;
get_system_info(&sys_info);
if (sys_info.cpu_count >= 2) {
for (unsigned int x = 0; x < sys_info.cpu_count; x++)
cpu_menu_items[x]->SetTarget(messenger);
}
}
void
NormalPulseView::UpdateColors(BMessage *message)
{
int32 color = message->FindInt32("color");
bool fade = message->FindBool("fade");
system_info sys_info;
get_system_info(&sys_info);
for (unsigned int x = 0; x < sys_info.cpu_count; x++) {
fProgressBars[x]->UpdateColors(color, fade);
fCpuButtons[x]->UpdateColors(color);
}
}