xref: /haiku/src/apps/pulse/NormalPulseView.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
1 //*****************************************************************************
2 //
3 //	File:		NormalPulseView.cpp
4 //
5 //	Written by:	Daniel Switkin
6 //
7 //	Copyright 1999, Be Incorporated
8 //
9 //*****************************************************************************
10 
11 
12 #include "NormalPulseView.h"
13 #include "Common.h"
14 #include "Pictures"
15 
16 #include <Catalog.h>
17 #include <Bitmap.h>
18 #include <Dragger.h>
19 #include <IconUtils.h>
20 #include <Window.h>
21 
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 
26 #include <cpu_type.h>
27 
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "NormalPulseView"
30 
31 
32 float
33 max_font_size(BFont font, const char* text, float maxSize, float maxWidth)
34 {
35 	const float steps = 0.5f;
36 
37 	for (float size = maxSize; size > 4; size -= steps) {
38 		font.SetSize(size);
39 		if (font.StringWidth(text) <= maxWidth)
40 			return size;
41 	}
42 
43 	return 4;
44 }
45 
46 
47 //	#pragma mark -
48 
49 
50 NormalPulseView::NormalPulseView(BRect rect)
51 	: PulseView(rect, "NormalPulseView"),
52 	fBrandLogo(NULL)
53 {
54 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
55 	SetLowUIColor(ViewUIColor());
56 
57 	mode1->SetLabel(B_TRANSLATE("Mini mode"));
58 	mode1->SetMessage(new BMessage(PV_MINI_MODE));
59 	mode2->SetLabel(B_TRANSLATE("Deskbar mode"));
60 	mode2->SetMessage(new BMessage(PV_DESKBAR_MODE));
61 
62 	DetermineVendorAndProcessor();
63 
64 	// Allocate progress bars and button pointers
65 	system_info systemInfo;
66 	get_system_info(&systemInfo);
67 	fCpuCount = systemInfo.cpu_count;
68 	fProgressBars = new ProgressBar *[fCpuCount];
69 	fCpuButtons = new CPUButton *[fCpuCount];
70 
71 	// Set up the CPU activity bars and buttons
72 	for (int x = 0; x < fCpuCount; x++) {
73 		BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x,
74 			PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH,
75 			PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT);
76 		char* str2 = (char *)B_TRANSLATE("CPU progress bar");
77 		fProgressBars[x] = new ProgressBar(r, str2);
78 		AddChild(fProgressBars[x]);
79 
80 		r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x,
81 			CPUBUTTON_MLEFT + CPUBUTTON_WIDTH + 7,
82 			CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT + 7);
83 		char temp[4];
84 		snprintf(temp, sizeof(temp), "%hhd", int8(x + 1));
85 		fCpuButtons[x] = new CPUButton(r, B_TRANSLATE("Pulse"), temp, NULL);
86 		AddChild(fCpuButtons[x]);
87 	}
88 
89 	if (fCpuCount == 1) {
90 		fProgressBars[0]->MoveBy(-3, 12);
91 		fCpuButtons[0]->Hide();
92 	}
93 }
94 
95 
96 NormalPulseView::~NormalPulseView()
97 {
98 	delete fCpuLogo;
99 	delete fBrandLogo;
100 	delete[] fCpuButtons;
101 	delete[] fProgressBars;
102 }
103 
104 
105 void
106 NormalPulseView::CalculateFontSizes()
107 {
108 	BFont font;
109 	GetFont(&font);
110 
111 	fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f);
112 
113 	if (fBrandLogo == NULL)
114 		fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f);
115 }
116 
117 
118 void
119 NormalPulseView::DetermineVendorAndProcessor()
120 {
121 	system_info sys_info;
122 	get_system_info(&sys_info);
123 
124 	// Initialize logo
125 
126 	fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8);
127 	fCpuLogo->SetBits(BlankLogo, fCpuLogo->BitsLength(), 0, B_CMAP8);
128 
129 	const unsigned char* logo = NULL;
130 	size_t logoSize = 0;
131 	uint32 topologyNodeCount = 0;
132 	cpu_topology_node_info* topology = NULL;
133 
134 	get_cpu_topology_info(NULL, &topologyNodeCount);
135 	if (topologyNodeCount != 0)
136 		topology = new cpu_topology_node_info[topologyNodeCount];
137 	get_cpu_topology_info(topology, &topologyNodeCount);
138 
139 	for (uint32 i = 0; i < topologyNodeCount; i++) {
140 		if (topology[i].type == B_TOPOLOGY_PACKAGE) {
141 			switch (topology[i].data.package.vendor) {
142 				case B_CPU_VENDOR_AMD:
143 					logo = kAmdLogo;
144 					logoSize = sizeof(kAmdLogo);
145 					break;
146 
147 				case B_CPU_VENDOR_CYRIX:
148 					logo = kCyrixLogo;
149 					logoSize = sizeof(kCyrixLogo);
150 					break;
151 
152 				case B_CPU_VENDOR_INTEL:
153 					logo = kIntelLogo;
154 					logoSize = sizeof(kIntelLogo);
155 					break;
156 
157 				case B_CPU_VENDOR_MOTOROLA:
158 					logo = kPowerPCLogo;
159 					logoSize = sizeof(kPowerPCLogo);
160 					break;
161 
162 				case B_CPU_VENDOR_VIA:
163 					logo = kViaLogo;
164 					logoSize = sizeof(kViaLogo);
165 					break;
166 
167 				default:
168 					break;
169 			}
170 
171 			break;
172 		}
173 	}
174 
175 	delete[] topology;
176 
177 	if (logo != NULL) {
178 		fBrandLogo = new BBitmap(BRect(0, 0, 47, 47), B_RGBA32);
179 		if (BIconUtils::GetVectorIcon(logo, logoSize, fBrandLogo) != B_OK) {
180 			delete fBrandLogo;
181 			fBrandLogo = NULL;
182 		}
183 	} else
184 		fBrandLogo = NULL;
185 
186 	get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor));
187 }
188 
189 
190 void
191 NormalPulseView::Draw(BRect rect)
192 {
193 	PushState();
194 
195 	SetDrawingMode(B_OP_OVER);
196 	// Processor picture
197 	DrawBitmap(fCpuLogo, BPoint(10, 10));
198 
199 	if (fBrandLogo != NULL) {
200 		DrawBitmap(fBrandLogo, BPoint(18, 17));
201 	} else {
202 		SetHighColor(240, 240, 240);
203 		SetFontSize(fVendorFontSize);
204 
205 		float width = StringWidth(fVendor);
206 		MovePenTo(10 + (32 - width / 2), 30);
207 		DrawString(fVendor);
208 	}
209 
210 	// Draw processor type and speed
211 	SetHighColor(240, 240, 240);
212 
213 	SetFontSize(fProcessorFontSize);
214 	float width = StringWidth(fProcessor);
215 	MovePenTo(10 + (32 - width / 2), 55);
216 	DrawString(fProcessor);
217 
218 	char buffer[64];
219 	int32 cpuSpeed = get_rounded_cpu_speed();
220 	if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0)
221 		snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.2f GHz"), cpuSpeed / 1000.0f);
222 	else
223 		snprintf(buffer, sizeof(buffer), B_TRANSLATE("%ld MHz"), cpuSpeed);
224 
225 	// We can't assume anymore that a CPU clock speed is always static.
226 	// Let's compute the best font size for the CPU speed string each time...
227 	BFont font;
228 	GetFont(&font);
229 	SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f));
230 	width = StringWidth(buffer);
231 	MovePenTo(10 + (32 - width / 2), 64);
232 	DrawString(buffer);
233 
234 	PopState();
235 }
236 
237 
238 void
239 NormalPulseView::Pulse()
240 {
241 	// Don't recalculate and redraw if this view is hidden
242 	if (!IsHidden()) {
243 		Update();
244 		if (Window()->Lock()) {
245 			// Set the value of each CPU bar
246 			for (int x = 0; x < fCpuCount; x++) {
247 				fProgressBars[x]->Set((int32)max_c(0, cpu_times[x] * 100));
248 			}
249 
250 			Sync();
251 			Window()->Unlock();
252 		}
253 	}
254 }
255 
256 
257 void
258 NormalPulseView::AttachedToWindow()
259 {
260 	SetFont(be_bold_font);
261 	CalculateFontSizes();
262 
263 	fPreviousTime = system_time();
264 
265 	BMessenger messenger(Window());
266 	mode1->SetTarget(messenger);
267 	mode2->SetTarget(messenger);
268 	preferences->SetTarget(messenger);
269 	about->SetTarget(messenger);
270 
271 	system_info sys_info;
272 	get_system_info(&sys_info);
273 	if (sys_info.cpu_count >= 2) {
274 		for (unsigned int x = 0; x < sys_info.cpu_count; x++)
275 			cpu_menu_items[x]->SetTarget(messenger);
276 	}
277 }
278 
279 
280 void
281 NormalPulseView::UpdateColors(BMessage *message)
282 {
283 	int32 color = message->FindInt32("color");
284 	bool fade = message->FindBool("fade");
285 	system_info sys_info;
286 	get_system_info(&sys_info);
287 
288 	for (unsigned int x = 0; x < sys_info.cpu_count; x++) {
289 		fProgressBars[x]->UpdateColors(color, fade);
290 		fCpuButtons[x]->UpdateColors(color);
291 	}
292 }
293 
294