xref: /haiku/src/apps/pulse/NormalPulseView.cpp (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
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 <Bitmap.h>
17 #include <Dragger.h>
18 #include <Window.h>
19 
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 
24 #include <cpu_type.h>
25 
26 
27 float
28 max_font_size(BFont font, const char* text, float maxSize, float maxWidth)
29 {
30 	const float steps = 0.5f;
31 
32 	for (float size = maxSize; size > 4; size -= steps) {
33 		font.SetSize(size);
34 		if (font.StringWidth(text) <= maxWidth)
35 			return size;
36 	}
37 
38 	return 4;
39 }
40 
41 
42 //	#pragma mark -
43 
44 
45 NormalPulseView::NormalPulseView(BRect rect)
46 	: PulseView(rect, "NormalPulseView"),
47 	fHasBrandLogo(false)
48 {
49 	rgb_color color = { 168, 168, 168, 0xff };
50 	SetViewColor(color);
51 	SetLowColor(color);
52 
53 	mode1->SetLabel("Mini Mode");
54 	mode1->SetMessage(new BMessage(PV_MINI_MODE));
55 	mode2->SetLabel("Deskbar Mode");
56 	mode2->SetMessage(new BMessage(PV_DESKBAR_MODE));
57 
58 	DetermineVendorAndProcessor();
59 
60 	// Allocate progress bars and button pointers
61 	system_info systemInfo;
62 	get_system_info(&systemInfo);
63 	fCpuCount = systemInfo.cpu_count;
64 	fProgressBars = new ProgressBar *[fCpuCount];
65 	fCpuButtons = new CPUButton *[fCpuCount];
66 
67 	// Set up the CPU activity bars and buttons
68 	for (int x = 0; x < fCpuCount; x++) {
69 		BRect r(PROGRESS_MLEFT, PROGRESS_MTOP + ITEM_OFFSET * x,
70 			PROGRESS_MLEFT + ProgressBar::PROGRESS_WIDTH,
71 			PROGRESS_MTOP + ITEM_OFFSET * x + ProgressBar::PROGRESS_HEIGHT);
72 		fProgressBars[x] = new ProgressBar(r, "CPU Progress Bar");
73 		AddChild(fProgressBars[x]);
74 
75 		r.Set(CPUBUTTON_MLEFT, CPUBUTTON_MTOP + ITEM_OFFSET * x,
76 			CPUBUTTON_MLEFT + CPUBUTTON_WIDTH,
77 			CPUBUTTON_MTOP + ITEM_OFFSET * x + CPUBUTTON_HEIGHT);
78 		char temp[4];
79 		sprintf(temp, "%d", x + 1);
80 		fCpuButtons[x] = new CPUButton(r, "CPUButton", temp, NULL);
81 		AddChild(fCpuButtons[x]);
82 
83 		//	If there is only 1 cpu it will be hidden below
84 		//	thus, no need to add the dragger as it will still
85 		//	be visible when replicants are turned on
86 		if (fCpuCount > 1) {
87 			BRect dragger_rect;
88 			dragger_rect = r;
89 			dragger_rect.top = dragger_rect.bottom;
90 			dragger_rect.left = dragger_rect.right;
91 			dragger_rect.bottom += 7;
92 			dragger_rect.right += 7;
93 			dragger_rect.OffsetBy(-1, -1);
94 			BDragger *dragger = new BDragger(dragger_rect, fCpuButtons[x], 0);
95 			AddChild(dragger);
96 		}
97 	}
98 
99 	if (fCpuCount == 1) {
100 		fProgressBars[0]->MoveBy(-3, 12);
101 		fCpuButtons[0]->Hide();
102 	}
103 }
104 
105 
106 NormalPulseView::~NormalPulseView()
107 {
108 	delete fCpuLogo;
109 	delete[] fCpuButtons;
110 	delete[] fProgressBars;
111 }
112 
113 
114 void
115 NormalPulseView::CalculateFontSizes()
116 {
117 	BFont font;
118 	GetFont(&font);
119 
120 	fProcessorFontSize = max_font_size(font, fProcessor, 11.0f, 46.0f);
121 
122 	if (!fHasBrandLogo)
123 		fVendorFontSize = max_font_size(font, fVendor, 13.0f, 46.0f);
124 }
125 
126 
127 void
128 NormalPulseView::DetermineVendorAndProcessor()
129 {
130 	system_info sys_info;
131 	get_system_info(&sys_info);
132 
133 	// Initialize logo
134 
135 	fCpuLogo = new BBitmap(BRect(0, 0, 63, 62), B_CMAP8);
136 	unsigned char *logo = BlankLogo;
137 
138 #if __POWERPC__
139 	logo = PowerPCLogo;
140 #endif
141 #if __INTEL__
142 
143 	switch (sys_info.cpu_type & B_CPU_x86_VENDOR_MASK) {
144 	case B_CPU_INTEL_x86:
145 		logo = IntelLogo;
146 		break;
147 
148 	case B_CPU_AMD_x86:
149 		logo = AmdLogo;
150 		break;
151 	};
152 #endif
153 
154 	fCpuLogo->SetBits(logo, fCpuLogo->BitsLength(), 0, B_CMAP8);
155 	fHasBrandLogo = (logo != BlankLogo);
156 
157 	get_cpu_type(fVendor, sizeof(fVendor), fProcessor, sizeof(fProcessor));
158 }
159 
160 
161 void
162 NormalPulseView::Draw(BRect rect)
163 {
164 	PushState();
165 
166 	// Black frame
167 	SetHighColor(0, 0, 0);
168 	BRect frame = Bounds();
169 	frame.right--;
170 	frame.bottom--;
171 	StrokeRect(frame);
172 
173 	// Bevelled edges
174 	SetHighColor(255, 255, 255);
175 	StrokeLine(BPoint(1, 1), BPoint(frame.right - 1, 1));
176 	StrokeLine(BPoint(1, 1), BPoint(1, frame.bottom - 1));
177 	SetHighColor(80, 80, 80);
178 	StrokeLine(BPoint(frame.right, 1), BPoint(frame.right, frame.bottom));
179 	StrokeLine(BPoint(2, frame.bottom), BPoint(frame.right - 1, frame.bottom));
180 
181 	// Dividing line
182 	SetHighColor(96, 96, 96);
183 	StrokeLine(BPoint(1, frame.bottom + 1), BPoint(frame.right, frame.bottom + 1));
184 	SetHighColor(255, 255, 255);
185 	StrokeLine(BPoint(1, frame.bottom + 2), BPoint(frame.right, frame.bottom + 2));
186 
187 	// Processor picture
188 	DrawBitmap(fCpuLogo, BPoint(10, 10));
189 
190 #if __INTEL__
191 	// Do nothing in the case of non-Intel CPUs - they already have a logo
192 	if (!fHasBrandLogo) {
193 		SetDrawingMode(B_OP_OVER);
194 		SetHighColor(240, 240, 240);
195 		SetFontSize(fVendorFontSize);
196 
197 		float width = StringWidth(fVendor);
198 		MovePenTo(10 + (32 - width / 2), 30);
199 		DrawString(fVendor);
200 	}
201 #endif
202 
203 	// Draw processor type and speed
204 	SetDrawingMode(B_OP_OVER);
205 	SetHighColor(240, 240, 240);
206 
207 	SetFontSize(fProcessorFontSize);
208 	float width = StringWidth(fProcessor);
209 	MovePenTo(10 + (32 - width / 2), 48);
210 	DrawString(fProcessor);
211 
212 	char buffer[64];
213 	int32 cpuSpeed = get_rounded_cpu_speed();
214 	if (cpuSpeed > 1000 && (cpuSpeed % 10) == 0)
215 		snprintf(buffer, sizeof(buffer), "%.2f GHz", cpuSpeed / 1000.0f);
216 	else
217 		snprintf(buffer, sizeof(buffer), "%ld MHz", cpuSpeed);
218 
219 	// We can't assume anymore that a CPU clock speed is always static.
220 	// Let's compute the best font size for the CPU speed string each time...
221 	BFont font;
222 	GetFont(&font);
223 	SetFontSize(max_font_size(font, buffer, fProcessorFontSize, 46.0f));
224 	width = StringWidth(buffer);
225 	MovePenTo(10 + (32 - width / 2), 60);
226 	DrawString(buffer);
227 
228 	PopState();
229 }
230 
231 
232 void
233 NormalPulseView::Pulse()
234 {
235 	// Don't recalculate and redraw if this view is hidden
236 	if (!IsHidden()) {
237 		Update();
238 		if (Window()->Lock()) {
239 			// Set the value of each CPU bar
240 			for (int x = 0; x < fCpuCount; x++) {
241 				fProgressBars[x]->Set(max_c(0, cpu_times[x] * 100));
242 			}
243 
244 			Sync();
245 			Window()->Unlock();
246 		}
247 	}
248 }
249 
250 
251 void
252 NormalPulseView::AttachedToWindow()
253 {
254 	SetFont(be_bold_font);
255 	CalculateFontSizes();
256 
257 	fPreviousTime = system_time();
258 
259 	BMessenger messenger(Window());
260 	mode1->SetTarget(messenger);
261 	mode2->SetTarget(messenger);
262 	preferences->SetTarget(messenger);
263 	about->SetTarget(messenger);
264 
265 	system_info sys_info;
266 	get_system_info(&sys_info);
267 	if (sys_info.cpu_count >= 2) {
268 		for (int x = 0; x < sys_info.cpu_count; x++) {
269 			cpu_menu_items[x]->SetTarget(messenger);
270 		}
271 	}
272 }
273 
274 
275 void
276 NormalPulseView::UpdateColors(BMessage *message)
277 {
278 	int32 color = message->FindInt32("color");
279 	bool fade = message->FindBool("fade");
280 	system_info sys_info;
281 	get_system_info(&sys_info);
282 
283 	for (int x = 0; x < sys_info.cpu_count; x++) {
284 		fProgressBars[x]->UpdateColors(color, fade);
285 		fCpuButtons[x]->UpdateColors(color);
286 	}
287 }
288 
289