xref: /haiku/src/apps/processcontroller/ThreadBarMenuItem.cpp (revision 5e96d7d537fbec23bad4ae9b4c8e7b02e769f0c6)
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 
26 #include <stdio.h>
27 
28 
29 ThreadBarMenuItem::ThreadBarMenuItem(const char* title, thread_id thread,
30 		BMenu *menu, BMessage* msg)
31 	: BMenuItem(menu, msg), fThreadID(thread)
32 {
33 	SetLabel(title);
34 	get_thread_info(fThreadID, &fThreadInfo);
35 	fLastTime = system_time();
36 	fKernel = -1;
37 	fGrenze1 = -1;
38 	fGrenze2 = -1;
39 }
40 
41 
42 void
43 ThreadBarMenuItem::DrawContent()
44 {
45 	if (fKernel < 0)
46 		BarUpdate();
47 	DrawBar(true);
48 	Menu()->MovePenTo(ContentLocation());
49 	BMenuItem::DrawContent();
50 }
51 
52 
53 void
54 ThreadBarMenuItem::DrawBar(bool force)
55 {
56 	bool selected = IsSelected();
57 	BRect frame = Frame();
58 	BMenu* menu = Menu();
59 	frame.right -= 24;
60 	frame.left = frame.right - kBarWidth;
61 	frame.top += 3;
62 	frame.bottom = frame.top + 8;
63 	if (fKernel < 0)
64 		return;
65 
66 	if (fGrenze1 < 0)
67 		force = true;
68 
69 	if (force) {
70 		if (selected)
71 			menu->SetHighColor(gFrameColorSelected);
72 		else
73 			menu->SetHighColor(gFrameColor);
74 		menu->StrokeRect(frame);
75 	}
76 
77 	frame.InsetBy(1, 1);
78 	BRect r = frame;
79 	float grenze1 = frame.left + (frame.right - frame.left) * fKernel;
80 	float grenze2 = frame.left + (frame.right - frame.left) * (fKernel + fUser);
81 	if (grenze1 > frame.right)
82 		grenze1 = frame.right;
83 	if (grenze2 > frame.right)
84 		grenze2 = frame.right;
85 	r.right = grenze1;
86 
87 	if (!force)
88 		r.left = fGrenze1;
89 
90 	if (r.left < r.right) {
91 		if (selected)
92 			menu->SetHighColor(gKernelColorSelected);
93 		else
94 			menu->SetHighColor(gKernelColor);
95 		menu->FillRect(r);
96 	}
97 
98 	r.left = grenze1;
99 	r.right = grenze2;
100 	if (!force) {
101 		if (fGrenze2 > r.left && r.left >= fGrenze1)
102 			r.left = fGrenze2;
103 		if (fGrenze1 < r.right && r.right  <=  fGrenze2)
104 			r.right = fGrenze1;
105 	}
106 	if (r.left < r.right) {
107 		thread_info threadInfo;
108 		bool idleThread = false;
109 		if (get_thread_info(fThreadID, &threadInfo) == B_OK)
110 			idleThread = threadInfo.priority == B_IDLE_PRIORITY;
111 
112 		if (selected) {
113 			menu->SetHighColor(
114 				idleThread ? gIdleColorSelected : gUserColorSelected);
115 		} else
116 			menu->SetHighColor(idleThread ? gIdleColor : gUserColor);
117 		menu->FillRect(r);
118 	}
119 	r.left = grenze2;
120 	r.right = frame.right;
121 	if (!force)
122 		r.right = fGrenze2;
123 	if (r.left < r.right) {
124 		if (selected)
125 			menu->SetHighColor(gWhiteSelected);
126 		else
127 			menu->SetHighColor(kWhite);
128 		menu->FillRect(r);
129 	}
130 	menu->SetHighColor(kBlack);
131 	fGrenze1 = grenze1;
132 	fGrenze2 = grenze2;
133 }
134 
135 
136 void
137 ThreadBarMenuItem::GetContentSize(float* width, float* height)
138 {
139 	BMenuItem::GetContentSize(width, height);
140 //	if (*height < 16)
141 //		*height = 16;
142 	*width += 10 + kBarWidth;
143 }
144 
145 
146 void
147 ThreadBarMenuItem::Highlight(bool on)
148 {
149 	if (on) {
150 		PriorityMenu* popup = (PriorityMenu*)Submenu();
151 		if (popup)
152 			popup->Update(fThreadInfo.priority);
153 	}
154 	BMenuItem::Highlight(on);
155 }
156 
157 
158 void
159 ThreadBarMenuItem::BarUpdate()
160 {
161 	thread_info info;
162 	if (get_thread_info(fThreadID, &info) == B_OK) {
163 		bigtime_t now = system_time();
164 		fKernel = double(info.kernel_time - fThreadInfo.kernel_time) / double(now - fLastTime);
165 		fUser = double(info.user_time - fThreadInfo.user_time) / double(now - fLastTime);
166 		if (info.priority == B_IDLE_PRIORITY) {
167 			fUser += fKernel;
168 			fKernel = 0;
169 		}
170 		fThreadInfo.user_time = info.user_time;
171 		fThreadInfo.kernel_time = info.kernel_time;
172 		fLastTime = now;
173 		if (IsSelected ()) {
174 			PriorityMenu* popup = (PriorityMenu*)Submenu();
175 			if (popup && info.priority != fThreadInfo.priority)
176 				popup->Update (info.priority);
177 		}
178 		fThreadInfo.priority = info.priority;
179 	} else
180 		fKernel = -1;
181 }
182