xref: /haiku/src/apps/pulse/NormalPulseView.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
54 	SetLowUIColor(ViewUIColor());
55 
56 	mode1->SetLabel(B_TRANSLATE("Mini mode"));
57 	mode1->SetMessage(new BMessage(PV_MINI_MODE));
58 	mode2->SetLabel(B_TRANSLATE("Deskbar mode"));
59 	mode2->SetMessage(new BMessage(PV_DESKBAR_MODE));
60 
61 	DetermineVendorAndProcessor();
62 
63 	// Allocate progress bars and button pointers
64 	system_info systemInfo;
65 	get_system_info(&systemInfo);
66 	fCpuCount = systemInfo.cpu_count;
67 	fProgressBars = new ProgressBar *[fCpuCount];
68 	fCpuButtons = new CPUButton *[fCpuCount];
69 
70 	// Set up the CPU activity bars and buttons
71 	for (int x = 0; x < fCpuCount; x++) {
72 		BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x,
73 			PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH,
74 			PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT);
75 		char* str2 = (char *)B_TRANSLATE("CPU progress bar");
76 		fProgressBars[x] = new ProgressBar(r, str2);
77 		AddChild(fProgressBars[x]);
78 
79 		r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x,
80 			CPUBUTTON_MLEFT + CPUBUTTON_WIDTH + 7,
81 			CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT + 7);
82 		char temp[4];
83 		snprintf(temp, sizeof(temp), "%hhd", x + 1);
84 		fCpuButtons[x] = new CPUButton(r, B_TRANSLATE("Pulse"), temp, NULL);
85 		AddChild(fCpuButtons[x]);
86 	}
87 
88 	if (fCpuCount == 1) {
89 		fProgressBars[0]->MoveBy(-3, 12);
90 		fCpuButtons[0]->Hide();
91 	}
92 }
93 
94 
95 NormalPulseView::~NormalPulseView()
96 {
97 	delete fCpuLogo;
98 	delete[] fCpuButtons;
99 	delete[] fProgressBars;
100 }
101 
102 
103 void
104 NormalPulseView::CalculateFontSizes()
105 {
106 	BFont font;
107 	GetFont(&font);
108 
109 	fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f);
110 
111 	if (!fHasBrandLogo)
112 		fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f);
113 }
114 
115 
116 void
117 NormalPulseView::DetermineVendorAndProcessor()
118 {
119 	system_info sys_info;
120 	get_system_info(&sys_info);
121 
122 	// Initialize logo
123 
124 	fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8);
125 	unsigned char *logo = BlankLogo;
126 
127 #if __POWERPC__
128 	logo = PowerPCLogo;
129 #elif __INTEL__
130 	uint32 topologyNodeCount = 0;
131 	cpu_topology_node_info* topology = NULL;
132 
133 	get_cpu_topology_info(NULL, &topologyNodeCount);
134 	if (topologyNodeCount != 0)
135 		topology = new cpu_topology_node_info[topologyNodeCount];
136 	get_cpu_topology_info(topology, &topologyNodeCount);
137 
138 	for (uint32 i = 0; i < topologyNodeCount; i++) {
139 		if (topology[i].type == B_TOPOLOGY_PACKAGE) {
140 			switch (topology[i].data.package.vendor) {
141 				case B_CPU_VENDOR_INTEL:
142 					logo = IntelLogo;
143 					break;
144 
145 				case B_CPU_VENDOR_AMD:
146 					logo = AmdLogo;
147 					break;
148 
149 				default:
150 					break;
151 			}
152 
153 			break;
154 		}
155 	}
156 
157 	delete[] topology;
158 #endif
159 
160 	fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8);
161 	fHasBrandLogo = (logo != BlankLogo);
162 
163 	get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor));
164 }
165 
166 
167 void
168 NormalPulseView::Draw(BRect rect)
169 {
170 	PushState();
171 
172 	// Black frame
173 	SetHighColor(0, 0, 0);
174 	BRect frame = Bounds();
175 	frame.right--;
176 	frame.bottom--;
177 	StrokeRect(frame);
178 
179 	// Bevelled edges
180 	SetHighColor(255, 255, 255);
181 	StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
182 	StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
183 	SetHighColor(80, 80, 80);
184 	StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
185 	StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
186 
187 	// Dividing line
188 	SetHighColor(96, 96, 96);
189 	StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
190 	SetHighColor(255, 255, 255);
191 	StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
192 
193 	// Processor picture
194 	DrawBitmap(fCpuLogo, BPoint(10, 10));
195 
196 #if __INTEL__
197 	// Do nothing in the case of non-Intel CPUs - they already have a logo
198 	if (!fHasBrandLogo) {
199 		SetDrawingMode(B_OP_OVER);
200 		SetHighColor(240, 240, 240);
201 		SetFontSize(fVendorFontSize);
202 
203 		float width = StringWidth(fVendor);
204 		MovePenTo(10 + (32 - width / 2), 30);
205 		DrawString(fVendor);
206 	}
207 #endif
208 
209 	// Draw processor type and speed
210 	SetDrawingMode(B_OP_OVER);
211 	SetHighColor(240, 240, 240);
212 
213 	SetFontSize(fProcessorFontSize);
214 	float width = StringWidth(fProcessor);
215 	MovePenTo(10 + (32 - width / 2), 48);
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), 60);
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