xref: /haiku/src/apps/pulse/NormalPulseView.cpp (revision 37fedaf8494b34aad811abcc49e79aa32943f880)
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 <Window.h>
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include <cpu_type.h>
26 
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "NormalPulseView"
29 
30 
31 float
32 max_font_size(BFont font, const char* text, float maxSize, float maxWidth)
33 {
34 	const float steps = 0.5f;
35 
36 	for (float size = maxSize; size > 4; size -= steps) {
37 		font.SetSize(size);
38 		if (font.StringWidth(text) <= maxWidth)
39 			return size;
40 	}
41 
42 	return 4;
43 }
44 
45 
46 //	#pragma mark -
47 
48 
49 NormalPulseView::NormalPulseView(BRect rect)
50 	: PulseView(rect, "NormalPulseView"),
51 	fHasBrandLogo(false)
52 {
53 	rgb_color color = { 168, 168, 168, 0xff };
54 	SetViewColor(color);
55 	SetLowColor(color);
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 		sprintf(temp, "%d", 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[] fCpuButtons;
100 	delete[] fProgressBars;
101 }
102 
103 
104 void
105 NormalPulseView::CalculateFontSizes()
106 {
107 	BFont font;
108 	GetFont(&font);
109 
110 	fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f);
111 
112 	if (!fHasBrandLogo)
113 		fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f);
114 }
115 
116 
117 void
118 NormalPulseView::DetermineVendorAndProcessor()
119 {
120 	system_info sys_info;
121 	get_system_info(&sys_info);
122 
123 	// Initialize logo
124 
125 	fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8);
126 	unsigned char *logo = BlankLogo;
127 
128 #if __POWERPC__
129 	logo = PowerPCLogo;
130 #endif
131 #if __INTEL__
132 	uint32 topologyNodeCount = 0;
133 	cpu_topology_node_info* topology = NULL;
134 
135 	get_cpu_topology_info(NULL, &topologyNodeCount);
136 	if (topologyNodeCount != 0)
137 		topology = new cpu_topology_node_info[topologyNodeCount];
138 	get_cpu_topology_info(topology, &topologyNodeCount);
139 
140 	for (uint32 i = 0; i < topologyNodeCount; i++) {
141 		if (topology[i].type == B_TOPOLOGY_PACKAGE) {
142 			switch (topology[i].data.package.vendor) {
143 				case B_CPU_VENDOR_INTEL:
144 					logo = IntelLogo;
145 					break;
146 
147 				case B_CPU_VENDOR_AMD:
148 					logo = AmdLogo;
149 					break;
150 
151 				default:
152 					break;
153 			}
154 
155 			break;
156 		}
157 	}
158 
159 	delete[] topology;
160 #endif
161 
162 	fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8);
163 	fHasBrandLogo = (logo != BlankLogo);
164 
165 	get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor));
166 }
167 
168 
169 void
170 NormalPulseView::Draw(BRect rect)
171 {
172 	PushState();
173 
174 	// Black frame
175 	SetHighColor(0, 0, 0);
176 	BRect frame = Bounds();
177 	frame.right--;
178 	frame.bottom--;
179 	StrokeRect(frame);
180 
181 	// Bevelled edges
182 	SetHighColor(255, 255, 255);
183 	StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
184 	StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
185 	SetHighColor(80, 80, 80);
186 	StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
187 	StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
188 
189 	// Dividing line
190 	SetHighColor(96, 96, 96);
191 	StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
192 	SetHighColor(255, 255, 255);
193 	StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
194 
195 	// Processor picture
196 	DrawBitmap(fCpuLogo, BPoint(10, 10));
197 
198 #if __INTEL__
199 	// Do nothing in the case of non-Intel CPUs - they already have a logo
200 	if (!fHasBrandLogo) {
201 		SetDrawingMode(B_OP_OVER);
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 #endif
210 
211 	// Draw processor type and speed
212 	SetDrawingMode(B_OP_OVER);
213 	SetHighColor(240, 240, 240);
214 
215 	SetFontSize(fProcessorFontSize);
216 	float width = StringWidth(fProcessor);
217 	MovePenTo(10 + (32 - width / 2), 48);
218 	DrawString(fProcessor);
219 
220 	char buffer[64];
221 	int32 cpuSpeed = get_rounded_cpu_speed();
222 	if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0)
223 		snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.2f GHz"), cpuSpeed / 1000.0f);
224 	else
225 		snprintf(buffer, sizeof(buffer), B_TRANSLATE("%ld MHz"), cpuSpeed);
226 
227 	// We can't assume anymore that a CPU clock speed is always static.
228 	// Let's compute the best font size for the CPU speed string each time...
229 	BFont font;
230 	GetFont(&font);
231 	SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f));
232 	width = StringWidth(buffer);
233 	MovePenTo(10 + (32 - width / 2), 60);
234 	DrawString(buffer);
235 
236 	PopState();
237 }
238 
239 
240 void
241 NormalPulseView::Pulse()
242 {
243 	// Don't recalculate and redraw if this view is hidden
244 	if (!IsHidden()) {
245 		Update();
246 		if (Window()->Lock()) {
247 			// Set the value of each CPU bar
248 			for (int x = 0; x < fCpuCount; x++) {
249 				fProgressBars[x]->Set((int32)max_c(0, cpu_times[x] * 100));
250 			}
251 
252 			Sync();
253 			Window()->Unlock();
254 		}
255 	}
256 }
257 
258 
259 void
260 NormalPulseView::AttachedToWindow()
261 {
262 	SetFont(be_bold_font);
263 	CalculateFontSizes();
264 
265 	fPreviousTime = system_time();
266 
267 	BMessenger messenger(Window());
268 	mode1->SetTarget(messenger);
269 	mode2->SetTarget(messenger);
270 	preferences->SetTarget(messenger);
271 	about->SetTarget(messenger);
272 
273 	system_info sys_info;
274 	get_system_info(&sys_info);
275 	if (sys_info.cpu_count >= 2) {
276 		for (unsigned int x = 0; x < sys_info.cpu_count; x++)
277 			cpu_menu_items[x]->SetTarget(messenger);
278 	}
279 }
280 
281 
282 void
283 NormalPulseView::UpdateColors(BMessage *message)
284 {
285 	int32 color = message->FindInt32("color");
286 	bool fade = message->FindBool("fade");
287 	system_info sys_info;
288 	get_system_info(&sys_info);
289 
290 	for (unsigned int x = 0; x < sys_info.cpu_count; x++) {
291 		fProgressBars[x]->UpdateColors(color, fade);
292 		fCpuButtons[x]->UpdateColors(color);
293 	}
294 }
295 
296