xref: /haiku/src/apps/processcontroller/ThreadBarMenuItem.cpp (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 /*
2 	ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved.
3 	Copyright (C) 2004 beunited.org
4 
5 	This library is free software; you can redistribute it and/or
6 	modify it under the terms of the GNU Lesser General Public
7 	License as published by the Free Software Foundation; either
8 	version 2.1 of the License, or (at your option) any later version.
9 
10 	This library is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 	Lesser General Public License for more details.
14 
15 	You should have received a copy of the GNU Lesser General Public
16 	License along with this library; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include "ThreadBarMenuItem.h"
21 
22 #include "Colors.h"
23 #include "PriorityMenu.h"
24 #include "ProcessController.h"
25 #include "Utilities.h"
26 
27 #include <stdio.h>
28 
29 
30 ThreadBarMenuItem::ThreadBarMenuItem(const char* title, thread_id thread,
31 		BMenu *menu, BMessage* msg)
32 	: BMenuItem(menu, msg), fThreadID(thread)
33 {
34 	SetLabel(title);
35 	get_thread_info(fThreadID, &fThreadInfo);
36 	fLastTime = system_time();
37 	fKernel = -1;
38 	fGrenze1 = -1;
39 	fGrenze2 = -1;
40 }
41 
42 
43 void
44 ThreadBarMenuItem::DrawContent()
45 {
46 	if (fKernel < 0)
47 		BarUpdate();
48 	DrawBar(true);
49 	Menu()->MovePenTo(ContentLocation());
50 	BMenuItem::DrawContent();
51 }
52 
53 
54 void
55 ThreadBarMenuItem::DrawBar(bool force)
56 {
57 	bool selected = IsSelected();
58 	BRect frame = Frame();
59 	BMenu* menu = Menu();
60 	rgb_color highColor = menu->HighColor();
61 
62 	BFont font;
63 	menu->GetFont(&font);
64 	frame = bar_rect(frame, &font);
65 
66 	if (fKernel < 0)
67 		return;
68 
69 	if (fGrenze1 < 0)
70 		force = true;
71 
72 	if (force) {
73 		if (selected)
74 			menu->SetHighColor(gFrameColorSelected);
75 		else
76 			menu->SetHighColor(gFrameColor);
77 		menu->StrokeRect(frame);
78 	}
79 
80 	frame.InsetBy(1, 1);
81 	BRect r = frame;
82 	float grenze1 = frame.left + (frame.right - frame.left) * fKernel;
83 	float grenze2 = frame.left + (frame.right - frame.left) * (fKernel + fUser);
84 	if (grenze1 > frame.right)
85 		grenze1 = frame.right;
86 	if (grenze2 > frame.right)
87 		grenze2 = frame.right;
88 	r.right = grenze1;
89 
90 	if (!force)
91 		r.left = fGrenze1;
92 
93 	if (r.left < r.right) {
94 		if (selected)
95 			menu->SetHighColor(gKernelColorSelected);
96 		else
97 			menu->SetHighColor(gKernelColor);
98 		menu->FillRect(r);
99 	}
100 
101 	r.left = grenze1;
102 	r.right = grenze2;
103 	if (!force) {
104 		if (fGrenze2 > r.left && r.left >= fGrenze1)
105 			r.left = fGrenze2;
106 		if (fGrenze1 < r.right && r.right  <=  fGrenze2)
107 			r.right = fGrenze1;
108 	}
109 	if (r.left < r.right) {
110 		thread_info threadInfo;
111 		bool idleThread = false;
112 		if (get_thread_info(fThreadID, &threadInfo) == B_OK)
113 			idleThread = threadInfo.priority == B_IDLE_PRIORITY;
114 
115 		if (selected) {
116 			menu->SetHighColor(
117 				idleThread ? gIdleColorSelected : gUserColorSelected);
118 		} else
119 			menu->SetHighColor(idleThread ? gIdleColor : gUserColor);
120 		menu->FillRect(r);
121 	}
122 	r.left = grenze2;
123 	r.right = frame.right;
124 	if (!force)
125 		r.right = fGrenze2;
126 	if (r.left < r.right) {
127 		if (selected)
128 			menu->SetHighColor(gWhiteSelected);
129 		else
130 			menu->SetHighColor(kWhite);
131 		menu->FillRect(r);
132 	}
133 	menu->SetHighColor(highColor);
134 	fGrenze1 = grenze1;
135 	fGrenze2 = grenze2;
136 }
137 
138 
139 void
140 ThreadBarMenuItem::GetContentSize(float* width, float* height)
141 {
142 	BMenuItem::GetContentSize(width, height);
143 	*width += 10 + kBarWidth;
144 }
145 
146 
147 void
148 ThreadBarMenuItem::Highlight(bool on)
149 {
150 	if (on) {
151 		PriorityMenu* popup = (PriorityMenu*)Submenu();
152 		if (popup)
153 			popup->Update(fThreadInfo.priority);
154 	}
155 	BMenuItem::Highlight(on);
156 }
157 
158 
159 void
160 ThreadBarMenuItem::BarUpdate()
161 {
162 	thread_info info;
163 	if (get_thread_info(fThreadID, &info) == B_OK) {
164 		bigtime_t now = system_time();
165 		fKernel = double(info.kernel_time - fThreadInfo.kernel_time) / double(now - fLastTime);
166 		fUser = double(info.user_time - fThreadInfo.user_time) / double(now - fLastTime);
167 		if (info.priority == B_IDLE_PRIORITY) {
168 			fUser += fKernel;
169 			fKernel = 0;
170 		}
171 		fThreadInfo.user_time = info.user_time;
172 		fThreadInfo.kernel_time = info.kernel_time;
173 		fLastTime = now;
174 		if (IsSelected ()) {
175 			PriorityMenu* popup = (PriorityMenu*)Submenu();
176 			if (popup && info.priority != fThreadInfo.priority)
177 				popup->Update (info.priority);
178 		}
179 		fThreadInfo.priority = info.priority;
180 	} else
181 		fKernel = -1;
182 }
183