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