xref: /haiku/src/apps/pulse/ProgressBar.cpp (revision d382fc3a8e7edf2bb0e5e81f95bbd3ae80ea1ca0)
1 //*****************************************************************************
2 //
3 //	File:		ProgressBar.cpp
4 //
5 //	Written by:	David Ramsey and Daniel Switkin
6 //
7 //	Copyright 1999, Be Incorporated
8 //
9 //*****************************************************************************
10 
11 
12 #include "ProgressBar.h"
13 #include "PulseApp.h"
14 
15 
16 ProgressBar::ProgressBar(BRect r, char *name) :	BView(r, name, B_FOLLOW_NONE,
17 	B_WILL_DRAW)
18 {
19 	previous_value = current_value = 0;
20 
21 	// Create 20 segments
22 	float height = (r.bottom - r.top) - 8;
23 	for (int32 counter = 0; counter < 20; counter++) {
24 		segments[counter].rect.Set(r.left + (counter * 7), r.top,
25 			(r.left + (counter * 7) + 5), r.top + height);
26 		segments[counter].rect.OffsetTo(BPoint((counter * 7) + 4, 4));
27 	}
28 	SetLowColor(255, 0, 0);
29 	SetViewColor(B_TRANSPARENT_COLOR);
30 }
31 
32 
33 // New - real time updating of bar colors
34 void
35 ProgressBar::UpdateColors(int32 color, bool fade)
36 {
37 	unsigned char red = (color & 0xff000000) >> 24;
38 	unsigned char green = (color & 0x00ff0000) >> 16;
39 	unsigned char blue = (color & 0x0000ff00) >> 8;
40 
41 	if (fade) {
42 		unsigned char red_base = red / 3;
43 		unsigned char green_base = green / 3;
44 		unsigned char blue_base = blue / 3;
45 
46 		for (int x = 0; x < 20; x++) {
47 			segments[x].color.red = (uint8)(red_base + ((red - red_base)
48 				* ((float)x / 19.0)));
49 			segments[x].color.green = (uint8)(green_base
50 				+ ((green - green_base) * ((float)x / 19.0)));
51 			segments[x].color.blue = (uint8)(blue_base + ((blue - blue_base)
52 				* ((float)x / 19.0)));
53 			segments[x].color.alpha = 0xff;
54 		}
55 	} else {
56 		for (int x = 0; x < 20; x++) {
57 			segments[x].color.red = red;
58 			segments[x].color.green = green;
59 			segments[x].color.blue = blue;
60 			segments[x].color.alpha = 0xff;
61 		}
62 	}
63 	Render(true);
64 }
65 
66 
67 void
68 ProgressBar::AttachedToWindow()
69 {
70 	Prefs *prefs = ((PulseApp *)be_app)->prefs;
71 	UpdateColors(prefs->normal_bar_color, prefs->normal_fade_colors);
72 }
73 
74 
75 void
76 ProgressBar::MouseDown(BPoint point)
77 {
78 	point = ConvertToParent(point);
79 	Parent()->MouseDown(point);
80 }
81 
82 
83 void
84 ProgressBar::Set(int32 value)
85 {
86 	// How many segments to light up
87 	current_value = (int32)(value / 4.9);
88 	if (current_value > 20)
89 		current_value = 20;
90 
91 	Render(false);
92 }
93 
94 
95 // Draws the progress bar. If "all" is true the entire bar is redrawn rather
96 // than just the part that changed.
97 void
98 ProgressBar::Render(bool all)
99 {
100 	if (all) {
101 		// Black border
102 		BRect bounds = Bounds();
103 		bounds.InsetBy(2, 2);
104 		SetHighColor(0, 0, 0);
105 		StrokeRect(bounds);
106 		bounds.InsetBy(1, 1);
107 		StrokeRect(bounds);
108 
109 		// Black dividers
110 		float left = bounds.left;
111 		BPoint start, end;
112 		for (int x = 0; x < 19; x++) {
113 			left += 7;
114 			start.Set(left, bounds.top);
115 			end.Set(left, bounds.bottom);
116 			StrokeLine(start, end);
117 		}
118 
119 		for (int x = 0; x < current_value; x++) {
120 			SetHighColor(segments[x].color.red, segments[x].color.green,
121 				segments[x].color.blue);
122 			FillRect(segments[x].rect);
123 		}
124 
125 		SetHighColor(75, 75, 75);
126 		if (current_value < 20) {
127 			for (int x = 19; x >= current_value; x--) {
128 				FillRect(segments[x].rect);
129 			}
130 		}
131 	} else if (current_value > previous_value) {
132 		for (int x = previous_value; x < current_value; x++) {
133 			SetHighColor(segments[x].color.red, segments[x].color.green,
134 				segments[x].color.blue);
135 			FillRect(segments[x].rect);
136 		}
137 	} else if (current_value < previous_value) {
138 		SetHighColor(75, 75, 75);
139 		for (int x = previous_value - 1; x >= current_value; x--) {
140 			FillRect(segments[x].rect);
141 		}
142 		// Special case to make sure the lowest light gets turned off
143 		if (current_value == 0) FillRect(segments[0].rect);
144 	}
145 
146 	Sync();
147 	previous_value = current_value;
148 }
149 
150 
151 void
152 ProgressBar::Draw(BRect rect)
153 {
154 	// Add bevels
155 	SetHighColor(dkgray, dkgray, dkgray);
156 	BRect frame = Bounds();
157 	StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.right, frame.top));
158 	StrokeLine(BPoint(frame.left, frame.top + 1), BPoint(frame.right,
159 		frame.top + 1));
160 	StrokeLine(BPoint(frame.left, frame.top), BPoint(frame.left,
161 		frame.bottom));
162 	StrokeLine(BPoint(frame.left + 1, frame.top),
163 		BPoint(frame.left + 1, frame.bottom));
164 
165 	SetHighColor(ltgray, ltgray, ltgray);
166 	StrokeLine(BPoint(frame.right-1, frame.top + 2),
167 		BPoint(frame.right - 1, frame.bottom));
168 	StrokeLine(BPoint(frame.right, frame.top + 1),
169 		BPoint(frame.right, frame.bottom));
170 	StrokeLine(BPoint(frame.left+1, frame.bottom - 1),
171 		BPoint(frame.right - 1, frame.bottom - 1));
172 	StrokeLine(BPoint(frame.left, frame.bottom),
173 		BPoint(frame.right, frame.bottom));
174 
175 	Render(true);
176 }
177